Skip to content

Commit a40b65b

Browse files
biasedbitnlutsenko
authored andcommitted
Add no-side effects version of navigateToAppLink:error: and navigate: (#245)
- Allows app to know the type of navigation that would result of calling BFAppLinkNavigation's navigateToAppLink:error: or navigate: without having any side effects - Also adds a test to ensure same output as navigateToAppLink:error: without the side effects.
1 parent d293c44 commit a40b65b

File tree

4 files changed

+78
-0
lines changed

4 files changed

+78
-0
lines changed

Bolts/iOS/BFAppLinkNavigation.h

+20
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ typedef NS_ENUM(NSInteger, BFAppLinkNavigationType) {
5757
extras:(NSDictionary *)extras
5858
appLinkData:(NSDictionary *)appLinkData;
5959

60+
/*!
61+
Creates an NSDictionary with the correct format for iOS callback URLs,
62+
to be used as 'appLinkData' argument in the call to navigationWithAppLink:extras:appLinkData:
63+
*/
64+
+ (NSDictionary *)callbackAppLinkDataForAppWithName:(NSString *)appName url:(NSString *)url;
65+
6066
/*! Performs the navigation */
6167
- (BFAppLinkNavigationType)navigate:(NSError **)error;
6268

@@ -69,6 +75,20 @@ typedef NS_ENUM(NSInteger, BFAppLinkNavigationType) {
6975
/*! Navigates to a BFAppLink and returns whether it opened in-app or in-browser */
7076
+ (BFAppLinkNavigationType)navigateToAppLink:(BFAppLink *)link error:(NSError **)error;
7177

78+
/*!
79+
Returns a BFAppLinkNavigationType based on a BFAppLink.
80+
It's essentially a no-side-effect version of navigateToAppLink:error:,
81+
allowing apps to determine flow based on the link type (e.g. open an
82+
internal web view instead of going straight to the browser for regular links.)
83+
*/
84+
+ (BFAppLinkNavigationType)navigationTypeForLink:(BFAppLink *)link;
85+
86+
/*!
87+
Return navigation type for current instance.
88+
No-side-effect version of navigate:
89+
*/
90+
- (BFAppLinkNavigationType)navigationType;
91+
7292
/*! Navigates to a URL (an asynchronous action) and returns a BFNavigationType */
7393
+ (BFTask *)navigateToURLInBackground:(NSURL *)destination;
7494

Bolts/iOS/BFAppLinkNavigation.m

+41
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
FOUNDATION_EXPORT NSString *const BFAppLinkUserAgentKeyName;
2121
FOUNDATION_EXPORT NSString *const BFAppLinkExtrasKeyName;
2222
FOUNDATION_EXPORT NSString *const BFAppLinkVersionKeyName;
23+
FOUNDATION_EXPORT NSString *const BFAppLinkRefererAppLink;
24+
FOUNDATION_EXPORT NSString *const BFAppLinkRefererAppName;
25+
FOUNDATION_EXPORT NSString *const BFAppLinkRefererUrl;
2326

2427
static id<BFAppLinkResolving> defaultResolver;
2528

@@ -43,6 +46,10 @@ + (instancetype)navigationWithAppLink:(BFAppLink *)appLink
4346
return navigation;
4447
}
4548

49+
+ (NSDictionary *)callbackAppLinkDataForAppWithName:(NSString *)appName url:(NSString *)url {
50+
return @{BFAppLinkRefererAppLink: @{BFAppLinkRefererAppName: appName, BFAppLinkRefererUrl: url}};
51+
}
52+
4653
- (NSString *)stringByEscapingQueryString:(NSString *)string {
4754
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0 || __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_9
4855
return [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
@@ -229,6 +236,40 @@ + (BFAppLinkNavigationType)navigateToAppLink:(BFAppLink *)link error:(NSError **
229236
appLinkData:nil] navigate:error];
230237
}
231238

239+
+ (BFAppLinkNavigationType)navigationTypeForLink:(BFAppLink *)link {
240+
return [[self navigationWithAppLink:link extras:nil appLinkData:nil] navigationType];
241+
}
242+
243+
- (BFAppLinkNavigationType)navigationType {
244+
BFAppLinkTarget *eligibleTarget = nil;
245+
for (BFAppLinkTarget *target in self.appLink.targets) {
246+
if ([[UIApplication sharedApplication] canOpenURL:target.URL]) {
247+
eligibleTarget = target;
248+
break;
249+
}
250+
}
251+
252+
if (eligibleTarget != nil) {
253+
NSURL *appLinkURL = [self appLinkURLWithTargetURL:eligibleTarget.URL error:nil];
254+
if (appLinkURL != nil) {
255+
return BFAppLinkNavigationTypeApp;
256+
} else {
257+
return BFAppLinkNavigationTypeFailure;
258+
}
259+
}
260+
261+
if (self.appLink.webURL != nil) {
262+
NSURL *appLinkURL = [self appLinkURLWithTargetURL:eligibleTarget.URL error:nil];
263+
if (appLinkURL != nil) {
264+
return BFAppLinkNavigationTypeBrowser;
265+
} else {
266+
return BFAppLinkNavigationTypeFailure;
267+
}
268+
}
269+
270+
return BFAppLinkNavigationTypeFailure;
271+
}
272+
232273
+ (id<BFAppLinkResolving>)defaultResolver {
233274
if (defaultResolver) {
234275
return defaultResolver;

BoltsTestUI/BoltsTestUI-Info.plist

+4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
</array>
4040
</dict>
4141
</array>
42+
<key>LSApplicationQueriesSchemes</key>
43+
<array>
44+
<string>bolts</string>
45+
</array>
4246
<key>CFBundleVersion</key>
4347
<string>1.0</string>
4448
<key>LSRequiresIPhoneOS</key>

BoltsTests/AppLinkTests.m

+13
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,19 @@ - (void)testPlatformFiltering {
756756

757757
#pragma mark App link navigation
758758

759+
- (void)testSimpleAppLinkNavigationLookup {
760+
BFAppLinkTarget *target = [BFAppLinkTarget appLinkTargetWithURL:[NSURL URLWithString:@"bolts://"]
761+
appStoreId:@"12345"
762+
appName:@"Bolts"];
763+
BFAppLink *appLink = [BFAppLink appLinkWithSourceURL:[NSURL URLWithString:@"http://www.example.com/path"]
764+
targets:@[target]
765+
webURL:[NSURL URLWithString:@"http://www.example.com/path"]];
766+
BFAppLinkNavigationType navigationType = [BFAppLinkNavigation navigationTypeForLink:appLink];
767+
768+
XCTAssertEqual(navigationType, BFAppLinkNavigationTypeApp);
769+
XCTAssertEqual((NSUInteger)0, openedUrls.count); // no side effects
770+
}
771+
759772
- (void)testSimpleAppLinkNavigation {
760773
BFAppLinkTarget *target = [BFAppLinkTarget appLinkTargetWithURL:[NSURL URLWithString:@"bolts://"]
761774
appStoreId:@"12345"

0 commit comments

Comments
 (0)