diff --git a/Bolts.xcodeproj/project.pbxproj b/Bolts.xcodeproj/project.pbxproj index 45cd256fa..99fddc866 100644 --- a/Bolts.xcodeproj/project.pbxproj +++ b/Bolts.xcodeproj/project.pbxproj @@ -63,6 +63,8 @@ 8EE768A81803E5DA009A53B1 /* BoltsVersion.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E0B5CDA17E13B4C0066379B /* BoltsVersion.h */; }; 8EE768A91803E5E0009A53B1 /* Bolts.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8EE768A61803E32F009A53B1 /* Bolts.h */; }; 8EE768AA1803E5E5009A53B1 /* BoltsVersion.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E0B5CDA17E13B4C0066379B /* BoltsVersion.h */; }; + B24A9E26194FABF700603EBB /* BFMeasurementEvent.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = B2DEBAF4194668D4005EBEAA /* BFMeasurementEvent.h */; }; + B2DEBAF6194668D4005EBEAA /* BFMeasurementEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = B2DEBAF5194668D4005EBEAA /* BFMeasurementEvent.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -102,6 +104,7 @@ 1E45E47518DA7F0000D23509 /* BFAppLinkNavigation.h in CopyFiles */, 1E45E47618DA7F0000D23509 /* BFAppLinkResolving.h in CopyFiles */, 1E45E47718DA7F0000D23509 /* BFAppLinkTarget.h in CopyFiles */, + B24A9E26194FABF700603EBB /* BFMeasurementEvent.h in CopyFiles */, 1E45E47818DA7F0000D23509 /* BFURL.h in CopyFiles */, 1E45E47918DA7F0000D23509 /* BFWebViewAppLinkResolver.h in CopyFiles */, 8E42701F1805E5A1000B84ED /* BFExecutor.h in CopyFiles */, @@ -199,6 +202,10 @@ 8EB2CB411805DDDB00323385 /* BFExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BFExecutor.m; sourceTree = ""; }; 8EDDA63517E17DDD00655F8A /* libMacBolts.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMacBolts.a; sourceTree = BUILT_PRODUCTS_DIR; }; 8EE768A61803E32F009A53B1 /* Bolts.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Bolts.h; sourceTree = ""; }; + B2112471194FCEA10001FF7A /* BFURL_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BFURL_Internal.h; sourceTree = ""; }; + B28E0515194F818B00AC3740 /* BFAppLink_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BFAppLink_Internal.h; sourceTree = ""; }; + B2DEBAF4194668D4005EBEAA /* BFMeasurementEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BFMeasurementEvent.h; sourceTree = ""; }; + B2DEBAF5194668D4005EBEAA /* BFMeasurementEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BFMeasurementEvent.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -338,6 +345,7 @@ isa = PBXGroup; children = ( 1E11AB7518C561E300522739 /* BFAppLink.h */, + B28E0515194F818B00AC3740 /* BFAppLink_Internal.h */, 1E11AB7618C561E300522739 /* BFAppLink.m */, 1E11AB7318C561E300522739 /* BFAppLinkNavigation.h */, 1E11AB7418C561E300522739 /* BFAppLinkNavigation.m */, @@ -356,9 +364,12 @@ 8E9C3D2017DEA35700427E62 /* BFTaskCompletionSource.h */, 8E9C3D2117DEA35700427E62 /* BFTaskCompletionSource.m */, 1E11AB7718C561E300522739 /* BFURL.h */, + B2112471194FCEA10001FF7A /* BFURL_Internal.h */, 1E11AB7818C561E300522739 /* BFURL.m */, 1EC3019418CDD8A500D06D07 /* BFWebViewAppLinkResolver.h */, 1EC3019518CDD8A500D06D07 /* BFWebViewAppLinkResolver.m */, + B2DEBAF4194668D4005EBEAA /* BFMeasurementEvent.h */, + B2DEBAF5194668D4005EBEAA /* BFMeasurementEvent.m */, 8EE768A61803E32F009A53B1 /* Bolts.h */, 8EA6BF661805CED500337041 /* Bolts.m */, 8E0B5CDA17E13B4C0066379B /* BoltsVersion.h */, @@ -579,6 +590,7 @@ 1EC3019618CDD8A500D06D07 /* BFWebViewAppLinkResolver.m in Sources */, 1E11AB7918C561E300522739 /* BFAppLinkNavigation.m in Sources */, 85D5138818E4E27700D19D87 /* BFAppLinkReturnToRefererView.m in Sources */, + B2DEBAF6194668D4005EBEAA /* BFMeasurementEvent.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Bolts/BFAppLink.m b/Bolts/BFAppLink.m index e1b2dc159..d75e7844f 100644 --- a/Bolts/BFAppLink.m +++ b/Bolts/BFAppLink.m @@ -8,7 +8,7 @@ * */ -#import "BFAppLink.h" +#import "BFAppLink_Internal.h" NSString *const BFAppLinkDataParameterName = @"al_applink_data"; NSString *const BFAppLinkTargetKeyName = @"target_url"; @@ -20,16 +20,39 @@ NSString *const BFAppLinkVersionKeyName = @"version"; NSString *const BFAppLinkVersion = @"1.0"; -@implementation BFAppLink +@implementation BFAppLink { + BOOL _isBackToReferrer; +} + (instancetype)appLinkWithSourceURL:(NSURL *)sourceURL targets:(NSArray *)targets - webURL:(NSURL *)webURL { - BFAppLink *link = [[self alloc] init]; + webURL:(NSURL *)webURL + isBackToReferrer:(BOOL)isBackToReferrer { + BFAppLink *link = [[self alloc] initWithIsBackToReferrer:isBackToReferrer]; link->_sourceURL = sourceURL; link->_targets = [NSArray arrayWithArray:targets]; link->_webURL = webURL; return link; } ++ (instancetype)appLinkWithSourceURL:(NSURL *)sourceURL + targets:(NSArray *)targets + webURL:(NSURL *)webURL { + return [self appLinkWithSourceURL:sourceURL + targets:targets + webURL:webURL + isBackToReferrer:NO]; +} + +- (BOOL)isBackToReferrer { + return _isBackToReferrer; +} + +- (BFAppLink *)initWithIsBackToReferrer:(BOOL)isBackToReferrer { + if ((self = [super init])) { + _isBackToReferrer = isBackToReferrer; + } + return self; +} + @end diff --git a/Bolts/BFAppLinkNavigation.h b/Bolts/BFAppLinkNavigation.h index e475b4ad7..0be97037d 100644 --- a/Bolts/BFAppLinkNavigation.h +++ b/Bolts/BFAppLinkNavigation.h @@ -24,6 +24,13 @@ typedef NS_ENUM(NSInteger, BFAppLinkNavigationType) { BFAppLinkNavigationTypeApp }; +/*! Bolts Events raised by BFMeasurementEvent for Applink */ +/* The event raised when the user navigates from your app to other apps */ +FOUNDATION_EXPORT NSString *const BFAppLinkNavigateOutEventName; +/* The event raised when the user navigates out from your app and back to the referrer app. + e.g when the user leaves your app after tapping the back-to-referrer navigation bar */ +FOUNDATION_EXPORT NSString *const BFAppLinkNavigateBackToReferrerEventName; + @protocol BFAppLinkResolving; @class BFTask; diff --git a/Bolts/BFAppLinkNavigation.m b/Bolts/BFAppLinkNavigation.m index d683fe1c0..cefdda585 100644 --- a/Bolts/BFAppLinkNavigation.m +++ b/Bolts/BFAppLinkNavigation.m @@ -17,6 +17,8 @@ #import "BFWebViewAppLinkResolver.h" #import "BFExecutor.h" #import "BFTask.h" +#import "BFMeasurementEvent.h" +#import "BFAppLink_Internal.h" FOUNDATION_EXPORT NSString *const BFAppLinkDataParameterName; FOUNDATION_EXPORT NSString *const BFAppLinkTargetKeyName; @@ -24,11 +26,11 @@ FOUNDATION_EXPORT NSString *const BFAppLinkExtrasKeyName; FOUNDATION_EXPORT NSString *const BFAppLinkVersionKeyName; -static id defaultResolver; - -@interface BFAppLinkNavigation () +/*! AppLink events raised in this class */ +NSString *const BFAppLinkNavigateOutEventName = @"al_nav_out"; +NSString *const BFAppLinkNavigateBackToReferrerEventName = @"al_ref_back_out"; -@end +static id defaultResolver; @implementation BFAppLinkNavigation @@ -97,43 +99,105 @@ - (BFAppLinkNavigationType)navigate:(NSError **)error { } } + NSURL *appLinkURLToOpen = nil; + NSError *encodingError = nil; + BFAppLinkNavigationType retType = BFAppLinkNavigationTypeFailure; if (eligibleTarget) { - NSError *encodingError = nil; - NSURL *appLinkURL = [self appLinkURLWithTargetURL:eligibleTarget.URL error:&encodingError]; - if (encodingError || !appLinkURL) { - // If there was an error encoding the app link data, fail hard. + NSURL *appLinkAppURL = [self appLinkURLWithTargetURL:eligibleTarget.URL error:&encodingError]; + if (encodingError || !appLinkAppURL) { if (error) { *error = encodingError; } - return BFAppLinkNavigationTypeFailure; - } - // Attempt to navigate - if ([[UIApplication sharedApplication] openURL:appLinkURL]) { - return BFAppLinkNavigationTypeApp; + } else if ([[UIApplication sharedApplication] canOpenURL:appLinkAppURL]) { + retType = BFAppLinkNavigationTypeApp; + appLinkURLToOpen = appLinkAppURL; } } - // Fall back to opening the url in the browser if available. - if (self.appLink.webURL) { - NSError *encodingError = nil; - NSURL *appLinkURL = [self appLinkURLWithTargetURL:self.appLink.webURL error:&encodingError]; - if (encodingError || !appLinkURL) { + if (!appLinkURLToOpen && self.appLink.webURL) { + // Fall back to opening the url in the browser if available. + NSURL *appLinkBrowserURL = [self appLinkURLWithTargetURL:self.appLink.webURL error:&encodingError]; + if (encodingError || !appLinkBrowserURL) { // If there was an error encoding the app link data, fail hard. if (error) { *error = encodingError; } - return BFAppLinkNavigationTypeFailure; - } - // Attempt to navigate - if ([[UIApplication sharedApplication] openURL:appLinkURL]) { + } else if ([[UIApplication sharedApplication] canOpenURL:appLinkBrowserURL]) { // This was a browser navigation. - return BFAppLinkNavigationTypeBrowser; + retType = BFAppLinkNavigationTypeBrowser; + appLinkURLToOpen = appLinkBrowserURL; } } - + + [self postAppLinkNavigateEventNotificationWithTargetURL:appLinkURLToOpen + error:error ? *error : nil + type:retType]; + if (appLinkURLToOpen) { + [[UIApplication sharedApplication] openURL:appLinkURLToOpen]; + } // Otherwise, navigation fails. - return BFAppLinkNavigationTypeFailure; + return retType; +} + +- (void) postAppLinkNavigateEventNotificationWithTargetURL:(NSURL *)outputURL error:(NSError *)error type:(BFAppLinkNavigationType)type{ + NSString *const EVENT_YES_VAL = @"1"; + NSString *const EVENT_NO_VAL = @"0"; + NSMutableDictionary *logData = [[NSMutableDictionary alloc] init]; + + NSString *outputURLScheme = [outputURL scheme]; + NSString *outputURLString = [outputURL absoluteString]; + if (outputURLScheme) { + logData[@"outputURLScheme"] = outputURLScheme; + } + if (outputURLString) { + logData[@"outputURL"] = outputURLString; + } + NSString *sourceURLString = [self.appLink.sourceURL absoluteString]; + NSString *sourceURLHost = [self.appLink.sourceURL host]; + NSString *sourceURLScheme = [self.appLink.sourceURL scheme]; + if (sourceURLString) { + logData[@"sourceURL"] = sourceURLString; + } + if (sourceURLHost) { + logData[@"sourceHost"] = sourceURLHost; + } + if (sourceURLScheme) { + logData[@"sourceScheme"] = sourceURLScheme; + } + if ([error localizedDescription]) { + logData[@"error"] = [error localizedDescription]; + } + NSString *success = nil; //no + NSString *linkType = nil; // unknown; + switch (type) { + case BFAppLinkNavigationTypeFailure: + success = EVENT_NO_VAL; + linkType = @"fail"; + break; + case BFAppLinkNavigationTypeBrowser: + success = EVENT_YES_VAL; + linkType = @"web"; + break; + case BFAppLinkNavigationTypeApp: + success = EVENT_YES_VAL; + linkType = @"app"; + break; + default: + break; + } + if (success) { + logData[@"success"] = success; + } + if (linkType) { + logData[@"type"] = linkType; + } + + if ([self.appLink isBackToReferrer]) { + [BFMeasurementEvent postNotificationForEventName:BFAppLinkNavigateBackToReferrerEventName args:logData]; + } else { + [BFMeasurementEvent postNotificationForEventName:BFAppLinkNavigateOutEventName args:logData]; + } } + (BFTask *)resolveAppLinkInBackground:(NSURL *)destination resolver:(id)resolver { diff --git a/Bolts/BFAppLinkReturnToRefererController.m b/Bolts/BFAppLinkReturnToRefererController.m index abc2fc270..d184db628 100644 --- a/Bolts/BFAppLinkReturnToRefererController.m +++ b/Bolts/BFAppLinkReturnToRefererController.m @@ -12,7 +12,7 @@ #import "BFAppLink.h" #import "BFAppLinkReturnToRefererView_Internal.h" -#import "BFURL.h" +#import "BFURL_Internal.h" static const CFTimeInterval kBFViewAnimationDuration = 0.25f; @@ -22,7 +22,10 @@ @interface BFAppLinkReturnToRefererController () @end -@implementation BFAppLinkReturnToRefererController +@implementation BFAppLinkReturnToRefererController { + BFURL *_lastShownBFUrl; + NSURL *_lastShownUrl; +} @synthesize view = _view; @@ -112,8 +115,11 @@ - (void)showViewForRefererAppLink:(BFAppLink *)refererAppLink { } - (void)showViewForRefererURL:(NSURL *)url { - BFURL *bfurl = [BFURL URLWithURL:url]; - [self showViewForRefererAppLink:bfurl.appLinkReferer]; + if (![_lastShownUrl isEqual:url]) { + _lastShownUrl = [url copy]; + _lastShownBFUrl = [BFURL URLForRenderBackToReferrerBarURL:url]; + } + [self showViewForRefererAppLink:_lastShownBFUrl.appLinkReferer]; } - (void)removeFromNavController { diff --git a/Bolts/BFAppLink_Internal.h b/Bolts/BFAppLink_Internal.h new file mode 100644 index 000000000..085f0c82f --- /dev/null +++ b/Bolts/BFAppLink_Internal.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import "BFAppLink.h" + +@interface BFAppLink (Internal) + ++ (instancetype)appLinkWithSourceURL:(NSURL *)sourceURL + targets:(NSArray *)targets + webURL:(NSURL *)webURL + isBackToReferrer:(BOOL)isBackToReferrer; + +/*! return if this AppLink is to go back to referrer. */ +- (BOOL)isBackToReferrer; + +@end \ No newline at end of file diff --git a/Bolts/BFMeasurementEvent.h b/Bolts/BFMeasurementEvent.h new file mode 100644 index 000000000..72d9bba88 --- /dev/null +++ b/Bolts/BFMeasurementEvent.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import + +/*! The name of the notification posted by BFMeasurementEvent */ +FOUNDATION_EXPORT NSString *const BFMeasurementEventNotificationName; + +/*! Defines keys in the userInfo object for the notification named BFMeasurementEventNotificationName */ +FOUNDATION_EXPORT NSString *const BFMeasurementEventNameKey; +FOUNDATION_EXPORT NSString *const BFMeasurementEventArgsKey; + +/*! + * Provides methods for posting notifications from the Bolts framework + */ +@interface BFMeasurementEvent : NSObject + ++ (void) postNotificationForEventName:(NSString *)name args:(NSDictionary *)args; + +@end diff --git a/Bolts/BFMeasurementEvent.m b/Bolts/BFMeasurementEvent.m new file mode 100644 index 000000000..10435599b --- /dev/null +++ b/Bolts/BFMeasurementEvent.m @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import "BFMeasurementEvent.h" + +NSString *const BFMeasurementEventNotificationName = @"com.parse.bolts.measurement_event"; + +NSString *const BFMeasurementEventNameKey = @"event_name"; +NSString *const BFMeasurementEventArgsKey = @"event_args"; + +__attribute__ ((noinline)) void warnOnMissingEventName() { + NSLog(@"Warning: Missing event name when logging bolts measurement event. \n" + " Ignoring this event in logging."); +} + +@implementation BFMeasurementEvent +{ + NSString *_name; + NSDictionary *_args; +} + +- (void) postNotification{ + if (!_name) { + warnOnMissingEventName(); + return; + } + NSNotificationCenter * center = [NSNotificationCenter defaultCenter]; + NSDictionary *userInfo = @{BFMeasurementEventNameKey: _name, + BFMeasurementEventArgsKey: _args}; + + [center postNotificationName:BFMeasurementEventNotificationName + object:self + userInfo:userInfo]; +} + +- (BFMeasurementEvent *) initEventWithName:(NSString *)name args:(NSDictionary *)args { + if ((self = [super init])) {; + _name = name; + _args = args ? args : @{}; + } + return self; +} + ++ (void) postNotificationForEventName:(NSString *)name args:(NSDictionary *)args { + [[[BFMeasurementEvent alloc] initEventWithName:name args:args] postNotification]; +} + +@end diff --git a/Bolts/BFURL.h b/Bolts/BFURL.h index ec69bfed0..7f3e03139 100644 --- a/Bolts/BFURL.h +++ b/Bolts/BFURL.h @@ -10,6 +10,15 @@ #import +/* Defines names of BFMeasurementEvent events */ +/* The name of the event posted when [BFURL URLWithURL:] is called successfully. This represents the successful parsing of an app link URL.*/ +FOUNDATION_EXPORT NSString *const BFAppLinkParseEventName; + +/* The name of the event posted when [BFURL URLWithInboundURL:] is called successfully. This represents parsing an inbound app link URL + * from a different application + */ +FOUNDATION_EXPORT NSString *const BFAppLinkNavigateInEventName; + @class BFAppLink; /*! @@ -19,11 +28,20 @@ @interface BFURL : NSObject /*! - Creates a link target from a raw URL. Usually, this will be used to parse a URL passed into - an app delegate's handleOpenURL: method. + Creates a link target from a raw URL. + On success, this posts the BFAppLinkParseEventName measurement event. If you are constructing the BFURL within your application delegate's + application:openURL:sourceApplication:annotation:, you should instead use URLWithInboundURL:sourceApplication: + to support better BFMeasurementEvent notifications */ + (BFURL *)URLWithURL:(NSURL *)url; +/*! + Creates a link target from a raw URL received from an external application. This is typically called from the app delegate's + application:openURL:sourceApplication:annotation: and will post the BFAppLinkNavigateInEventName measurement event. + sourceApplication is the bundle ID of the app that is requesting your app to open the URL (url). +*/ ++ (BFURL *)URLWithInboundURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication; + /*! Gets the target URL. If the link is an App Link, this is the target of the App Link. Otherwise, it is the url that created the target. diff --git a/Bolts/BFURL.m b/Bolts/BFURL.m index 99a9733fa..5c95c80eb 100644 --- a/Bolts/BFURL.m +++ b/Bolts/BFURL.m @@ -9,8 +9,9 @@ */ #import "BFURL.h" -#import "BFAppLink.h" +#import "BFAppLink_Internal.h" #import "BFAppLinkTarget.h" +#import "BFMeasurementEvent.h" FOUNDATION_EXPORT NSString *const BFAppLinkDataParameterName; FOUNDATION_EXPORT NSString *const BFAppLinkTargetKeyName; @@ -21,9 +22,13 @@ FOUNDATION_EXPORT NSString *const BFAppLinkRefererAppName; FOUNDATION_EXPORT NSString *const BFAppLinkRefererUrl; +/* app Link Event raised by this BFURL */ +NSString *const BFAppLinkParseEventName = @"al_link_parse"; +NSString *const BFAppLinkNavigateInEventName = @"al_nav_in"; + @implementation BFURL -- (id)initWithURL:(NSURL *)url { +- (id)initWithURL:(NSURL *)url forOpenInboundURL:(BOOL)forOpenURLEvent sourceApplication:(NSString *)sourceApplication forRenderBackToReferrerBar:(BOOL)forRenderBackToReferrerBar { if (self = [super init]) { _inputURL = url; _targetURL = url; @@ -66,7 +71,38 @@ - (id)initWithURL:(NSURL *)url { appName:refererAppName]; _appLinkReferer = [BFAppLink appLinkWithSourceURL:[NSURL URLWithString:refererURLString] targets:@[target] - webURL:nil]; + webURL:nil + isBackToReferrer:YES]; + } + + // Raise Measurement Event + NSString *const EVENT_YES_VAL = @"1"; + NSString *const EVENT_NO_VAL = @"0"; + NSMutableDictionary * logData = [[NSMutableDictionary alloc] init]; + logData[@"version"] = version; + if (refererURLString) { + logData[@"refererURL"] = refererURLString; + } + if (refererAppName) { + logData[@"refererAppName"] = refererAppName; + } + if (sourceApplication) { + logData[@"sourceApplication"] = sourceApplication; + } + if ([_targetURL absoluteString]) { + logData[@"targetURL"] = [_targetURL absoluteString]; + } + if ([_inputURL absoluteString]) { + logData[@"inputURL"] = [_inputURL absoluteString]; + } + if ([_inputURL scheme]) { + logData[@"inputURLScheme"] = [_inputURL scheme]; + } + logData[@"forRenderBackToReferrerBar"] = forRenderBackToReferrerBar ? EVENT_YES_VAL : EVENT_NO_VAL; + logData[@"forOpenUrl"] = forOpenURLEvent ? EVENT_YES_VAL : EVENT_NO_VAL; + [BFMeasurementEvent postNotificationForEventName:BFAppLinkParseEventName args:logData]; + if (forOpenURLEvent) { + [BFMeasurementEvent postNotificationForEventName:BFAppLinkNavigateInEventName args:logData]; } } } @@ -76,7 +112,15 @@ - (id)initWithURL:(NSURL *)url { } + (BFURL *)URLWithURL:(NSURL *)url { - return [[BFURL alloc] initWithURL:url]; + return [[BFURL alloc] initWithURL:url forOpenInboundURL:NO sourceApplication:nil forRenderBackToReferrerBar:NO]; +} + ++ (BFURL *)URLWithInboundURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication { + return [[BFURL alloc] initWithURL:url forOpenInboundURL:YES sourceApplication:sourceApplication forRenderBackToReferrerBar:NO]; +} + ++ (BFURL *)URLForRenderBackToReferrerBarURL:(NSURL *)url { + return [[BFURL alloc] initWithURL:url forOpenInboundURL:NO sourceApplication:nil forRenderBackToReferrerBar:YES]; } + (NSString *)decodeURLString:(NSString *)string { diff --git a/Bolts/BFURL_Internal.h b/Bolts/BFURL_Internal.h new file mode 100644 index 000000000..676e66562 --- /dev/null +++ b/Bolts/BFURL_Internal.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import "BFURL.h" + +@interface BFURL (Internal) ++ (BFURL *)URLForRenderBackToReferrerBarURL:(NSURL *)url; +@end diff --git a/Bolts/Bolts.h b/Bolts/Bolts.h index b49e2a11b..b8985d688 100644 --- a/Bolts/Bolts.h +++ b/Bolts/Bolts.h @@ -18,6 +18,9 @@ #import "BFAppLink.h" #import "BFAppLinkTarget.h" #import "BFURL.h" +#import "BFMeasurementEvent.h" +#import "BFAppLinkReturnToRefererController.h" +#import "BFAppLinkReturnToRefererView.h" #endif /*! @abstract 80175001: There were multiple errors. */