diff --git a/DEVELOPING.md b/DEVELOPING.md
index 7e4fc621..d823b633 100644
--- a/DEVELOPING.md
+++ b/DEVELOPING.md
@@ -59,7 +59,7 @@ gulp prerelease;
> **[optional]** Update [iOS SDK](https://github.com/BranchMetrics/ios-branch-deep-linking/tags) (will need to update `plugin.xml` dependencies if new iOS files)
```sh
-./src/ios/dependencies/update.sh 0.12.14;
+./src/ios/dependencies/update.sh 0.12.20;
```
### Test
@@ -67,7 +67,7 @@ gulp prerelease;
> Modify `BRANCH_KEY` and `URI_SCHEME` and `config.xml` to values in [Branch Dashboard](https://dashboard.branch.io/settings/link)
```sh
-gulp prerelease && cd testbed && npm install -g cordova && cordova platform remove ios && cordova platform remove android && cordova platform remove browser && cordova platform add ios && cordova platform add android && cordova plugin remove io.branch.sdk && cordova plugin add ../ --variable BRANCH_KEY=key_live_icCccJIpd7GlYY5oOmoEtpafuDiuyXhT --variable URI_SCHEME=enefftest;
+gulp prerelease; cd testbed; npm install -g cordova; cordova platform remove ios; cordova platform remove android; cordova platform remove browser; cordova platform add ios; cordova platform add android; cordova plugin remove io.branch.sdk; cordova plugin add ../ --variable BRANCH_KEY=key_live_icCccJIpd7GlYY5oOmoEtpafuDiuyXhT --variable URI_SCHEME=enefftest;
# cordova plugin add branch-cordova-sdk --variable BRANCH_KEY=key_live_icCccJIpd7GlYY5oOmoEtpafuDiuyXhT --variable URI_SCHEME=enefftest;
```
@@ -75,11 +75,11 @@ gulp prerelease && cd testbed && npm install -g cordova && cordova platform remo
> Validate all features on both `iOS` and `Android` on `device` only (no `simulator` or `TestFlight`)
```sh
-cordova build ios --developmentTeam="PW4Q8885U7" --device;
+cordova build ios && open -a Xcode platforms/ios/Branch\ Testing.xcworkspace;
```
```sh
-cordova build android && cordova run android;
+cordova build android; cordova run android;
chrome://inspect/#devices
```
diff --git a/README.md b/README.md
index 68b7ab52..1cbc4bbb 100644
--- a/README.md
+++ b/README.md
@@ -205,9 +205,9 @@
- Delete your app from the device *(resets the Apple AASA scraping)*
- - Compile your app *(`cordova build ios --developmentTeam="PW4Q8885U7" --device;`)*
+ - Compile your app *(`cordova build ios` `phone gap build ios` `ionic build ios`)*
- - Open the app in Xcode and set your Provisioning Profile `Development Team`
+ - Open the app in `Xcode` and set your Provisioning Profile `Development Team`
- Launch your app to `device` *(not Simulator or TestFlight)*
@@ -225,7 +225,7 @@
- Delete your app from the device
- - Compile your app *(`cordova run android`)*
+ - Compile your app *(`cordova build android` `phone gap build android` `ionic build android`)*
- Launch your app to `device` *(not Simulator or Genymotion)*
@@ -328,6 +328,7 @@
$android_url: 'http://www.example.com/android',
$ios_url: 'http://www.example.com/ios',
$ipad_url: 'http://www.example.com/ipad',
+ $deeplink_path: "content/123",
more_custom: 'data',
even_more_custom: true,
this_is_custom: 321
@@ -700,6 +701,8 @@
- Always use the `Branch.initSession(function(data) {});` to read Deep Link data
- Always test on `device` (`simulator` `browser` `genymotion` will break)
+
+ - You must launch the app through `Xcode` for iOS
- Other deep link plugins (ex `cordova-universal-links-plugin`) will interferer with Branch
diff --git a/plugin.xml b/plugin.xml
index 48f5bd75..1fac340a 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -120,6 +120,7 @@ SOFTWARE.
+
diff --git a/src/android/io/branch/BranchSDK.java b/src/android/io/branch/BranchSDK.java
index feee1b74..1130628d 100644
--- a/src/android/io/branch/BranchSDK.java
+++ b/src/android/io/branch/BranchSDK.java
@@ -350,7 +350,6 @@ private void getFirstReferringParams(CallbackContext callbackContext) {
*/
private void createBranchUniversalObject(JSONObject options, CallbackContext callbackContext) throws JSONException {
-
BranchUniversalObject branchObj = new BranchUniversalObject();
// Set object properties
@@ -373,7 +372,6 @@ private void createBranchUniversalObject(JSONObject options, CallbackContext cal
// Set content visibility
if (options.has("contentIndexingMode")) {
-
if (options.getString("contentIndexingMode").equals("private")) {
branchObj.setContentIndexingMode(BranchUniversalObject.CONTENT_INDEX_MODE.PRIVATE);
} else {
@@ -447,6 +445,7 @@ private BranchLinkProperties createLinkProperties(JSONObject options, JSONObject
BranchLinkProperties linkProperties = new BranchLinkProperties();
+ // Add link properties
if (options.has("feature")) {
linkProperties.setFeature(options.getString("feature"));
}
@@ -465,39 +464,26 @@ private BranchLinkProperties createLinkProperties(JSONObject options, JSONObject
if (options.has("duration")) {
linkProperties.setDuration(options.getInt("duration"));
}
-
if (options.has("tags")) {
JSONArray array = (JSONArray) options.get("tags");
if (array != null) {
- for (int i=0;i keys = controlParams.keys();
+
+ while (keys.hasNext()) {
+ String key = keys.next().toString();
+
+ Log.d(LCAT, String.format("key: %s", key));
+
+ linkProperties.addControlParameter(key, controlParams.getString(key));
}
return linkProperties;
diff --git a/src/ios/dependencies/Branch-SDK/BNCCallbacks.h b/src/ios/dependencies/Branch-SDK/BNCCallbacks.h
index 7b47030e..a0c74409 100644
--- a/src/ios/dependencies/Branch-SDK/BNCCallbacks.h
+++ b/src/ios/dependencies/Branch-SDK/BNCCallbacks.h
@@ -11,11 +11,11 @@
@class BranchUniversalObject, BranchLinkProperties;
-typedef void (^callbackWithParams) (NSDictionary * _Nonnull params, NSError * _Nullable error);
-typedef void (^callbackWithUrl) (NSString * _Nonnull url, NSError * _Nullable error);
+typedef void (^callbackWithParams) (NSDictionary * _Nullable params, NSError * _Nullable error);
+typedef void (^callbackWithUrl) (NSString * _Nullable url, NSError * _Nullable error);
typedef void (^callbackWithStatus) (BOOL changed, NSError * _Nullable error);
typedef void (^callbackWithList) (NSArray * _Nullable list, NSError * _Nullable error);
typedef void (^callbackWithUrlAndSpotlightIdentifier) (NSString * _Nullable url, NSString * _Nullable spotlightIdentifier, NSError * _Nullable error);
-typedef void (^callbackWithBranchUniversalObject) (BranchUniversalObject * _Nonnull universalObject, BranchLinkProperties * _Nonnull linkProperties, NSError * _Nullable error);
+typedef void (^callbackWithBranchUniversalObject) (BranchUniversalObject * _Nullable universalObject, BranchLinkProperties * _Nullable linkProperties, NSError * _Nullable error);
#endif /* BNCCallbacks_h */
diff --git a/src/ios/dependencies/Branch-SDK/BNCConfig.h b/src/ios/dependencies/Branch-SDK/BNCConfig.h
index 03f374fb..9a1f1826 100644
--- a/src/ios/dependencies/Branch-SDK/BNCConfig.h
+++ b/src/ios/dependencies/Branch-SDK/BNCConfig.h
@@ -6,29 +6,9 @@
// Copyright (c) 2014 Branch Metrics. All rights reserved.
//
-#ifndef Branch_SDK_Config_h
-#define Branch_SDK_Config_h
+#import
-#define SDK_VERSION @"0.12.19"
-
-#define BNC_PROD_ENV
-//#define BNC_STAGE_ENV
-//#define BNC_DEV_ENV
-
-#ifdef BNC_PROD_ENV
-#define BNC_API_BASE_URL @"https://api.branch.io"
-#endif
-
-#ifdef BNC_STAGE_ENV
-#define BNC_API_BASE_URL @"http://api.dev.branch.io"
-#endif
-
-#define BNC_LINK_URL @"https://bnc.lt"
-
-#ifdef BNC_DEV_ENV
-#define BNC_API_BASE_URL @"http://localhost:3001"
-#endif
-
-#define BNC_API_VERSION @"v1"
-
-#endif
+extern NSString * const SDK_VERSION;
+extern NSString * const BNC_API_BASE_URL;
+extern NSString * const BNC_LINK_URL;
+extern NSString * const BNC_API_VERSION;
diff --git a/src/ios/dependencies/Branch-SDK/BNCConfig.m b/src/ios/dependencies/Branch-SDK/BNCConfig.m
new file mode 100644
index 00000000..3d5e1a66
--- /dev/null
+++ b/src/ios/dependencies/Branch-SDK/BNCConfig.m
@@ -0,0 +1,14 @@
+//
+// BNCConfig.c
+// Branch-TestBed
+//
+// Created by edward on 12/12/16.
+// Copyright © 2016 Branch Metrics. All rights reserved.
+//
+
+#include "BNCConfig.h"
+
+NSString * const BNC_API_BASE_URL = @"https://api.branch.io";
+NSString * const BNC_API_VERSION = @"v1";
+NSString * const BNC_LINK_URL = @"https://bnc.lt";
+NSString * const SDK_VERSION = @"0.12.20";
diff --git a/src/ios/dependencies/Branch-SDK/BNCDeviceInfo.m b/src/ios/dependencies/Branch-SDK/BNCDeviceInfo.m
index 2fc417cd..0669df5f 100644
--- a/src/ios/dependencies/Branch-SDK/BNCDeviceInfo.m
+++ b/src/ios/dependencies/Branch-SDK/BNCDeviceInfo.m
@@ -46,7 +46,7 @@ - (id)init {
self.isRealHardwareId = isRealHardwareId;
self.hardwareIdType = hardwareIdType;
}
-
+
self.vendorId = [BNCSystemObserver getVendorId];
self.brandName = [BNCSystemObserver getBrand];
self.modelName = [BNCSystemObserver getModel];
@@ -83,10 +83,21 @@ - (id)init {
}
- self.browserUserAgent =
- [[[UIWebView alloc]
- initWithFrame:CGRectZero]
- stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
+ void (^setUpBrowserUserAgent)() = ^() {
+ self.browserUserAgent = [[[UIWebView alloc]
+ initWithFrame:CGRectZero]
+ stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
+ };
+
+ if (NSThread.isMainThread) {
+
+ setUpBrowserUserAgent();
+
+ } else {
+
+ dispatch_sync(dispatch_get_main_queue(), setUpBrowserUserAgent);
+
+ }
return self;
}
diff --git a/src/ios/dependencies/Branch-SDK/BNCPreferenceHelper.m b/src/ios/dependencies/Branch-SDK/BNCPreferenceHelper.m
index 462d4863..f54e5a1b 100644
--- a/src/ios/dependencies/Branch-SDK/BNCPreferenceHelper.m
+++ b/src/ios/dependencies/Branch-SDK/BNCPreferenceHelper.m
@@ -374,17 +374,20 @@ - (void)setUniversalLinkUrl:(NSString *)universalLinkUrl {
}
- (NSString *)sessionParams {
- if (_sessionParams) {
- _sessionParams = [self readStringFromDefaults:BRANCH_PREFS_KEY_SESSION_PARAMS];
+ @synchronized (self) {
+ if (!_sessionParams) {
+ _sessionParams = [self readStringFromDefaults:BRANCH_PREFS_KEY_SESSION_PARAMS];
+ }
+ return _sessionParams;
}
-
- return _sessionParams;
}
- (void)setSessionParams:(NSString *)sessionParams {
- if (![_sessionParams isEqualToString:sessionParams]) {
- _sessionParams = sessionParams;
- [self writeObjectToDefaults:BRANCH_PREFS_KEY_SESSION_PARAMS value:sessionParams];
+ @synchronized (self) {
+ if (![_sessionParams isEqualToString:sessionParams]) {
+ _sessionParams = sessionParams;
+ [self writeObjectToDefaults:BRANCH_PREFS_KEY_SESSION_PARAMS value:sessionParams];
+ }
}
}
@@ -479,22 +482,28 @@ - (void)setRequestMetadataKey:(NSString *)key value:(NSObject *)value {
}
- (NSMutableDictionary *)instrumentationDictionary {
- if (!_instrumentationDictionary) {
- _instrumentationDictionary = [NSMutableDictionary dictionary];
+ @synchronized (self) {
+ if (!_instrumentationDictionary) {
+ _instrumentationDictionary = [NSMutableDictionary dictionary];
+ }
+ return _instrumentationDictionary;
}
- return _instrumentationDictionary;
}
- (void)addInstrumentationDictionaryKey:(NSString *)key value:(NSString *)value {
- if (key && value) {
- [self.instrumentationDictionary setObject:value forKey:key];
+ @synchronized (self) {
+ if (key && value) {
+ [self.instrumentationDictionary setObject:value forKey:key];
+ }
}
}
- (void)clearInstrumentationDictionary {
- NSArray *keys = [_instrumentationDictionary allKeys];
- for (int i = 0 ; i < [keys count]; i++) {
- [_instrumentationDictionary removeObjectForKey:keys[i]];
+ @synchronized (self) {
+ NSArray *keys = [_instrumentationDictionary allKeys];
+ for (int i = 0 ; i < [keys count]; i++) {
+ [_instrumentationDictionary removeObjectForKey:keys[i]];
+ }
}
}
@@ -606,42 +615,48 @@ - (NSDictionary *)getContentAnalyticsManifest {
return (NSDictionary *)[self readObjectFromDefaults:BRANCH_PREFS_KEY_ANALYTICS_MANIFEST];
}
+
#pragma mark - Writing To Persistence
+
- (void)writeIntegerToDefaults:(NSString *)key value:(NSInteger)value {
- self.persistenceDict[key] = @(value);
- [self persistPrefsToDisk];
+ [self writeObjectToDefaults:key value:@(value)];
}
- (void)writeBoolToDefaults:(NSString *)key value:(BOOL)value {
- self.persistenceDict[key] = @(value);
- [self persistPrefsToDisk];
+ [self writeObjectToDefaults:key value:@(value)];
}
- (void)writeObjectToDefaults:(NSString *)key value:(NSObject *)value {
- if (value) {
- self.persistenceDict[key] = value;
- }
- else {
- [self.persistenceDict removeObjectForKey:key];
+ @synchronized (self) {
+ if (value) {
+ self.persistenceDict[key] = value;
+ }
+ else {
+ [self.persistenceDict removeObjectForKey:key];
+ }
+ [self persistPrefsToDisk];
}
-
- [self persistPrefsToDisk];
}
- (void)persistPrefsToDisk {
@synchronized (self) {
- NSDictionary *persistenceDict = [self.persistenceDict copy];
+ if (!self.persistenceDict) return;
+ NSData *data = nil;
+ @try {
+ data = [NSKeyedArchiver archivedDataWithRootObject:self.persistenceDict];
+ }
+ @catch (id exception) {
+ data = nil;
+ [self logWarning:
+ [NSString stringWithFormat:@"Exception creating preferences data: %@.",
+ exception]];
+ }
+ if (!data) {
+ [self logWarning:@"Can't create preferences data."];
+ return;
+ }
NSBlockOperation *newPersistOp = [NSBlockOperation blockOperationWithBlock:^ {
- NSData *data = nil;
- @try {
- data = [NSKeyedArchiver archivedDataWithRootObject:persistenceDict];
- } @catch (id n) {
- }
- if (!data) {
- [self logWarning:@"Can't create preferences archive."];
- return;
- }
NSError *error = nil;
[data writeToURL:self.class.URLForPrefsFile
options:NSDataWritingAtomic error:&error];
@@ -651,7 +666,7 @@ - (void)persistPrefsToDisk {
@"Failed to persist preferences to disk: %@.", error]];
}
}];
- [self.persistPrefsQueue addOperation:newPersistOp];
+ [self.persistPrefsQueue addOperation:newPersistOp];
}
}
diff --git a/src/ios/dependencies/Branch-SDK/BNCServerRequestQueue.h b/src/ios/dependencies/Branch-SDK/BNCServerRequestQueue.h
index 44eab536..fd0286d1 100755
--- a/src/ios/dependencies/Branch-SDK/BNCServerRequestQueue.h
+++ b/src/ios/dependencies/Branch-SDK/BNCServerRequestQueue.h
@@ -26,6 +26,7 @@
- (void)clearQueue;
- (BOOL)containsInstallOrOpen;
+- (BOOL)removeInstallOrOpen;
- (BOOL)containsClose;
- (BranchOpenRequest *)moveInstallOrOpenToFront:(NSInteger)networkCount;
diff --git a/src/ios/dependencies/Branch-SDK/BNCServerRequestQueue.m b/src/ios/dependencies/Branch-SDK/BNCServerRequestQueue.m
index 219bb486..b59538eb 100755
--- a/src/ios/dependencies/Branch-SDK/BNCServerRequestQueue.m
+++ b/src/ios/dependencies/Branch-SDK/BNCServerRequestQueue.m
@@ -131,6 +131,21 @@ - (BOOL)containsInstallOrOpen {
return NO;
}
+- (BOOL)removeInstallOrOpen {
+ @synchronized (self.queue) {
+ for (int i = 0; i < self.queue.count; i++) {
+ BranchOpenRequest *req = [self.queue objectAtIndex:i];
+ // Install extends open, so only need to check open.
+ if ([req isKindOfClass:[BranchOpenRequest class]]) {
+ req.callback = nil;
+ [self remove:req];
+ return YES;
+ }
+ }
+ return NO;
+ }
+}
+
- (BranchOpenRequest *)moveInstallOrOpenToFront:(NSInteger)networkCount {
BOOL requestAlreadyInProgress = networkCount > 0;
diff --git a/src/ios/dependencies/Branch-SDK/BNCStrongMatchHelper.h b/src/ios/dependencies/Branch-SDK/BNCStrongMatchHelper.h
index f908f542..f93cbf9b 100644
--- a/src/ios/dependencies/Branch-SDK/BNCStrongMatchHelper.h
+++ b/src/ios/dependencies/Branch-SDK/BNCStrongMatchHelper.h
@@ -6,14 +6,17 @@
// Copyright © 2015 Branch Metrics. All rights reserved.
//
+
#import
#import
+
@interface BNCStrongMatchHelper : NSObject
+ (BNCStrongMatchHelper *)strongMatchHelper;
- (void)createStrongMatchWithBranchKey:(NSString *)branchKey;
- (BOOL)shouldDelayInstallRequest;
-+ (NSURL *)getUrlForCookieBasedMatchingWithBranchKey:(NSString *)branchKey redirectUrl:(NSString *)redirectUrl;
++ (NSURL *)getUrlForCookieBasedMatchingWithBranchKey:(NSString *)branchKey
+ redirectUrl:(NSString *)redirectUrl;
@end
diff --git a/src/ios/dependencies/Branch-SDK/BNCStrongMatchHelper.m b/src/ios/dependencies/Branch-SDK/BNCStrongMatchHelper.m
index dc294808..f1d533aa 100644
--- a/src/ios/dependencies/Branch-SDK/BNCStrongMatchHelper.m
+++ b/src/ios/dependencies/Branch-SDK/BNCStrongMatchHelper.m
@@ -6,36 +6,117 @@
// Copyright © 2015 Branch Metrics. All rights reserved.
//
+
#import "BNCStrongMatchHelper.h"
+#import
#import "BNCConfig.h"
#import "BNCPreferenceHelper.h"
#import "BNCSystemObserver.h"
#import "BranchConstants.h"
-// Stub the class for older Xcode versions, methods don't actually do anything.
-#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < 90000
+
+#pragma mark BNCStrongMatchHelper iOS 8.0
+
+
+// This is a stub the class for older Xcode versions. These methods don't do anything.
+#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < 90000 // iOS < 9.0
@implementation BNCStrongMatchHelper
-+ (BNCStrongMatchHelper *)strongMatchHelper { return nil; }
-- (void)createStrongMatchWithBranchKey:(NSString *)branchKey { }
-- (BOOL)shouldDelayInstallRequest { return NO; }
-+ (NSURL *)getUrlForCookieBasedMatchingWithBranchKey:(NSString *)branchKey redirectUrl:(NSString *)redirectUrl { return nil; }
++ (BNCStrongMatchHelper *)strongMatchHelper {
+ return nil;
+}
+
+- (void)createStrongMatchWithBranchKey:(NSString *)branchKey {
+}
+
+- (BOOL)shouldDelayInstallRequest {
+ return NO;
+}
+
++ (NSURL *)getUrlForCookieBasedMatchingWithBranchKey:(NSString *)branchKey
+ redirectUrl:(NSString *)redirectUrl {
+ return nil;
+}
@end
-#else
-NSInteger const ABOUT_30_DAYS_TIME_IN_SECONDS = 60 * 60 * 24 * 30;
+#else // ------------------------------------------------------------------------------ iOS >= 9.0
+#import
-@interface BNCStrongMatchHelper ()
-@property (strong, nonatomic) UIWindow *secondWindow;
+#pragma mark - BNCMatchView
+
+
+@interface BNCMatchView : UIView
+@end
+
+
+@implementation BNCMatchView
+
+- (instancetype) initWithFrame:(CGRect)frame {
+ self = [super initWithFrame:frame];
+ self.alpha = 0.0;
+ return self;
+}
+
+- (void) setAlpha:(CGFloat)alpha {
+ [super setAlpha:0.0];
+}
+
+- (CGFloat) alpha {
+ return 1.0;
+}
+
+@end
+
+
+#pragma mark - BNCMatchViewController
+
+
+// This is a class interface that will be dynamically subclassed from SFSafariViewController
+@interface BNCMatchViewController : UIViewController
+@end
+
+
+@implementation BNCMatchViewController
+
+- (instancetype) initWithURL:(NSURL*)URL {
+ self = [super init];
+ return self;
+}
+
+- (BOOL) canBecomeFirstResponder {
+ return NO;
+}
+
+- (BOOL) becomeFirstResponder {
+ return NO;
+}
+
+- (UIResponder*) nextResponder {
+ return nil;
+}
+
+- (void) setDelegate:(id)delegate {
+}
+
+@end
+
+
+#pragma mark - BNCStrongMatchHelper iOS 9.0
+
+
+@interface BNCStrongMatchHelper ()
@property (assign, nonatomic) BOOL requestInProgress;
@property (assign, nonatomic) BOOL shouldDelayInstallRequest;
-
+@property (strong, nonatomic) UIWindow *primaryWindow;
+@property (strong, nonatomic) BNCMatchView *matchView;
+@property (strong, nonatomic) BNCMatchViewController *matchViewController;
@end
+
@implementation BNCStrongMatchHelper
+ (BNCStrongMatchHelper *)strongMatchHelper {
@@ -49,7 +130,8 @@ + (BNCStrongMatchHelper *)strongMatchHelper {
return strongMatchHelper;
}
-+ (NSURL *)getUrlForCookieBasedMatchingWithBranchKey:(NSString *)branchKey redirectUrl:(NSString *)redirectUrl {
++ (NSURL *)getUrlForCookieBasedMatchingWithBranchKey:(NSString *)branchKey
+ redirectUrl:(NSString *)redirectUrl {
if (!branchKey) {
return nil;
}
@@ -62,12 +144,16 @@ + (NSURL *)getUrlForCookieBasedMatchingWithBranchKey:(NSString *)branchKey redir
} else {
appDomainLinkURL = BNC_LINK_URL;
}
- NSMutableString *urlString = [[NSMutableString alloc] initWithFormat:@"%@/_strong_match?os=%@", appDomainLinkURL, [BNCSystemObserver getOS]];
+ NSMutableString *urlString =
+ [[NSMutableString alloc] initWithFormat:@"%@/_strong_match?os=%@",
+ appDomainLinkURL, [BNCSystemObserver getOS]];
BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper preferenceHelper];
BOOL isRealHardwareId;
NSString *hardwareIdType;
- NSString *hardwareId = [BNCSystemObserver getUniqueHardwareId:&isRealHardwareId isDebug:preferenceHelper.isDebug andType:&hardwareIdType];
+ NSString *hardwareId =
+ [BNCSystemObserver getUniqueHardwareId:&isRealHardwareId
+ isDebug:preferenceHelper.isDebug andType:&hardwareIdType];
if (!hardwareId || !isRealHardwareId) {
[preferenceHelper logWarning:@"Cannot use cookie-based matching while setDebug is enabled"];
return nil;
@@ -76,88 +162,160 @@ + (NSURL *)getUrlForCookieBasedMatchingWithBranchKey:(NSString *)branchKey redir
[urlString appendFormat:@"&%@=%@", BRANCH_REQUEST_KEY_HARDWARE_ID, hardwareId];
if (preferenceHelper.deviceFingerprintID) {
- [urlString appendFormat:@"&%@=%@", BRANCH_REQUEST_KEY_DEVICE_FINGERPRINT_ID, preferenceHelper.deviceFingerprintID];
+ [urlString appendFormat:@"&%@=%@",
+ BRANCH_REQUEST_KEY_DEVICE_FINGERPRINT_ID,
+ preferenceHelper.deviceFingerprintID];
}
if ([BNCSystemObserver getAppVersion]) {
- [urlString appendFormat:@"&%@=%@", BRANCH_REQUEST_KEY_APP_VERSION, [BNCSystemObserver getAppVersion]];
+ [urlString appendFormat:@"&%@=%@",
+ BRANCH_REQUEST_KEY_APP_VERSION,
+ [BNCSystemObserver getAppVersion]];
}
[urlString appendFormat:@"&branch_key=%@", branchKey];
-
[urlString appendFormat:@"&sdk=ios%@", SDK_VERSION];
if (redirectUrl) {
- [urlString appendFormat:@"&redirect_url=%@", [redirectUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
+ [urlString appendFormat:@"&redirect_url=%@",
+ [redirectUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
- return [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
+ NSString *escapedURL =
+ [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+ return [NSURL URLWithString:escapedURL];
}
- (void)createStrongMatchWithBranchKey:(NSString *)branchKey {
- if (self.requestInProgress) {
- return;
- }
+ @synchronized (self) {
+ if (self.requestInProgress) return;
- self.requestInProgress = YES;
-
- NSDate *thirtyDaysAgo = [NSDate dateWithTimeIntervalSinceNow:-ABOUT_30_DAYS_TIME_IN_SECONDS];
- NSDate *lastCheck = [BNCPreferenceHelper preferenceHelper].lastStrongMatchDate;
- if ([lastCheck compare:thirtyDaysAgo] == NSOrderedDescending) {
- self.requestInProgress = NO;
- return;
- }
-
- self.shouldDelayInstallRequest = YES;
- [self presentSafariVCWithBranchKey:branchKey];
-}
+ NSInteger const ABOUT_30_DAYS_TIME_IN_SECONDS = 60 * 60 * 24 * 30;
+ NSDate *thirtyDaysAgo = [NSDate dateWithTimeIntervalSinceNow:-ABOUT_30_DAYS_TIME_IN_SECONDS];
+ NSDate *lastCheck = [BNCPreferenceHelper preferenceHelper].lastStrongMatchDate;
+ if ([lastCheck compare:thirtyDaysAgo] == NSOrderedDescending) return;
+
+ NSURL *strongMatchUrl =
+ [BNCStrongMatchHelper
+ getUrlForCookieBasedMatchingWithBranchKey:branchKey
+ redirectUrl:nil];
+ if (!strongMatchUrl) return;
+
+ self.requestInProgress = YES;
+ self.shouldDelayInstallRequest = YES;
-- (void)presentSafariVCWithBranchKey:(NSString *)branchKey {
- NSURL *strongMatchUrl = [BNCStrongMatchHelper getUrlForCookieBasedMatchingWithBranchKey:branchKey redirectUrl:nil];
- if (!strongMatchUrl) {
- self.shouldDelayInstallRequest = NO;
- self.requestInProgress = NO;
- return;
- }
-
- Class SFSafariViewControllerClass = NSClassFromString(@"SFSafariViewController");
- Class UIApplicationClass = NSClassFromString(@"UIApplication");
- if (SFSafariViewControllerClass) {
-
// Must be on next run loop to avoid a warning
dispatch_async(dispatch_get_main_queue(), ^{
- UIViewController * safController = [[SFSafariViewControllerClass alloc] initWithURL:strongMatchUrl];
- self.secondWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
- self.secondWindow.rootViewController = safController;
- self.secondWindow.windowLevel = UIWindowLevelNormal - 100;
- [self.secondWindow setHidden:NO];
- UIWindow *keyWindow = [[UIApplicationClass sharedApplication] keyWindow];
- [self.secondWindow makeKeyWindow];
-
- // Give enough time for Safari to load the request (optimized for 3G)
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [keyWindow makeKeyWindow];
-
- // Remove the window and release it's strong reference. This is important to ensure that
- // applications using view controller based status bar appearance are restored.
- [self.secondWindow removeFromSuperview];
- self.secondWindow = nil;
-
- [BNCPreferenceHelper preferenceHelper].lastStrongMatchDate = [NSDate date];
+
+ if (![self willLoadViewControllerWithURL:strongMatchUrl]) {
+ self.shouldDelayInstallRequest = NO;
self.requestInProgress = NO;
- });
+ return;
+ }
+
+ // Give enough time for Safari to load the request (optimized for 3G)
+ dispatch_after(
+ dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)),
+ dispatch_get_main_queue(),
+ ^{ [self unloadViewController]; }
+ );
});
}
- else {
- self.requestInProgress = NO;
+}
+
+- (BOOL) subclass:(Class)subclass selector:(SEL)selector {
+ Class templateClass = objc_getClass("BNCMatchViewController");
+ if (!templateClass) return NO;
+
+ Method method = class_getInstanceMethod(templateClass, selector);
+ if (!method) return NO;
+
+ const char * typeEncoding = method_getTypeEncoding(method);
+ if (!typeEncoding) return NO;
+
+ IMP implementation = class_getMethodImplementation(templateClass, selector);
+ if (!implementation) return NO;
+
+ class_addMethod(subclass, selector, implementation, typeEncoding);
+ return YES;
+}
+
+- (BOOL) willLoadViewControllerWithURL:(NSURL*)matchURL {
+ if (self.primaryWindow) return NO;
+
+ // Dynamically subclass the SFSafariViewController if available.
+ // This allows us to compile and link to an app that doesn't
+ // include SafariServices, but is also able to compile and link
+ // when it is.
+
+ Class SFSafariViewControllerClass = NSClassFromString(@"SFSafariViewController");
+ if (!SFSafariViewControllerClass) return NO;
+
+ Class BNCMatchViewControllerSubclass = NSClassFromString(@"BNCMatchViewController_Safari");
+ if (!BNCMatchViewControllerSubclass) {
+ // The class isn't registered. Create it:
+
+ BNCMatchViewControllerSubclass =
+ objc_allocateClassPair(SFSafariViewControllerClass, "BNCMatchViewController_Safari", 0);
+ if (!BNCMatchViewControllerSubclass) return NO;
+
+ BOOL fail = NO;
+ fail |= ![self subclass:BNCMatchViewControllerSubclass selector:@selector(becomeFirstResponder)];
+ fail |= ![self subclass:BNCMatchViewControllerSubclass selector:@selector(canBecomeFirstResponder)];
+ fail |= ![self subclass:BNCMatchViewControllerSubclass selector:@selector(nextResponder)];
+ if (fail) {
+ objc_disposeClassPair(BNCMatchViewControllerSubclass);
+ return NO;
+ }
+ objc_registerClassPair(BNCMatchViewControllerSubclass);
}
+
+ NSLog(@"Safari initializing."); // eDebug
+ self.matchViewController = [[BNCMatchViewControllerSubclass alloc] initWithURL:matchURL];
+ if (!self.matchViewController) return NO;
+
+ self.primaryWindow = [[UIApplication sharedApplication] keyWindow];
+ self.matchViewController.delegate = self;
+ self.matchViewController.view.frame = self.primaryWindow.bounds;
+
+ self.matchView = [[BNCMatchView alloc] initWithFrame:self.primaryWindow.bounds];
+ self.matchView.alpha = 1.0;
+ [self.matchView addSubview:self.matchViewController.view];
+
+ [self.primaryWindow.rootViewController addChildViewController:self.matchViewController];
+ UIView *parentView = self.primaryWindow.rootViewController.view ?: self.primaryWindow;
+ [parentView insertSubview:self.matchView atIndex:0];
+
+ [self.matchViewController didMoveToParentViewController:self.primaryWindow.rootViewController];
+
+ return YES;
}
-- (BOOL)shouldDelayInstallRequest {
- return _shouldDelayInstallRequest;
+- (void) unloadViewController {
+ NSLog(@"Safari unloadViewController"); // eDebug
+
+ [self.matchViewController willMoveToParentViewController:nil];
+ [self.matchViewController.view removeFromSuperview];
+ [self.matchViewController removeFromParentViewController];
+ self.matchViewController.delegate = nil;
+ self.matchViewController = nil;
+
+ [self.matchView removeFromSuperview];
+ self.matchView = nil;
+
+ self.primaryWindow = nil;
+
+ [BNCPreferenceHelper preferenceHelper].lastStrongMatchDate = [NSDate date];
+ self.shouldDelayInstallRequest = NO;
+ self.requestInProgress = NO;
}
+- (void)safariViewController:(SFSafariViewController *)controller
+ didCompleteInitialLoad:(BOOL)didLoadSuccessfully {
+ NSLog(@"Safari Did load. Success: %d.", didLoadSuccessfully); // eDebug
+ [self unloadViewController];
+}
@end
-#endif
+#endif // ------------------------------------------------------------------------------ iOS >= 9.0
diff --git a/src/ios/dependencies/Branch-SDK/Branch.m b/src/ios/dependencies/Branch-SDK/Branch.m
index 5151e1ba..540f2edd 100644
--- a/src/ios/dependencies/Branch-SDK/Branch.m
+++ b/src/ios/dependencies/Branch-SDK/Branch.m
@@ -72,11 +72,10 @@ @interface Branch()
@property (strong, nonatomic) BNCServerInterface *bServerInterface;
-@property (strong, nonatomic) NSTimer *sessionTimer;
@property (strong, nonatomic) BNCServerRequestQueue *requestQueue;
@property (strong, nonatomic) dispatch_semaphore_t processing_sema;
-@property (strong, nonatomic) callbackWithParams sessionInitWithParamsCallback;
-@property (strong, nonatomic) callbackWithBranchUniversalObject sessionInitWithBranchUniversalObjectCallback;
+@property (copy, nonatomic) callbackWithParams sessionInitWithParamsCallback;
+@property (copy, nonatomic) callbackWithBranchUniversalObject sessionInitWithBranchUniversalObjectCallback;
@property (assign, nonatomic) NSInteger networkCount;
@property (assign, nonatomic) BOOL isInitialized;
@property (assign, nonatomic) BOOL shouldCallSessionInitCallback;
@@ -86,7 +85,7 @@ @interface Branch()
@property (strong, nonatomic) BNCContentDiscoveryManager *contentDiscoveryManager;
@property (strong, nonatomic) NSString *branchKey;
@property (strong, nonatomic) NSMutableDictionary *deepLinkControllers;
-@property (weak, nonatomic) UIViewController *deepLinkPresentingController;
+@property (weak, nonatomic) UIViewController *deepLinkPresentingController;
@property (assign, nonatomic) BOOL useCookieBasedMatching;
@property (strong, nonatomic) NSDictionary *deepLinkDebugParams;
@property (assign, nonatomic) BOOL accountForFacebookSDK;
@@ -94,7 +93,7 @@ @interface Branch()
@property (assign, nonatomic) BOOL delayForAppleAds;
@property (assign, nonatomic) BOOL searchAdsDebugMode;
@property (strong, nonatomic) NSMutableArray *whiteListedSchemeList;
-
+@property (assign, nonatomic) BOOL appIsInBackground;
@end
@implementation Branch
@@ -1152,6 +1151,7 @@ - (BNCLinkData *)prepareLinkDataFor:(NSArray *)tags andAlias:(NSString *)alias a
#pragma mark - BranchUniversalObject methods
+
- (void)registerViewWithParams:(NSDictionary *)params andCallback:(callbackWithParams)callback {
[self initSessionIfNeededAndNotInProgress];
@@ -1164,22 +1164,18 @@ - (void)registerViewWithParams:(NSDictionary *)params andCallback:(callbackWithP
#pragma mark - Application State Change methods
- (void)applicationDidBecomeActive {
- [self clearTimer];
+ self.appIsInBackground = NO;
if (!self.isInitialized && !self.preferenceHelper.shouldWaitForInit && ![self.requestQueue containsInstallOrOpen]) {
[self initUserSessionAndCallCallback:YES];
}
}
- (void)applicationWillResignActive {
- [self clearTimer];
- self.sessionTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(callClose) userInfo:nil repeats:NO];
+ self.appIsInBackground = YES;
+ [self callClose];
[self.requestQueue persistImmediately];
}
-- (void)clearTimer {
- [self.sessionTimer invalidate];
-}
-
- (void)callClose {
if (self.isInitialized) {
self.isInitialized = NO;
@@ -1268,11 +1264,7 @@ - (void)processNextQueueItem {
[req processResponse:nil error:[NSError errorWithDomain:BNCErrorDomain code:BNCInitError userInfo:@{ NSLocalizedDescriptionKey: @"Branch User Session has not been initialized" }]];
return;
}
-
- if (![req isKindOfClass:[BranchCloseRequest class]]) {
- [self clearTimer];
- }
-
+
[req makeRequest:self.bServerInterface key:self.branchKey callback:callback];
}
}
@@ -1338,26 +1330,17 @@ - (void)registerInstallOrOpen:(Class)clazz {
if ([BNCSystemObserver getOSVersion].integerValue >= 9 && self.useCookieBasedMatching) {
[[BNCStrongMatchHelper strongMatchHelper] createStrongMatchWithBranchKey:self.branchKey];
}
-
- // If there isn't already an Open / Install request, add one to the queue
- if (![self.requestQueue containsInstallOrOpen]) {
- BranchOpenRequest *req = [[clazz alloc] initWithCallback:initSessionCallback];
-
- [self insertRequestAtFront:req];
- }
- // If there is already one in the queue, make sure it's in the front.
- // Make sure a callback is associated with this request. This callback can
- // be cleared if the app is terminated while an Open/Install is pending.
- else {
- BranchOpenRequest *req = [self.requestQueue moveInstallOrOpenToFront:self.networkCount];
- req.callback = initSessionCallback;
- }
-
+
+ if ([self.requestQueue removeInstallOrOpen])
+ self.networkCount = 0;
+ BranchOpenRequest *req = [[clazz alloc] initWithCallback:initSessionCallback];
+ [self insertRequestAtFront:req];
[self processNextQueueItem];
}
- (void)handleInitSuccess {
- self.isInitialized = YES;
+ if (!self.appIsInBackground)
+ self.isInitialized = YES;
NSDictionary *latestReferringParams = [self getLatestReferringParams];
if (self.shouldCallSessionInitCallback) {
@@ -1433,7 +1416,7 @@ + (NSString *)bundleIdentifier {
}
+ (NSString *)kitDisplayVersion {
- return @"0.12.19";
+ return SDK_VERSION;
}
-@end
\ No newline at end of file
+@end
diff --git a/src/ios/dependencies/Branch-SDK/BranchActivityItemProvider.m b/src/ios/dependencies/Branch-SDK/BranchActivityItemProvider.m
index 2d183b4a..ebcbea98 100644
--- a/src/ios/dependencies/Branch-SDK/BranchActivityItemProvider.m
+++ b/src/ios/dependencies/Branch-SDK/BranchActivityItemProvider.m
@@ -94,6 +94,12 @@ + (NSString *)humanReadableChannelWithActivityType:(NSString *)activityString {
@"WeChat", @"com.tencent.xin.sharetimeline",
@"LINE", @"jp.naver.line.Share",
@"Pinterest", @"pinterest.ShareExtension",
+
+ // Keys for older app versions --
+
+ @"Facebook", @"com.facebook.Facebook.ShareExtension",
+ @"Twitter", @"com.atebits.Tweetie2.ShareExtension",
+
nil
];
// Set to a more human readible sting if we can identify it
diff --git a/src/ios/dependencies/Branch-SDK/Requests/BranchOpenRequest.h b/src/ios/dependencies/Branch-SDK/Requests/BranchOpenRequest.h
index db1315d3..14c10ab8 100644
--- a/src/ios/dependencies/Branch-SDK/Requests/BranchOpenRequest.h
+++ b/src/ios/dependencies/Branch-SDK/Requests/BranchOpenRequest.h
@@ -11,7 +11,7 @@
@interface BranchOpenRequest : BNCServerRequest
-@property (strong, nonatomic) callbackWithStatus callback;
+@property (copy, nonatomic) callbackWithStatus callback;
- (id)initWithCallback:(callbackWithStatus)callback;
- (id)initWithCallback:(callbackWithStatus)callback isInstall:(BOOL)isInstall;
diff --git a/src/ios/dependencies/Branch-SDK/Requests/BranchOpenRequest.m b/src/ios/dependencies/Branch-SDK/Requests/BranchOpenRequest.m
index 8d0f3655..1f5d0ec3 100644
--- a/src/ios/dependencies/Branch-SDK/Requests/BranchOpenRequest.m
+++ b/src/ios/dependencies/Branch-SDK/Requests/BranchOpenRequest.m
@@ -16,12 +16,12 @@
#import "BranchContentDiscoveryManifest.h"
#import "BranchContentDiscoverer.h"
-@interface BranchOpenRequest ()
+@interface BranchOpenRequest ()
@property (assign, nonatomic) BOOL isInstall;
-
@end
+
@implementation BranchOpenRequest
- (id)initWithCallback:(callbackWithStatus)callback {
diff --git a/src/ios/dependencies/Branch.framework/Versions/A/Branch b/src/ios/dependencies/Branch.framework/Versions/A/Branch
index 79c7484c..d9bc2ec2 100644
Binary files a/src/ios/dependencies/Branch.framework/Versions/A/Branch and b/src/ios/dependencies/Branch.framework/Versions/A/Branch differ
diff --git a/src/ios/dependencies/Branch.framework/Versions/A/Headers/BNCCallbacks.h b/src/ios/dependencies/Branch.framework/Versions/A/Headers/BNCCallbacks.h
index 7b47030e..a0c74409 100644
--- a/src/ios/dependencies/Branch.framework/Versions/A/Headers/BNCCallbacks.h
+++ b/src/ios/dependencies/Branch.framework/Versions/A/Headers/BNCCallbacks.h
@@ -11,11 +11,11 @@
@class BranchUniversalObject, BranchLinkProperties;
-typedef void (^callbackWithParams) (NSDictionary * _Nonnull params, NSError * _Nullable error);
-typedef void (^callbackWithUrl) (NSString * _Nonnull url, NSError * _Nullable error);
+typedef void (^callbackWithParams) (NSDictionary * _Nullable params, NSError * _Nullable error);
+typedef void (^callbackWithUrl) (NSString * _Nullable url, NSError * _Nullable error);
typedef void (^callbackWithStatus) (BOOL changed, NSError * _Nullable error);
typedef void (^callbackWithList) (NSArray * _Nullable list, NSError * _Nullable error);
typedef void (^callbackWithUrlAndSpotlightIdentifier) (NSString * _Nullable url, NSString * _Nullable spotlightIdentifier, NSError * _Nullable error);
-typedef void (^callbackWithBranchUniversalObject) (BranchUniversalObject * _Nonnull universalObject, BranchLinkProperties * _Nonnull linkProperties, NSError * _Nullable error);
+typedef void (^callbackWithBranchUniversalObject) (BranchUniversalObject * _Nullable universalObject, BranchLinkProperties * _Nullable linkProperties, NSError * _Nullable error);
#endif /* BNCCallbacks_h */
diff --git a/src/ios/dependencies/Branch.framework/Versions/A/Headers/BNCConfig.h b/src/ios/dependencies/Branch.framework/Versions/A/Headers/BNCConfig.h
index 03f374fb..9a1f1826 100644
--- a/src/ios/dependencies/Branch.framework/Versions/A/Headers/BNCConfig.h
+++ b/src/ios/dependencies/Branch.framework/Versions/A/Headers/BNCConfig.h
@@ -6,29 +6,9 @@
// Copyright (c) 2014 Branch Metrics. All rights reserved.
//
-#ifndef Branch_SDK_Config_h
-#define Branch_SDK_Config_h
+#import
-#define SDK_VERSION @"0.12.19"
-
-#define BNC_PROD_ENV
-//#define BNC_STAGE_ENV
-//#define BNC_DEV_ENV
-
-#ifdef BNC_PROD_ENV
-#define BNC_API_BASE_URL @"https://api.branch.io"
-#endif
-
-#ifdef BNC_STAGE_ENV
-#define BNC_API_BASE_URL @"http://api.dev.branch.io"
-#endif
-
-#define BNC_LINK_URL @"https://bnc.lt"
-
-#ifdef BNC_DEV_ENV
-#define BNC_API_BASE_URL @"http://localhost:3001"
-#endif
-
-#define BNC_API_VERSION @"v1"
-
-#endif
+extern NSString * const SDK_VERSION;
+extern NSString * const BNC_API_BASE_URL;
+extern NSString * const BNC_LINK_URL;
+extern NSString * const BNC_API_VERSION;
diff --git a/src/ios/dependencies/Branch.framework/Versions/A/Headers/BNCServerRequestQueue.h b/src/ios/dependencies/Branch.framework/Versions/A/Headers/BNCServerRequestQueue.h
index 44eab536..fd0286d1 100755
--- a/src/ios/dependencies/Branch.framework/Versions/A/Headers/BNCServerRequestQueue.h
+++ b/src/ios/dependencies/Branch.framework/Versions/A/Headers/BNCServerRequestQueue.h
@@ -26,6 +26,7 @@
- (void)clearQueue;
- (BOOL)containsInstallOrOpen;
+- (BOOL)removeInstallOrOpen;
- (BOOL)containsClose;
- (BranchOpenRequest *)moveInstallOrOpenToFront:(NSInteger)networkCount;
diff --git a/testbed/www/js.es6/index.js b/testbed/www/js.es6/index.js
index 5558851c..ea801228 100644
--- a/testbed/www/js.es6/index.js
+++ b/testbed/www/js.es6/index.js
@@ -180,6 +180,8 @@ function BranchDeepLink() {
$android_url: "http://www.example.com/android",
$ios_url: "http://www.example.com/ios",
$ipad_url: "http://www.example.com/ipad",
+ $deeplink_path: "content/123",
+ $match_duration: 2000,
more_custom: "data",
even_more_custom: true,
this_is_custom: 41231,
diff --git a/testbed/www/js/index.js b/testbed/www/js/index.js
index 0a7d663f..8d6c5f8b 100644
--- a/testbed/www/js/index.js
+++ b/testbed/www/js/index.js
@@ -182,6 +182,8 @@ function BranchDeepLink() {
$android_url: "http://www.example.com/android",
$ios_url: "http://www.example.com/ios",
$ipad_url: "http://www.example.com/ipad",
+ $deeplink_path: "content/123",
+ $match_duration: 2000,
more_custom: "data",
even_more_custom: true,
this_is_custom: 41231,