ViewController.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /*
  2. * Copyright 2018 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "ViewController.h"
  17. #import <FirebaseDynamicLinks/FDLURLComponents.h>
  18. #import <FirebaseDynamicLinks/FIRDynamicLinks.h>
  19. #import "LinkTableViewCell.h"
  20. #import "ParamTableViewCell.h"
  21. static NSArray *kParamsConfiguration;
  22. @interface ViewController () <ParamTableViewCellDelegate>
  23. @end
  24. @implementation ViewController {
  25. NSArray *_paramsConfiguration;
  26. NSMutableDictionary *_paramValues;
  27. NSURL *_longLink;
  28. NSURL *_shortLink;
  29. }
  30. - (void)viewDidLoad {
  31. [super viewDidLoad];
  32. self.view.backgroundColor = [UIColor whiteColor];
  33. self.title = @"FDL Builder";
  34. self.tableView.rowHeight = 60;
  35. [self _initDefaultValues];
  36. }
  37. #pragma mark - UITableViewDelegate
  38. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  39. if (indexPath.section == 0 && indexPath.row == (kParamsConfiguration.count + 0)) {
  40. [self _buildFDLLink];
  41. }
  42. if (indexPath.section == 0 && indexPath.row == (kParamsConfiguration.count + 1)) {
  43. // copy long link
  44. if (_longLink) {
  45. [UIPasteboard generalPasteboard].string = _longLink.absoluteString;
  46. [self _presentMessage:@"Long Link copied to Clipboard" description:nil];
  47. } else {
  48. [self _presentMessage:@"Long Link is empty" description:nil];
  49. }
  50. }
  51. if (indexPath.section == 0 && indexPath.row == (kParamsConfiguration.count + 2)) {
  52. // copy short link
  53. if (_shortLink) {
  54. [UIPasteboard generalPasteboard].string = _shortLink.absoluteString;
  55. [self _presentMessage:@"Short Link copied to Clipboard" description:nil];
  56. } else {
  57. [self _presentMessage:@"Short Link is empty" description:nil];
  58. }
  59. }
  60. }
  61. #pragma mark - UITableViewDataSource
  62. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  63. if (section == 0) {
  64. return kParamsConfiguration.count + 3;
  65. } else {
  66. return 0;
  67. }
  68. }
  69. - (UITableViewCell *)tableView:(UITableView *)tableView
  70. cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  71. if (indexPath.row >= kParamsConfiguration.count) {
  72. return [self _customCellForRow:indexPath.row - kParamsConfiguration.count];
  73. } else {
  74. ParamTableViewCell *cell =
  75. (ParamTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"ParamTableViewCell"];
  76. if (!cell) {
  77. cell = [[ParamTableViewCell alloc] init];
  78. }
  79. NSDictionary *paramConfig = kParamsConfiguration[indexPath.row];
  80. cell.paramConfig = paramConfig;
  81. cell.textFieldValue = _paramValues[paramConfig[@"id"]];
  82. cell.delegate = self;
  83. return cell;
  84. }
  85. }
  86. - (void)paramTableViewCellUpdatedValue:(ParamTableViewCell *)cell;
  87. { _paramValues[cell.paramConfig[@"id"]] = cell.textFieldValue; }
  88. #pragma mark - Private methods
  89. - (UITableViewCell *)_customCellForRow:(NSUInteger)row {
  90. switch (row) {
  91. case 0: {
  92. UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
  93. reuseIdentifier:@"cell"];
  94. cell.textLabel.text = @"Generate Link";
  95. cell.accessibilityIdentifier = @"generate-link";
  96. cell.textLabel.textAlignment = NSTextAlignmentCenter;
  97. cell.textLabel.font = [UIFont boldSystemFontOfSize:22];
  98. return cell;
  99. } break;
  100. case 1:
  101. case 2: {
  102. LinkTableViewCell *cell = (LinkTableViewCell *)[self.tableView
  103. dequeueReusableCellWithIdentifier:@"LinkTableViewCell"];
  104. if (!cell) {
  105. cell = [[LinkTableViewCell alloc] init];
  106. }
  107. if (row == 1) {
  108. [cell setTitle:@"Long link" link:_longLink.absoluteString];
  109. } else {
  110. [cell setTitle:@"Short link" link:_shortLink.absoluteString];
  111. }
  112. return cell;
  113. } break;
  114. case 3: {
  115. UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
  116. reuseIdentifier:@"cell"];
  117. cell.textLabel.text = @"Perform FDL self diagnostic";
  118. cell.textLabel.textAlignment = NSTextAlignmentCenter;
  119. cell.textLabel.font = [UIFont systemFontOfSize:22];
  120. return cell;
  121. } break;
  122. }
  123. return nil;
  124. }
  125. - (void)_initDefaultValues {
  126. static dispatch_once_t onceToken;
  127. dispatch_once(&onceToken, ^{
  128. kParamsConfiguration = @[
  129. // general link params
  130. @{
  131. @"id" : @"linkString",
  132. @"label" : @"Link value (required)",
  133. @"defaultValue" : @"https://www.google.com?q=jump",
  134. },
  135. // The default value of domain appcode belongs to project: app-invites-qa
  136. @{
  137. @"id" : @"domainURIPrefix",
  138. @"label" : @"App domainURIPrefix (required)",
  139. @"defaultValue" : @"https://testfdl.page.link",
  140. },
  141. // analytics params
  142. @{
  143. @"id" : @"FIRDynamicLinkGoogleAnalyticsParameters.source",
  144. @"label" : @"Google Analytics source (optional)",
  145. @"defaultValue" : @"",
  146. },
  147. @{
  148. @"id" : @"FIRDynamicLinkGoogleAnalyticsParameters.medium",
  149. @"label" : @"Google Analytics medium (optional)",
  150. @"defaultValue" : @"",
  151. },
  152. @{
  153. @"id" : @"FIRDynamicLinkGoogleAnalyticsParameters.campaign",
  154. @"label" : @"Google Analytics campaign (optional)",
  155. @"defaultValue" : @"",
  156. },
  157. @{
  158. @"id" : @"FIRDynamicLinkGoogleAnalyticsParameters.term",
  159. @"label" : @"Google Analytics term (optional)",
  160. @"defaultValue" : @"",
  161. },
  162. @{
  163. @"id" : @"FIRDynamicLinkGoogleAnalyticsParameters.content",
  164. @"label" : @"Google Analytics content (optional)",
  165. @"defaultValue" : @"",
  166. },
  167. // iOS params
  168. @{
  169. @"id" : @"FIRDynamicLinkIOSParameters.bundleId",
  170. @"label" : @"iOS App bundle ID",
  171. @"defaultValue" : [[NSBundle mainBundle] bundleIdentifier] ?: @"",
  172. },
  173. @{
  174. @"id" : @"FIRDynamicLinkIOSParameters.fallbackURL",
  175. @"label" : @"Fallback URL iOS (optional)",
  176. },
  177. @{
  178. @"id" : @"FIRDynamicLinkIOSParameters.minimumAppVersion",
  179. @"label" : @"minimum version of iOS App (optional)",
  180. @"defaultValue" : @"1.0",
  181. },
  182. @{
  183. @"id" : @"FIRDynamicLinkIOSParameters.customScheme",
  184. @"label" : @"iOS App custom scheme (optional)",
  185. },
  186. @{
  187. @"id" : @"FIRDynamicLinkIOSParameters.iPadBundleID",
  188. @"label" : @"iPad App bundleID (optional)",
  189. @"defaultValue" : @"",
  190. },
  191. @{
  192. @"id" : @"FIRDynamicLinkIOSParameters.iPadFallbackURL",
  193. @"label" : @"Fallback URL on iPad (optional)",
  194. },
  195. @{
  196. @"id" : @"FIRDynamicLinkIOSParameters.appStoreID",
  197. @"label" : @"iOS AppStore ID (optional)",
  198. },
  199. // iTunesConnect params
  200. @{
  201. @"id" : @"FIRDynamicLinkItunesConnectAnalyticsParameters.affiliateToken",
  202. @"label" : @"iTunesConnect affiliate token (optional)",
  203. @"defaultValue" : @"",
  204. },
  205. @{
  206. @"id" : @"FIRDynamicLinkItunesConnectAnalyticsParameters.campaignToken",
  207. @"label" : @"iTunesConnect campaign token (optional)",
  208. @"defaultValue" : @"",
  209. },
  210. @{
  211. @"id" : @"FIRDynamicLinkItunesConnectAnalyticsParameters.providerToken",
  212. @"label" : @"iTunesConnect provider token (optional)",
  213. @"defaultValue" : @"",
  214. },
  215. // Android params
  216. @{
  217. @"id" : @"FIRDynamicLinkAndroidParameters.packageName",
  218. @"label" : @"Android App package name (optional)",
  219. @"defaultValue" : @"",
  220. },
  221. @{
  222. @"id" : @"FIRDynamicLinkAndroidParameters.fallbackURL",
  223. @"label" : @"Android fallback URL (optional)",
  224. @"defaultValue" : @"",
  225. },
  226. @{
  227. @"id" : @"FIRDynamicLinkAndroidParameters.minimumVersion",
  228. @"label" : @"Andropid App minimum version, integer number (optional)",
  229. @"defaultValue" : @"",
  230. },
  231. // social tag params
  232. @{
  233. @"id" : @"FIRDynamicLinkSocialMetaTagParameters.title",
  234. @"label" : @"Social meta tag title (optional)",
  235. @"defaultValue" : @"",
  236. },
  237. @{
  238. @"id" : @"FIRDynamicLinkSocialMetaTagParameters.descriptionText",
  239. @"label" : @"Social meta tag description text (optional)",
  240. @"defaultValue" : @"",
  241. },
  242. @{
  243. @"id" : @"FIRDynamicLinkSocialMetaTagParameters.imageURL",
  244. @"label" : @"Social meta tag image URL (optional)",
  245. @"defaultValue" : @"",
  246. },
  247. // OtherPlatform params
  248. @{
  249. @"id" : @"FIRDynamicLinkOtherPlatformParameters.fallbackUrl",
  250. @"label" : @"OtherPlatform Fallback link (optional)",
  251. @"defaultValue" : @"",
  252. },
  253. ];
  254. });
  255. _paramValues = [[NSMutableDictionary alloc] initWithCapacity:kParamsConfiguration.count];
  256. for (NSDictionary *paramConfig in kParamsConfiguration) {
  257. if (paramConfig[@"defaultValue"]) {
  258. _paramValues[paramConfig[@"id"]] = paramConfig[@"defaultValue"];
  259. }
  260. }
  261. }
  262. - (void)_buildFDLLink {
  263. NSURL *link = [NSURL URLWithString:_paramValues[@"linkString"]];
  264. FIRDynamicLinkComponents *components =
  265. [FIRDynamicLinkComponents componentsWithLink:link
  266. domainURIPrefix:_paramValues[@"domainURIPrefix"]];
  267. FIRDynamicLinkGoogleAnalyticsParameters *analyticsParams =
  268. [FIRDynamicLinkGoogleAnalyticsParameters
  269. parametersWithSource:_paramValues[@"FIRDynamicLinkGoogleAnalyticsParameters.source"]
  270. medium:_paramValues[@"FIRDynamicLinkGoogleAnalyticsPara"
  271. @"meters.medium"]
  272. campaign:_paramValues[@"FIRDynamicLinkGoogleAnalyticsPara"
  273. @"meters.campaign"]];
  274. analyticsParams.term = _paramValues[@"FIRDynamicLinkGoogleAnalyticsParameters.term"];
  275. analyticsParams.content = _paramValues[@"FIRDynamicLinkGoogleAnalyticsParameters.content"];
  276. FIRDynamicLinkIOSParameters *iOSParams;
  277. if (_paramValues[@"FIRDynamicLinkIOSParameters.bundleId"]) {
  278. iOSParams = [FIRDynamicLinkIOSParameters
  279. parametersWithBundleID:_paramValues[@"FIRDynamicLinkIOSParameters.bundleId"]];
  280. iOSParams.fallbackURL =
  281. [NSURL URLWithString:_paramValues[@"FIRDynamicLinkIOSParameters.fallbackURL"]];
  282. iOSParams.customScheme = _paramValues[@"FIRDynamicLinkIOSParameters.customScheme"];
  283. iOSParams.iPadBundleID = _paramValues[@"FIRDynamicLinkIOSParameters.iPadBundleID"];
  284. iOSParams.iPadFallbackURL =
  285. [NSURL URLWithString:_paramValues[@"FIRDynamicLinkIOSParameters.iPadFallbackURL"]];
  286. iOSParams.appStoreID = _paramValues[@"FIRDynamicLinkIOSParameters.appStoreId"];
  287. iOSParams.minimumAppVersion = _paramValues[@"FIRDynamicLinkIOSParameters.minimumAppVersion"];
  288. }
  289. FIRDynamicLinkItunesConnectAnalyticsParameters *appStoreParams =
  290. [FIRDynamicLinkItunesConnectAnalyticsParameters parameters];
  291. appStoreParams.affiliateToken =
  292. _paramValues[@"FIRDynamicLinkItunesConnectAnalyticsParameters.affiliateToken"];
  293. appStoreParams.campaignToken =
  294. _paramValues[@"FIRDynamicLinkItunesConnectAnalyticsParameters.campaignToken"];
  295. appStoreParams.providerToken =
  296. _paramValues[@"FIRDynamicLinkItunesConnectAnalyticsParameters.providerToken"];
  297. FIRDynamicLinkAndroidParameters *androidParams;
  298. if (_paramValues[@"FIRDynamicLinkAndroidParameters.packageName"]) {
  299. androidParams = [FIRDynamicLinkAndroidParameters
  300. parametersWithPackageName:_paramValues[@"FIRDynamicLinkAndroidParameters.packageName"]];
  301. androidParams.fallbackURL =
  302. [NSURL URLWithString:_paramValues[@"FIRDynamicLinkAndroidParameters.fallbackURL"]];
  303. if ([_paramValues[@"FIRDynamicLinkAndroidParameters.minimumVersion"] integerValue] > 0) {
  304. androidParams.minimumVersion =
  305. [_paramValues[@"FIRDynamicLinkAndroidParameters.minimumVersion"] integerValue];
  306. }
  307. }
  308. FIRDynamicLinkSocialMetaTagParameters *socialParams =
  309. [FIRDynamicLinkSocialMetaTagParameters parameters];
  310. socialParams.title = _paramValues[@"FIRDynamicLinkSocialMetaTagParameters.title"];
  311. socialParams.descriptionText =
  312. _paramValues[@"FIRDynamicLinkSocialMetaTagParameters.descriptionText"];
  313. socialParams.imageURL =
  314. [NSURL URLWithString:_paramValues[@"FIRDynamicLinkSocialMetaTagParameters.imageURL"]];
  315. FIRDynamicLinkOtherPlatformParameters *otherPlatformParams =
  316. [FIRDynamicLinkOtherPlatformParameters parameters];
  317. otherPlatformParams.fallbackUrl =
  318. [NSURL URLWithString:_paramValues[@"FIRDynamicLinkOtherPlatformParameters.fallbackUrl"]];
  319. FIRDynamicLinkComponentsOptions *options = [FIRDynamicLinkComponentsOptions options];
  320. options.pathLength = FIRShortDynamicLinkPathLengthShort;
  321. components.analyticsParameters = analyticsParams;
  322. components.iOSParameters = iOSParams;
  323. components.iTunesConnectParameters = appStoreParams;
  324. components.androidParameters = androidParams;
  325. components.socialMetaTagParameters = socialParams;
  326. components.otherPlatformParameters = otherPlatformParams;
  327. components.options = options;
  328. NSURL *longURL = components.url;
  329. // Handle longURL.
  330. NSLog(@"Long URL: %@", longURL);
  331. _longLink = longURL;
  332. [self.tableView
  333. reloadRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:kParamsConfiguration.count + 1
  334. inSection:0] ]
  335. withRowAnimation:UITableViewRowAnimationNone];
  336. [components shortenWithCompletion:^(NSURL *_Nullable shortURL, NSArray *_Nullable warnings,
  337. NSError *_Nullable error) {
  338. // Handle shortURL or error.
  339. NSLog(@"Short URL: %@, warnings: %@ error: %@", shortURL, warnings, error);
  340. if (error) {
  341. [self _presentMessage:@"Error generating short link" description:[error description]];
  342. }
  343. _shortLink = shortURL;
  344. [self.tableView
  345. reloadRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:kParamsConfiguration.count + 2
  346. inSection:0] ]
  347. withRowAnimation:UITableViewRowAnimationNone];
  348. }];
  349. }
  350. - (void)_presentMessage:(NSString *)message description:(NSString *)description {
  351. UIAlertController *alertVC =
  352. [UIAlertController alertControllerWithTitle:message
  353. message:description
  354. preferredStyle:UIAlertControllerStyleAlert];
  355. [alertVC addAction:[UIAlertAction actionWithTitle:@"Dismiss"
  356. style:UIAlertActionStyleCancel
  357. handler:NULL]];
  358. [self presentViewController:alertVC animated:YES completion:NULL];
  359. }
  360. @end