diff --git a/.gitmodules b/.gitmodules index fc0b2bb..458f64f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,6 @@ [submodule "ADNLogin-SDK-iOS"] path = Dependencies/ADNLogin-SDK url = https://github.com/appdotnet/ADNLogin-SDK-iOS.git +[submodule "Dependencies/Branch-iOS-SDK"] + path = Dependencies/Branch-iOS-SDK + url = https://github.com/BranchMetrics/Branch-iOS-SDK diff --git a/Dependencies/ADNLogin-SDK b/Dependencies/ADNLogin-SDK index 3c1e043..b2a2c55 160000 --- a/Dependencies/ADNLogin-SDK +++ b/Dependencies/ADNLogin-SDK @@ -1 +1 @@ -Subproject commit 3c1e043b08542e83b3e4f01816650ae4b18c3ddd +Subproject commit b2a2c5574d0ee24a13515c730c5f87b0a0df840f diff --git a/Dependencies/Branch-iOS-SDK b/Dependencies/Branch-iOS-SDK new file mode 160000 index 0000000..2b808c3 --- /dev/null +++ b/Dependencies/Branch-iOS-SDK @@ -0,0 +1 @@ +Subproject commit 2b808c34dfa037e20a8b848a0b5bb0f898a60764 diff --git a/Dependencies/Pocket-SDK b/Dependencies/Pocket-SDK index d421134..c161bd8 160000 --- a/Dependencies/Pocket-SDK +++ b/Dependencies/Pocket-SDK @@ -1 +1 @@ -Subproject commit d421134c1b1009148c1e9c9aa35bb42fbfe27e0a +Subproject commit c161bd80711239f8a5a0b5bfeef355204cb8a0e8 diff --git a/Overshare Kit/OSKPresentationManager.m b/Overshare Kit/OSKPresentationManager.m index 0858832..2acad5e 100644 --- a/Overshare Kit/OSKPresentationManager.m +++ b/Overshare Kit/OSKPresentationManager.m @@ -37,6 +37,9 @@ #import "UIViewController+OSKUtilities.h" #import "UIColor+OSKUtility.h" +// --- Branch --- +#import "Branch.h" + NSString * const OSKPresentationOption_ActivityCompletionHandler = @"OSKPresentationOption_ActivityCompletionHandler"; NSString * const OSKPresentationOption_PresentationEndingHandler = @"OSKPresentationOption_PresentationEndingHandler"; @@ -374,6 +377,11 @@ - (void)tearDownShadowView { - (void)activitySheet:(OSKActivitySheetViewController *)viewController didSelectActivity:(OSKActivity *)activity { + // --- Branch --- + // Registers that user clicked the share button in the app + Branch *branch = [Branch getInstance]; + [branch userCompletedAction:@"click_share"]; + [self _proceedWithSession:viewController.session selectedActivity:activity presentingViewController:self.presentingViewController @@ -1159,6 +1167,17 @@ - (void)sessionControllerDidBeginPerformingActivity:(OSKSessionController *)cont - (void)sessionControllerDidFinish:(OSKSessionController *)controller successful:(BOOL)successful error:(NSError *)error { + + // --- Branch --- + // Registers if the user was successful or not in sharing + Branch *branch = [Branch getInstance]; + if (successful) { + [branch userCompletedAction:@"successful_share"]; + } else { + [branch userCompletedAction:@"failed_share"]; + } + + OSKSession *session = controller.session; OSKActivity *selectedActivity = controller.activity; @@ -1193,6 +1212,11 @@ - (void)sessionControllerDidCancel:(OSKSessionController *)controller { no need to dismiss it. */ + // --- Branch --- + // Registers that user cancelled the share + Branch *branch = [Branch getInstance]; + [branch userCompletedAction:@"cancelled_share"]; + if ([self isPresenting] == NO) { // Don't perform the presentation ending block unless the activity sheet // has already been dismissed. E.g., on iPad, the session controller diff --git a/Overshare Kit/OSKShareableContent.h b/Overshare Kit/OSKShareableContent.h index 916d1c7..1be6bb8 100644 --- a/Overshare Kit/OSKShareableContent.h +++ b/Overshare Kit/OSKShareableContent.h @@ -137,6 +137,26 @@ These can be custom items, or additional instances of the official items above. */ @property (copy, nonatomic) NSString *title; + +// ========== Branch ========== + +@property (strong, nonatomic) NSMutableArray *channelsToProcessToBranch; + +@property (strong, nonatomic) NSMutableArray *channelsWithStringsToProcessToBranch; + +@property (strong, nonatomic) NSString *urlToProcessToBranch; + +@property (strong, nonatomic) NSArray *branchTags; + +@property (strong, nonatomic) NSString *branchFeature; + +@property (strong, nonatomic) NSString *branchStage; + +@property (strong, nonatomic) NSDictionary *branchParams; + +@property (strong, nonatomic) NSDictionary *branchOGTags; + +// ========== End Branch ========== @end /// ----------------------------------------- @@ -155,6 +175,90 @@ These can be custom items, or additional instances of the official items above. */ + (instancetype)contentFromURL:(NSURL *)url; +// ========== Branch ========== +/** + Branch extensions to convenient constructors for links + */ + +// All Branch Arguments: Tracking, Deep link params, Stage, and Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchParams + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature; + +// Tracking tags ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags; + +// Tracking Tags, Deep link params ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchPrams; + +// Deep link params ++ (instancetype)contentFromURL:(NSURL *)url + branchParams:(NSDictionary *)branchPrams; + +// Tracking Tags, Deep link params, Stage ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchPrams + branchStage:(NSString *)branchStage; + +// Deep link params, Stage ++ (instancetype)contentFromURL:(NSURL *)url + branchParams:(NSDictionary *)branchPrams + branchStage:(NSString *)branchStage; + +// Tracking Tags, Stage ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags + branchStage:(NSString *)branchStage; + +// Stage ++ (instancetype)contentFromURL:(NSURL *)url + branchStage:(NSString *)branchStage; + +// Tracking tags, Deep link params, and Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchParams + branchFeature:(NSString *)branchFeature; + +// Tracking tags, Stage, and Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature; + +// Deep link params, Stage and Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchParams:(NSDictionary *)branchParams + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature; + +// Deep link params and Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchParams:(NSDictionary *)branchParams + branchFeature:(NSString *)branchFeature; + +// Stage and Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature; + +// Tracking tags and Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags + branchFeature:(NSString *)branchFeature; + +// Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchFeature:(NSString *)branchFeature; + +// ========== End Branch ========== + /** Convenient constructor for content drawn from microblog posts (like Twitter or App.net). */ @@ -163,12 +267,150 @@ These can be custom items, or additional instances of the official items above. canonicalURL:(NSString *)canonicalURL images:(NSArray *)images; +// ========== Branch ========== +/** + Branch extensions to convenient constructors for microblog posts + */ + +// All Branch Arguments: Tracking, Deep link params, Stage, and Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchParams + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature; + +// Tracking tags ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags; + +// Tracking Tags, Deep link params ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchPrams; + +// Deep link params ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchParams:(NSDictionary *)branchPrams; + +// Tracking Tags, Deep link params, Stage ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchPrams + branchStage:(NSString *)branchStage; + +// Deep link params, Stage ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchParams:(NSDictionary *)branchPrams + branchStage:(NSString *)branchStage; + +// Tracking Tags, Stage ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags + branchStage:(NSString *)branchStage; + +// Stage ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchStage:(NSString *)branchStage; + +// Tracking tags, Deep link params, and Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchParams + branchFeature:(NSString *)branchFeature; + +// Tracking tags, Stage, and Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature; + +// Deep link params, Stage and Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchParams:(NSDictionary *)branchParams + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature; + +// Deep link params and Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchParams:(NSDictionary *)branchParams + branchFeature:(NSString *)branchFeature; + +// Stage and Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature; + +// Tracking tags and Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags + branchFeature:(NSString *)branchFeature; + +// Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchFeature:(NSString *)branchFeature; + +// ========== End Branch ========== + /** Convenient constructor for sharing one or more images with a common caption. */ + (instancetype)contentFromImages:(NSArray *)images caption:(NSString *)caption; +// ========== Branch ========== + +/** + Processes URLs in all Content Items and replaces with Branch URLs + */ +- (void)processURLsForBranch; + +// ========== Branch ========== + @end diff --git a/Overshare Kit/OSKShareableContent.m b/Overshare Kit/OSKShareableContent.m index 84a954f..b97a8ee 100644 --- a/Overshare Kit/OSKShareableContent.m +++ b/Overshare Kit/OSKShareableContent.m @@ -10,6 +10,11 @@ #import "OSKShareableContentItem.h" + +// Include Branch, and Branch preference helper +#import "Branch.h" +#import "BNCPreferenceHelper.h" + @implementation OSKShareableContent + (instancetype)contentFromText:(NSString *)text { @@ -54,10 +59,21 @@ + (instancetype)contentFromText:(NSString *)text { return content; } -+ (instancetype)contentFromURL:(NSURL *)url { ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchParams + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature { NSParameterAssert(url.absoluteString.length); OSKShareableContent *content = [[OSKShareableContent alloc] init]; + + // Branch arguments + content.branchTags = branchTrackingTags; + content.branchStage = branchStage; + content.branchFeature = branchFeature; + content.branchParams = branchParams; + NSString *absoluteString = url.absoluteString; content.title = absoluteString; @@ -117,14 +133,222 @@ + (instancetype)contentFromURL:(NSURL *)url { textEditing.text = url.absoluteString; content.textEditingItem = textEditing; + // ========== Branch ========== + // Check to see if a URL is present, and that the Branch API key is present. If so, process all the Content Items for a Branch short URL + if (url && ![[BNCPreferenceHelper getAppKey] isEqualToString:@"bnc_no_value"]) { + + // Branch arguments + content.branchTags = branchTrackingTags; + content.branchStage = branchStage; + content.branchFeature = branchFeature; + content.branchParams = branchParams; + + [content initiateBranchWithURL:url]; + } + // --- End Branch + return content; } -+ (instancetype)contentFromMicroblogPost:(NSString *)text authorName:(NSString *)authorName canonicalURL:(NSString *)canonicalURL images:(NSArray *)images { +// ========== Branch ========== + +/** + Original class method without Branch arguments + */ ++ (instancetype)contentFromURL:(NSURL *)url { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:nil + branchParams:nil + branchStage:nil + branchFeature:nil]; +}; + +// Tracking tags ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:branchTrackingTags + branchParams:nil + branchStage:nil + branchFeature:nil]; +}; + +// Tracking Tags, Deep link params ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchPrams { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:branchTrackingTags + branchParams:branchPrams + branchStage:nil + branchFeature:nil]; +}; + +// Deep link params ++ (instancetype)contentFromURL:(NSURL *)url + branchParams:(NSDictionary *)branchPrams { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:nil + branchParams:branchPrams + branchStage:nil + branchFeature:nil]; +}; + +// Tracking Tags, Deep link params, Stage ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchPrams + branchStage:(NSString *)branchStage { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:branchTrackingTags + branchParams:branchPrams + branchStage:branchStage + branchFeature:nil]; +}; + +// Deep link params, Stage ++ (instancetype)contentFromURL:(NSURL *)url + branchParams:(NSDictionary *)branchPrams + branchStage:(NSString *)branchStage { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:nil + branchParams:branchPrams + branchStage:branchStage + branchFeature:nil]; +}; + +// Tracking Tags, Stage ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags + branchStage:(NSString *)branchStage { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:branchTrackingTags + branchParams:nil + branchStage:branchStage + branchFeature:nil]; +}; + +// Stage ++ (instancetype)contentFromURL:(NSURL *)url + branchStage:(NSString *)branchStage { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:nil + branchParams:nil + branchStage:branchStage + branchFeature:nil]; +}; + +// Tracking tags, Deep link params, and Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchParams + branchFeature:(NSString *)branchFeature { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:branchTrackingTags + branchParams:branchParams + branchStage:nil + branchFeature:branchFeature]; +}; + +// Tracking tags, Stage, and Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:branchTrackingTags + branchParams:nil + branchStage:branchStage + branchFeature:branchFeature]; +}; + +// Deep link params, Stage and Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchParams:(NSDictionary *)branchParams + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:nil + branchParams:branchParams + branchStage:branchStage + branchFeature:branchFeature]; +}; + +// Deep link params and Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchParams:(NSDictionary *)branchParams + branchFeature:(NSString *)branchFeature { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:nil + branchParams:branchParams + branchStage:nil + branchFeature:branchFeature]; +}; + +// Stage and Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:nil + branchParams:nil + branchStage:branchStage + branchFeature:branchFeature]; +}; + +// Tracking tags and Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchTrackingTags:(NSArray *)branchTrackingTags + branchFeature:(NSString *)branchFeature { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:branchTrackingTags + branchParams:nil + branchStage:nil + branchFeature:branchFeature]; +}; + +// Feature ++ (instancetype)contentFromURL:(NSURL *)url + branchFeature:(NSString *)branchFeature { + + return [OSKShareableContent contentFromURL:url + branchTrackingTags:nil + branchParams:nil + branchStage:nil + branchFeature:branchFeature]; +}; + +// ========== End Branch ========== + ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchParams + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature { + OSKShareableContent *content = [[OSKShareableContent alloc] init]; content.title = [NSString stringWithFormat:@"Post by %@: “%@”", authorName, text]; + NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; + NSURL *URLforCanonicalURL = nil; if (canonicalURL) { URLforCanonicalURL = [NSURL URLWithString:canonicalURL]; @@ -166,7 +390,7 @@ + (instancetype)contentFromMicroblogPost:(NSString *)text authorName:(NSString * OSKEmailContentItem *emailItem = [[OSKEmailContentItem alloc] init]; emailItem.body = [NSString stringWithFormat:@"“%@”\n\n(Via @%@)\n\n%@ ", text, authorName, canonicalURL]; - emailItem.subject = @"Clipper Ships Sail On the Ocean"; + emailItem.subject = [NSString stringWithFormat:@"Link from %@", appName]; emailItem.attachments = images.copy; content.emailItem = emailItem; @@ -185,7 +409,6 @@ + (instancetype)contentFromMicroblogPost:(NSString *)text authorName:(NSString * OSKLinkBookmarkContentItem *linkBookmarking = [[OSKLinkBookmarkContentItem alloc] init]; linkBookmarking.url = URLforCanonicalURL; linkBookmarking.notes = [NSString stringWithFormat:@"%@\n\n%@", text, canonicalURL]; - NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; linkBookmarking.tags = @[appName]; linkBookmarking.markToRead = YES; content.linkBookmarkItem = linkBookmarking; @@ -224,9 +447,196 @@ + (instancetype)contentFromMicroblogPost:(NSString *)text authorName:(NSString * textEditing.text = emailItem.body; content.textEditingItem = textEditing; + // ========== Branch ========== + // Check to see if a URL is present, and that the Branch API key is present. If so, process all the Content Items for a Branch short URL + if (URLforCanonicalURL && ![[BNCPreferenceHelper getAppKey] isEqualToString:@"bnc_no_value"]) { + + // Branch arguments + content.branchTags = branchTrackingTags; + content.branchStage = branchStage; + content.branchFeature = branchFeature; + content.branchParams = branchParams; + + [content initiateBranchWithURL:URLforCanonicalURL]; + } + // --- End Branch + return content; } +// ========== Branch ========== + +/** + Original class method without Branch arguments + */ ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:nil branchParams:nil branchStage:nil branchFeature:nil]; +} + +/** + Branch extensions to convenient constructors for Microblog posts + */ + +// Tracking tags ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:branchTrackingTags branchParams:nil branchStage:nil branchFeature:nil]; +} + +// Tracking tags, Deep link params ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchPrams { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:branchTrackingTags branchParams:branchPrams branchStage:nil branchFeature:nil]; +} + +// Deep link params ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchParams:(NSDictionary *)branchPrams { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:nil branchParams:branchPrams branchStage:nil branchFeature:nil]; +} + +// Tracking Tags, Deep link params, Stage ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchPrams + branchStage:(NSString *)branchStage { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:branchTrackingTags branchParams:branchPrams branchStage:branchStage branchFeature:nil]; +} + +// Deep link params, Stage ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchParams:(NSDictionary *)branchPrams + branchStage:(NSString *)branchStage { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:nil branchParams:branchPrams branchStage:branchStage branchFeature:nil]; +}; + +// Tracking Tags, Stage ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags + branchStage:(NSString *)branchStage { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:branchTrackingTags branchParams:nil branchStage:branchStage branchFeature:nil]; +}; + +// Tracking tags, Deep link params, and Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags + branchParams:(NSDictionary *)branchParams + branchFeature:(NSString *)branchFeature { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:branchTrackingTags branchParams:branchParams branchStage:nil branchFeature:branchFeature]; +}; + +// Tracking tags, Stage, and Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:branchTrackingTags branchParams:nil branchStage:branchStage branchFeature:branchFeature]; +}; + +// Deep link params, Stage and Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchParams:(NSDictionary *)branchParams + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:nil branchParams:branchParams branchStage:branchStage branchFeature:branchFeature]; +}; + +// Deep link params and Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchParams:(NSDictionary *)branchParams + branchFeature:(NSString *)branchFeature { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:nil branchParams:branchParams branchStage:nil branchFeature:branchFeature]; +}; + +// Stage and Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchStage:(NSString *)branchStage + branchFeature:(NSString *)branchFeature { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:nil branchParams:nil branchStage:branchStage branchFeature:branchFeature]; +}; + +// Tracking tags and Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchTrackingTags:(NSArray *)branchTrackingTags + branchFeature:(NSString *)branchFeature { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:branchTrackingTags branchParams:nil branchStage:nil branchFeature:branchFeature]; +}; + +// Feature ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchFeature:(NSString *)branchFeature { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:nil branchParams:nil branchStage:nil branchFeature:branchFeature]; +}; + +// Stage ++ (instancetype)contentFromMicroblogPost:(NSString *)text + authorName:(NSString *)authorName + canonicalURL:(NSString *)canonicalURL + images:(NSArray *)images + branchStage:(NSString *)branchStage { + + return [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL images:images branchTrackingTags:nil branchParams:nil branchStage:branchStage branchFeature:nil]; +}; + +//========== End Branch ========== + + (instancetype)contentFromImages:(NSArray *)images caption:(NSString *)caption { OSKShareableContent *content = [[OSKShareableContent alloc] init]; @@ -319,6 +729,138 @@ + (instancetype)contentFromImages:(NSArray *)images caption:(NSString *)caption return content; } +// ========== Branch ========== +// Private calls + +// Initates all of the share channels to generate a Branch URL for +- (void)initiateBranchWithURL:(NSURL *)url { + // Arrays of all channels + // Channels that have a url or link attribute + self.channelsToProcessToBranch = [@[ + @"facebook", + @"browser", + @"read_later", + @"bookmark", + @"microblog_twitter", + @"email", + @"sms", + @"todo", + @"text_editor", + @"airdrop" + ] mutableCopy]; + + // URL to process for each channel + self.urlToProcessToBranch = [url absoluteString]; + + // begin processing URLs for Branch + [self processURLsForBranch]; +} + +// Gets a Branch short URL for each channel +// The Branch SDK cannot generate more then one URL simultaniously, otherwise the callback block will be over written +// To work around this, each channel is stored as an NSString in an NSMutableArray. Once the callback from the first URL is fired, the processed channel is removed from the NSMutable Array. If another NSString is present in the NSMutableArray, processURLsForBranch is called on the OSKShareableContent instance again which processes the next channel in the array +- (void)processURLsForBranch { + + // Sinleton Branch instance + Branch *branch = [Branch getInstance]; + + // Weak block reference to self + // This is so we can reference the self instance from inside the callback block + __weak OSKShareableContent *weakContent = self; + + //The next channel we're going to process for getShortUrl + NSString *channel = [self.channelsToProcessToBranch firstObject]; + + // Content items that take a single URL as an argument + // Create Branch Short URL for each channel + [branch getShortURLWithParams:self.branchParams + andTags:self.branchTags + andChannel:channel + andFeature:self.branchFeature + andStage:self.branchStage + andCallback:^(NSString *url, NSError *error) { + __strong OSKShareableContent *strongContent = weakContent; + + if(!error) { + + // Grab the channel we need to process again + NSString *channel = [strongContent.channelsToProcessToBranch firstObject]; + + // Each channel type stores the URL in a different property. So we'll make sure we update the correct property here. Once the property is updated with the new URL, the user will be sent to the new Branch URL rather than the original URL + if([channel isEqualToString:@"facebook"]) { + strongContent.facebookItem.link = [NSURL URLWithString:url]; + //NSLog(@"Facebook: %@", strongContent.facebookItem.link); + } else if ([channel isEqualToString:@"browser"]) { + strongContent.webBrowserItem.url = [NSURL URLWithString:url]; + //NSLog(@"Browser: %@", strongContent.webBrowserItem.url); + } else if ([channel isEqualToString:@"read_later"]) { + strongContent.readLaterItem.url = [NSURL URLWithString:url]; + //NSLog(@"Read Later: %@", strongContent.readLaterItem.url); + } else if ([channel isEqualToString:@"bookmark"]) { + strongContent.linkBookmarkItem.url = [NSURL URLWithString:url]; + //NSLog(@"Bookmark: %@", strongContent.linkBookmarkItem.url); + } else if ([channel isEqualToString:@"microblog_twitter"]) { + strongContent.microblogPostItem.text = [self branchifiedStringWithURL:url andOriginalString:strongContent.microblogPostItem.text]; + //NSLog(@"Twitter / Microblog: %@", strongContent.microblogPostItem.text); + } else if ([channel isEqualToString:@"email"]) { + strongContent.emailItem.body = [self branchifiedStringWithURL:url andOriginalString:strongContent.emailItem.body]; + //NSLog(@"Email: %@", strongContent.emailItem.body); + } else if ([channel isEqualToString:@"sms"]) { + strongContent.smsItem.body = [self branchifiedStringWithURL:url andOriginalString:strongContent.smsItem.body]; + //NSLog(@"SMS: %@", strongContent.smsItem.body); + } else if ([channel isEqualToString:@"todo"]) { + strongContent.toDoListItem.notes = [ self branchifiedStringWithURL:url andOriginalString:strongContent.toDoListItem.notes]; + //NSLog(@"Todo: %@", strongContent.toDoListItem.notes); + } else if ([channel isEqualToString:@"text_editor"]) { + strongContent.textEditingItem.text = [self branchifiedStringWithURL:url andOriginalString:strongContent.textEditingItem.text]; + //NSLog(@"Text editor: %@", strongContent.textEditingItem.text); + } else if ([channel isEqualToString:@"airdrop"]) { + NSMutableArray *airdropItems = [strongContent.airDropItem.items mutableCopy]; + for (int i = 0; i < [airdropItems count]; i++) { + if ([airdropItems[i] isKindOfClass:[NSString class]]) { + airdropItems[i] = + [self branchifiedStringWithURL:url + andOriginalString:airdropItems[i]]; + //NSLog(@"AirDrop: %@", airdropItems[i]); + } + } + strongContent.airDropItem.items = airdropItems; + } + } + + // Next channel + [strongContent.channelsToProcessToBranch removeObjectAtIndex:0]; + if (strongContent.channelsToProcessToBranch.count > 0) { + //NSLog(@"\n--------------------------------------\n"); + [strongContent processURLsForBranch]; + } + }]; +} + +// Processes strings of content, and replaces the URL at the end with the Branch URL provided +- (NSString *)branchifiedStringWithURL:(NSString *)branchURL andOriginalString:(NSString *)string { + // Identifies all links in a string + NSTextCheckingResult *urlCheckingResult = [self identifyAllUrlsAndReplaceInString:string]; + + // Remove the original URL from the end of the string + NSString *truncatedString = [string stringByReplacingCharactersInRange:urlCheckingResult.range withString:@""]; + + // Append the original string with the Branch URL and return + return [truncatedString stringByAppendingString:branchURL]; +} + +// Identifies all links in a string +- (NSTextCheckingResult *)identifyAllUrlsAndReplaceInString:(NSString *)string { + // Find all URLs in a string + NSDataDetector *detect = [[NSDataDetector alloc] initWithTypes:NSTextCheckingTypeLink error:nil]; + NSMutableArray *allURLs = [[detect matchesInString:string options:0 range:NSMakeRange(0, [string length])] mutableCopy]; + + //return the URL checking result at the end of the string + return [allURLs lastObject]; +} + +// ========== End Branch ========== + - (instancetype)init { self = [super init]; if (self) { diff --git a/Overshare Kit/OSKShareableContentItem.h b/Overshare Kit/OSKShareableContentItem.h index 5faa038..8d4ea5e 100644 --- a/Overshare Kit/OSKShareableContentItem.h +++ b/Overshare Kit/OSKShareableContentItem.h @@ -63,6 +63,7 @@ extern NSString * const OSKShareableContentItemType_TextEditing; @warning Required. Subclasses must override without calling super. */ + - (NSString *)itemType; /** diff --git a/OvershareKit.podspec b/OvershareKit+Branch.podspec similarity index 60% rename from OvershareKit.podspec rename to OvershareKit+Branch.podspec index 066acd3..17de22b 100644 --- a/OvershareKit.podspec +++ b/OvershareKit+Branch.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| - s.name = "OvershareKit" - s.version = "1.3.1" - s.summary = "A soup-to-nuts sharing library for iOS." - s.homepage = "https://github.com/overshare/overshare-kit" + s.name = "OvershareKit+Branch" + s.version = "1.3.2" + s.summary = "A soup-to-nuts sharing library for iOS, with a little extra zest from Branch." + s.homepage = "https://github.com/BranchMetrics/overshare-kit" s.license = { :type => 'MIT', :file => 'LICENSE' } - s.author = { "Jared Sinclair" => "desk@jaredsinclair.com", "Justin Williams" => "justin@carpeaqua.com" } - s.source = { :git => "https://github.com/overshare/overshare-kit.git", :tag => s.version.to_s } + s.author = { "Scott Hasbrouck" => "scott@branch.io" } + s.source = { :git => "https://github.com/BranchMetrics/overshare-kit.git", :tag => s.version.to_s } s.platform = :ios, '7.0' s.requires_arc = true s.frameworks = 'UIKit', 'AddressBook', 'CoreMotion', 'CoreLocation', 'MediaPlayer' @@ -21,4 +21,5 @@ Pod::Spec.new do |s| s.dependency 'ADNLogin' s.dependency 'PocketAPI' + s.dependency 'Branch' end diff --git a/Projects/Static Library/OvershareKit/OvershareKit.xcodeproj/project.pbxproj b/Projects/Static Library/OvershareKit/OvershareKit.xcodeproj/project.pbxproj index 13dc241..9785cf0 100644 --- a/Projects/Static Library/OvershareKit/OvershareKit.xcodeproj/project.pbxproj +++ b/Projects/Static Library/OvershareKit/OvershareKit.xcodeproj/project.pbxproj @@ -120,6 +120,16 @@ 8895C34C18A3BA6B000B7F28 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8895C34B18A3BA6B000B7F28 /* MediaPlayer.framework */; }; 8895C34E18A3BA70000B7F28 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8895C34D18A3BA70000B7F28 /* Security.framework */; }; 8895C35018A3BA78000B7F28 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8895C34F18A3BA78000B7F28 /* SystemConfiguration.framework */; }; + D24CF7471A6FF57F00540A64 /* BNCError.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF7331A6FF57F00540A64 /* BNCError.m */; }; + D24CF7481A6FF57F00540A64 /* BNCPreferenceHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF7351A6FF57F00540A64 /* BNCPreferenceHelper.m */; }; + D24CF7491A6FF57F00540A64 /* BNCServerInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF7371A6FF57F00540A64 /* BNCServerInterface.m */; }; + D24CF74A1A6FF57F00540A64 /* BNCServerRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF7391A6FF57F00540A64 /* BNCServerRequest.m */; }; + D24CF74B1A6FF57F00540A64 /* BNCServerRequestQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF73B1A6FF57F00540A64 /* BNCServerRequestQueue.m */; }; + D24CF74C1A6FF57F00540A64 /* BNCServerResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF73D1A6FF57F00540A64 /* BNCServerResponse.m */; }; + D24CF74D1A6FF57F00540A64 /* BNCSystemObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF73F1A6FF57F00540A64 /* BNCSystemObserver.m */; }; + D24CF74E1A6FF57F00540A64 /* Branch.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF7421A6FF57F00540A64 /* Branch.m */; }; + D24CF74F1A6FF57F00540A64 /* BranchServerInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF7441A6FF57F00540A64 /* BranchServerInterface.m */; }; + D24CF7501A6FF57F00540A64 /* UIViewController+BNCDebugging.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF7461A6FF57F00540A64 /* UIViewController+BNCDebugging.m */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -496,6 +506,28 @@ 8895C34B18A3BA6B000B7F28 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; }; 8895C34D18A3BA70000B7F28 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 8895C34F18A3BA78000B7F28 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + D24CF7311A6FF57F00540A64 /* BNCConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCConfig.h; sourceTree = ""; }; + D24CF7321A6FF57F00540A64 /* BNCError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCError.h; sourceTree = ""; }; + D24CF7331A6FF57F00540A64 /* BNCError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCError.m; sourceTree = ""; }; + D24CF7341A6FF57F00540A64 /* BNCPreferenceHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCPreferenceHelper.h; sourceTree = ""; }; + D24CF7351A6FF57F00540A64 /* BNCPreferenceHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCPreferenceHelper.m; sourceTree = ""; }; + D24CF7361A6FF57F00540A64 /* BNCServerInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCServerInterface.h; sourceTree = ""; }; + D24CF7371A6FF57F00540A64 /* BNCServerInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCServerInterface.m; sourceTree = ""; }; + D24CF7381A6FF57F00540A64 /* BNCServerRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCServerRequest.h; sourceTree = ""; }; + D24CF7391A6FF57F00540A64 /* BNCServerRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCServerRequest.m; sourceTree = ""; }; + D24CF73A1A6FF57F00540A64 /* BNCServerRequestQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCServerRequestQueue.h; sourceTree = ""; }; + D24CF73B1A6FF57F00540A64 /* BNCServerRequestQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCServerRequestQueue.m; sourceTree = ""; }; + D24CF73C1A6FF57F00540A64 /* BNCServerResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCServerResponse.h; sourceTree = ""; }; + D24CF73D1A6FF57F00540A64 /* BNCServerResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCServerResponse.m; sourceTree = ""; }; + D24CF73E1A6FF57F00540A64 /* BNCSystemObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCSystemObserver.h; sourceTree = ""; }; + D24CF73F1A6FF57F00540A64 /* BNCSystemObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCSystemObserver.m; sourceTree = ""; }; + D24CF7401A6FF57F00540A64 /* Branch-SDK-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Branch-SDK-Prefix.pch"; sourceTree = ""; }; + D24CF7411A6FF57F00540A64 /* Branch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Branch.h; sourceTree = ""; }; + D24CF7421A6FF57F00540A64 /* Branch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Branch.m; sourceTree = ""; }; + D24CF7431A6FF57F00540A64 /* BranchServerInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchServerInterface.h; sourceTree = ""; }; + D24CF7441A6FF57F00540A64 /* BranchServerInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchServerInterface.m; sourceTree = ""; }; + D24CF7451A6FF57F00540A64 /* UIViewController+BNCDebugging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+BNCDebugging.h"; sourceTree = ""; }; + D24CF7461A6FF57F00540A64 /* UIViewController+BNCDebugging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+BNCDebugging.m"; sourceTree = ""; }; F2ED4093BD3864F639BD9AB1 /* GooglePlus-Icon-76.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "GooglePlus-Icon-76.png"; sourceTree = ""; }; F2ED4477173538D750DC8F83 /* GooglePlus-Icon-29.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "GooglePlus-Icon-29.png"; sourceTree = ""; }; F2ED44D42685E0B33F979699 /* GooglePlus-Icon-29@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "GooglePlus-Icon-29@2x.png"; sourceTree = ""; }; @@ -529,6 +561,7 @@ 7F6711F8181EDF870006E037 /* Third-Party Dependencies */ = { isa = PBXGroup; children = ( + D24CF7301A6FF57F00540A64 /* Branch-SDK */, 7F6711F9181EDF900006E037 /* ADNLogin */, 7F6711FA181EDF960006E037 /* Pocket */, ); @@ -964,6 +997,36 @@ path = Images; sourceTree = ""; }; + D24CF7301A6FF57F00540A64 /* Branch-SDK */ = { + isa = PBXGroup; + children = ( + D24CF7311A6FF57F00540A64 /* BNCConfig.h */, + D24CF7321A6FF57F00540A64 /* BNCError.h */, + D24CF7331A6FF57F00540A64 /* BNCError.m */, + D24CF7341A6FF57F00540A64 /* BNCPreferenceHelper.h */, + D24CF7351A6FF57F00540A64 /* BNCPreferenceHelper.m */, + D24CF7361A6FF57F00540A64 /* BNCServerInterface.h */, + D24CF7371A6FF57F00540A64 /* BNCServerInterface.m */, + D24CF7381A6FF57F00540A64 /* BNCServerRequest.h */, + D24CF7391A6FF57F00540A64 /* BNCServerRequest.m */, + D24CF73A1A6FF57F00540A64 /* BNCServerRequestQueue.h */, + D24CF73B1A6FF57F00540A64 /* BNCServerRequestQueue.m */, + D24CF73C1A6FF57F00540A64 /* BNCServerResponse.h */, + D24CF73D1A6FF57F00540A64 /* BNCServerResponse.m */, + D24CF73E1A6FF57F00540A64 /* BNCSystemObserver.h */, + D24CF73F1A6FF57F00540A64 /* BNCSystemObserver.m */, + D24CF7401A6FF57F00540A64 /* Branch-SDK-Prefix.pch */, + D24CF7411A6FF57F00540A64 /* Branch.h */, + D24CF7421A6FF57F00540A64 /* Branch.m */, + D24CF7431A6FF57F00540A64 /* BranchServerInterface.h */, + D24CF7441A6FF57F00540A64 /* BranchServerInterface.m */, + D24CF7451A6FF57F00540A64 /* UIViewController+BNCDebugging.h */, + D24CF7461A6FF57F00540A64 /* UIViewController+BNCDebugging.m */, + ); + name = "Branch-SDK"; + path = "../../../../Branch-iOS-SDK/Branch-SDK/Branch-SDK"; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -999,6 +1062,7 @@ hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 7FEE7661181ED867000F684A; productRefGroup = 7FEE766B181ED867000F684A /* Products */; @@ -1019,6 +1083,7 @@ 7F75BEFE1821539700D3681E /* OSKAccountManagementViewController.m in Sources */, 7FEE78C8181ED8FE000F684A /* OSKAppDotNetActivity.m in Sources */, 7FEE78F6181ED8FE000F684A /* OSKUsernamePasswordViewController.m in Sources */, + D24CF7501A6FF57F00540A64 /* UIViewController+BNCDebugging.m in Sources */, 7FEE78BE181ED8FE000F684A /* OSKActivityCollectionViewCell.m in Sources */, 7FEE78D1181ED8FE000F684A /* OSKFileManager.m in Sources */, 7FEE78F7181ED8FE000F684A /* OSKWebViewController.m in Sources */, @@ -1026,6 +1091,7 @@ 7FEE78E2181ED8FE000F684A /* OSKPagedHorizontalLayout.m in Sources */, 7FEE78C2181ED8FE000F684A /* OSKActivityOperation.m in Sources */, 7FEE78DA181ED8FE000F684A /* OSKManagedAccount.m in Sources */, + D24CF74A1A6FF57F00540A64 /* BNCServerRequest.m in Sources */, 7FA91AF71889F61D00A5DF9B /* OSKReadingListActivity.m in Sources */, 7FEE78E6181ED8FE000F684A /* OSKPresentationManager.m in Sources */, 7F55A30E18425C6C004A3BCC /* OSKSessionController_Phone.m in Sources */, @@ -1045,6 +1111,7 @@ 7FEE78D9181ED8FE000F684A /* OSKMailComposeViewController.m in Sources */, 7F55A30C18425C6C004A3BCC /* OSKSession.m in Sources */, 7FEE78F9181ED8FE000F684A /* UIDevice+OSKHardware.m in Sources */, + D24CF74C1A6FF57F00540A64 /* BNCServerResponse.m in Sources */, 7FEE78EE181ED8FE000F684A /* OSKSystemAccountStore.m in Sources */, 7FEE78C9181ED8FE000F684A /* OSKAppDotNetAuthenticationViewController.m in Sources */, 7FEE78C3181ED8FE000F684A /* OSKActivitySheetViewController.m in Sources */, @@ -1057,10 +1124,12 @@ 7FEE78DB181ED8FE000F684A /* OSKManagedAccountCredential.m in Sources */, 7FEE78F2181ED8FE000F684A /* OSKTwitterText.m in Sources */, 7FEE78BB181ED8FE000F684A /* OSKActionSheet.m in Sources */, + D24CF7491A6FF57F00540A64 /* BNCServerInterface.m in Sources */, 7FEE78F4181ED8FE000F684A /* OSKTwitterUtility.m in Sources */, 32C2B9B7190337BC0055C98B /* OSKMimeAttachment.m in Sources */, 7FEE78B3181ED8FE000F684A /* NSHTTPURLResponse+OSKUtilities.m in Sources */, 7FEE78F3181ED8FE000F684A /* OSKTwitterTextEntity.m in Sources */, + D24CF74B1A6FF57F00540A64 /* BNCServerRequestQueue.m in Sources */, 7FEE78B2181ED8FE000F684A /* NSDictionary+OSKModel.m in Sources */, 7FEE78F5181ED8FE000F684A /* OSKUsernamePasswordCell.m in Sources */, 7FEE78BA181ED8FE000F684A /* OSKAccountChooserViewController.m in Sources */, @@ -1079,13 +1148,17 @@ 7FEE78C6181ED8FE000F684A /* OSKAirDropViewController.m in Sources */, 7F55A30D18425C6C004A3BCC /* OSKSessionController_Pad.m in Sources */, 7F75BF001821539700D3681E /* OSKPocketAccountViewController.m in Sources */, + D24CF7471A6FF57F00540A64 /* BNCError.m in Sources */, 7FEE78B5181ED8FE000F684A /* NSString+OSK_UUID.m in Sources */, + D24CF74F1A6FF57F00540A64 /* BranchServerInterface.m in Sources */, + D24CF74D1A6FF57F00540A64 /* BNCSystemObserver.m in Sources */, 7FEE78B9181ED8FE000F684A /* OSK1PasswordSearchActivity.m in Sources */, 7F1DA9E0183C6B050082356D /* OSKLinkShorteningUtility.m in Sources */, 7FEE7675181ED867000F684A /* OvershareKit.m in Sources */, 7FEE78DE181ED8FE000F684A /* OSKMicroblogPublishingViewController.m in Sources */, 7FEE78C5181ED8FE000F684A /* OSKAirDropActivity.m in Sources */, 7FEE78DC181ED8FE000F684A /* OSKManagedAccountStore.m in Sources */, + D24CF7481A6FF57F00540A64 /* BNCPreferenceHelper.m in Sources */, 7FEE78CA181ED8FE000F684A /* OSKAppDotNetUtility.m in Sources */, 7FEE78D7181ED8FE000F684A /* OSKInstapaperUtility.m in Sources */, 7FEE78CE181ED8FE000F684A /* OSKCopyToPasteboardActivity.m in Sources */, @@ -1107,6 +1180,7 @@ 7FE4109F1821994B00B13AB1 /* OSKFacebookPublishingViewController.m in Sources */, 7FEE78B4181ED8FE000F684A /* NSMutableURLRequest+OSKUtilities.m in Sources */, 7FEE78EC181ED8FE000F684A /* OSKShareableContentItem.m in Sources */, + D24CF74E1A6FF57F00540A64 /* Branch.m in Sources */, 7FEE78E5181ED8FE000F684A /* OSKPocketActivity.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1188,6 +1262,10 @@ isa = XCBuildConfiguration; buildSettings = { DSTROOT = /tmp/OvershareKit.dst; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "/Users/scott/Code/ObjC/overshare-deeplinking-kit/Dependencies/Branch-iOS-SDK", + ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "OvershareKit/OvershareKit-Prefix.pch"; OTHER_LDFLAGS = "-ObjC"; @@ -1200,6 +1278,10 @@ isa = XCBuildConfiguration; buildSettings = { DSTROOT = /tmp/OvershareKit.dst; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "/Users/scott/Code/ObjC/overshare-deeplinking-kit/Dependencies/Branch-iOS-SDK", + ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "OvershareKit/OvershareKit-Prefix.pch"; OTHER_LDFLAGS = "-ObjC"; diff --git a/Projects/iOS App/Overshare/Overshare.xcodeproj/project.pbxproj b/Projects/iOS App/Overshare/Overshare.xcodeproj/project.pbxproj index 9323c95..547ca5b 100644 --- a/Projects/iOS App/Overshare/Overshare.xcodeproj/project.pbxproj +++ b/Projects/iOS App/Overshare/Overshare.xcodeproj/project.pbxproj @@ -258,6 +258,16 @@ 8895C33E18A3BA1B000B7F28 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8895C33D18A3BA1B000B7F28 /* Security.framework */; }; 8895C34018A3BA24000B7F28 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8895C33F18A3BA24000B7F28 /* SystemConfiguration.framework */; }; 8895C35218A3BFA2000B7F28 /* Icon-60@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8895C35118A3BFA2000B7F28 /* Icon-60@2x.png */; }; + D24CF7261A6FF57000540A64 /* BNCError.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF7121A6FF57000540A64 /* BNCError.m */; }; + D24CF7271A6FF57000540A64 /* BNCPreferenceHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF7141A6FF57000540A64 /* BNCPreferenceHelper.m */; }; + D24CF7281A6FF57000540A64 /* BNCServerInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF7161A6FF57000540A64 /* BNCServerInterface.m */; }; + D24CF7291A6FF57000540A64 /* BNCServerRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF7181A6FF57000540A64 /* BNCServerRequest.m */; }; + D24CF72A1A6FF57000540A64 /* BNCServerRequestQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF71A1A6FF57000540A64 /* BNCServerRequestQueue.m */; }; + D24CF72B1A6FF57000540A64 /* BNCServerResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF71C1A6FF57000540A64 /* BNCServerResponse.m */; }; + D24CF72C1A6FF57000540A64 /* BNCSystemObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF71E1A6FF57000540A64 /* BNCSystemObserver.m */; }; + D24CF72D1A6FF57000540A64 /* Branch.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF7211A6FF57000540A64 /* Branch.m */; }; + D24CF72E1A6FF57000540A64 /* BranchServerInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF7231A6FF57000540A64 /* BranchServerInterface.m */; }; + D24CF72F1A6FF57000540A64 /* UIViewController+BNCDebugging.m in Sources */ = {isa = PBXBuildFile; fileRef = D24CF7251A6FF57000540A64 /* UIViewController+BNCDebugging.m */; }; F2ED44FF27CCD7E9F8A34E77 /* GooglePlus-Icon-76.png in Resources */ = {isa = PBXBuildFile; fileRef = F2ED4DB1EC62FB9EF52F15D0 /* GooglePlus-Icon-76.png */; }; F2ED453AABB8833C66910E03 /* GooglePlus-Icon-76@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F2ED46B9E187F11BFEF64BF2 /* GooglePlus-Icon-76@2x.png */; }; F2ED4696B1DB571FBBE9204A /* GooglePlus-Icon-60@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F2ED40569B315A0A210DC081 /* GooglePlus-Icon-60@2x.png */; }; @@ -655,6 +665,28 @@ 8895C33D18A3BA1B000B7F28 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 8895C33F18A3BA24000B7F28 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; 8895C35118A3BFA2000B7F28 /* Icon-60@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-60@2x.png"; path = "Overshare/Icon-60@2x.png"; sourceTree = ""; }; + D24CF7101A6FF57000540A64 /* BNCConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCConfig.h; sourceTree = ""; }; + D24CF7111A6FF57000540A64 /* BNCError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCError.h; sourceTree = ""; }; + D24CF7121A6FF57000540A64 /* BNCError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCError.m; sourceTree = ""; }; + D24CF7131A6FF57000540A64 /* BNCPreferenceHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCPreferenceHelper.h; sourceTree = ""; }; + D24CF7141A6FF57000540A64 /* BNCPreferenceHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCPreferenceHelper.m; sourceTree = ""; }; + D24CF7151A6FF57000540A64 /* BNCServerInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCServerInterface.h; sourceTree = ""; }; + D24CF7161A6FF57000540A64 /* BNCServerInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCServerInterface.m; sourceTree = ""; }; + D24CF7171A6FF57000540A64 /* BNCServerRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCServerRequest.h; sourceTree = ""; }; + D24CF7181A6FF57000540A64 /* BNCServerRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCServerRequest.m; sourceTree = ""; }; + D24CF7191A6FF57000540A64 /* BNCServerRequestQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCServerRequestQueue.h; sourceTree = ""; }; + D24CF71A1A6FF57000540A64 /* BNCServerRequestQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCServerRequestQueue.m; sourceTree = ""; }; + D24CF71B1A6FF57000540A64 /* BNCServerResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCServerResponse.h; sourceTree = ""; }; + D24CF71C1A6FF57000540A64 /* BNCServerResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCServerResponse.m; sourceTree = ""; }; + D24CF71D1A6FF57000540A64 /* BNCSystemObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCSystemObserver.h; sourceTree = ""; }; + D24CF71E1A6FF57000540A64 /* BNCSystemObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCSystemObserver.m; sourceTree = ""; }; + D24CF71F1A6FF57000540A64 /* Branch-SDK-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Branch-SDK-Prefix.pch"; sourceTree = ""; }; + D24CF7201A6FF57000540A64 /* Branch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Branch.h; sourceTree = ""; }; + D24CF7211A6FF57000540A64 /* Branch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Branch.m; sourceTree = ""; }; + D24CF7221A6FF57000540A64 /* BranchServerInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchServerInterface.h; sourceTree = ""; }; + D24CF7231A6FF57000540A64 /* BranchServerInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchServerInterface.m; sourceTree = ""; }; + D24CF7241A6FF57000540A64 /* UIViewController+BNCDebugging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+BNCDebugging.h"; sourceTree = ""; }; + D24CF7251A6FF57000540A64 /* UIViewController+BNCDebugging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+BNCDebugging.m"; sourceTree = ""; }; F2ED40569B315A0A210DC081 /* GooglePlus-Icon-60@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "GooglePlus-Icon-60@2x.png"; sourceTree = ""; }; F2ED41960B167BFC3B93056A /* GooglePlus-Icon-29@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "GooglePlus-Icon-29@2x.png"; sourceTree = ""; }; F2ED429BFCE742838350E97F /* OSKGooglePlusActivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSKGooglePlusActivity.m; sourceTree = ""; }; @@ -1473,6 +1505,7 @@ 7FEE7922181EDC71000F684A /* Third-Party Dependencies */ = { isa = PBXGroup; children = ( + D24CF70F1A6FF57000540A64 /* Branch-SDK */, 7FEE7924181EDC88000F684A /* ADNLogin */, 7FEE7923181EDC84000F684A /* Pocket */, ); @@ -1516,6 +1549,36 @@ name = GooglePlus; sourceTree = ""; }; + D24CF70F1A6FF57000540A64 /* Branch-SDK */ = { + isa = PBXGroup; + children = ( + D24CF7101A6FF57000540A64 /* BNCConfig.h */, + D24CF7111A6FF57000540A64 /* BNCError.h */, + D24CF7121A6FF57000540A64 /* BNCError.m */, + D24CF7131A6FF57000540A64 /* BNCPreferenceHelper.h */, + D24CF7141A6FF57000540A64 /* BNCPreferenceHelper.m */, + D24CF7151A6FF57000540A64 /* BNCServerInterface.h */, + D24CF7161A6FF57000540A64 /* BNCServerInterface.m */, + D24CF7171A6FF57000540A64 /* BNCServerRequest.h */, + D24CF7181A6FF57000540A64 /* BNCServerRequest.m */, + D24CF7191A6FF57000540A64 /* BNCServerRequestQueue.h */, + D24CF71A1A6FF57000540A64 /* BNCServerRequestQueue.m */, + D24CF71B1A6FF57000540A64 /* BNCServerResponse.h */, + D24CF71C1A6FF57000540A64 /* BNCServerResponse.m */, + D24CF71D1A6FF57000540A64 /* BNCSystemObserver.h */, + D24CF71E1A6FF57000540A64 /* BNCSystemObserver.m */, + D24CF71F1A6FF57000540A64 /* Branch-SDK-Prefix.pch */, + D24CF7201A6FF57000540A64 /* Branch.h */, + D24CF7211A6FF57000540A64 /* Branch.m */, + D24CF7221A6FF57000540A64 /* BranchServerInterface.h */, + D24CF7231A6FF57000540A64 /* BranchServerInterface.m */, + D24CF7241A6FF57000540A64 /* UIViewController+BNCDebugging.h */, + D24CF7251A6FF57000540A64 /* UIViewController+BNCDebugging.m */, + ); + name = "Branch-SDK"; + path = "../../../Dependencies/Branch-iOS-SDK/Branch-SDK/Branch-SDK"; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1557,6 +1620,7 @@ hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 7FEE7626181ED83D000F684A; productRefGroup = 7FEE7630181ED83D000F684A /* Products */; @@ -1722,9 +1786,11 @@ 7FEE7790181ED8EF000F684A /* NSMutableURLRequest+OSKUtilities.m in Sources */, 7FEE77C5181ED8EF000F684A /* OSKPocketActivity.m in Sources */, 7FEE77B6181ED8EF000F684A /* OSKInstapaperUtility.m in Sources */, + D24CF7291A6FF57000540A64 /* BNCServerRequest.m in Sources */, 7F55A30118425C46004A3BCC /* OSKSessionController_Phone.m in Sources */, 7FEE7643181ED83D000F684A /* OSKAppDelegate.m in Sources */, 7FEE77AD181ED8EF000F684A /* OSKCopyToPasteboardActivity.m in Sources */, + D24CF7261A6FF57000540A64 /* BNCError.m in Sources */, 7FEE77B4181ED8EF000F684A /* OSKInMemoryImageCache.m in Sources */, 7FEE77A3181ED8EF000F684A /* OSKADNLoginManager.m in Sources */, 7F75BF3D1821588700D3681E /* PocketAPI.m in Sources */, @@ -1760,7 +1826,9 @@ 7FEE7797181ED8EF000F684A /* OSKActionSheet.m in Sources */, 7F78E9AC1820E5630042CF02 /* OSKPocketAccountViewController.m in Sources */, 7FEE77AE181ED8EF000F684A /* OSKEmailActivity.m in Sources */, + D24CF7281A6FF57000540A64 /* BNCServerInterface.m in Sources */, 7F14C95918DB5DBC00E635FE /* OSKTextViewAttachmentView.m in Sources */, + D24CF72D1A6FF57000540A64 /* Branch.m in Sources */, 7F14C95F18DB651800E635FE /* OSKCursorMovement.m in Sources */, 7FEE77B7181ED8EF000F684A /* OSKKeychainUtility.m in Sources */, 7FE467391821F4010054D2BC /* OSKAccountTypeCell.m in Sources */, @@ -1768,6 +1836,7 @@ 7FD649DA1895C7CA0021BD50 /* OSKDraftsActivity.m in Sources */, 7F75BF3E1821588700D3681E /* PocketAPILogin.m in Sources */, 7FEE77C7181ED8EF000F684A /* OSKReadabilityActivity.m in Sources */, + D24CF72B1A6FF57000540A64 /* BNCServerResponse.m in Sources */, 7F55A30218425C46004A3BCC /* OSKSessionController.m in Sources */, 7FEE77C1181ED8EF000F684A /* OSKOmnifocusActivity.m in Sources */, 7FEE7794181ED8EF000F684A /* OSK1PasswordBrowserActivity.m in Sources */, @@ -1808,21 +1877,26 @@ 7FEE77D8181ED8EF000F684A /* UIColor+OSKUtility.m in Sources */, 7FEE77A4181ED8EF000F684A /* OSKAirDropActivity.m in Sources */, 7F75BF3F1821588700D3681E /* PocketAPIOperation.m in Sources */, + D24CF72A1A6FF57000540A64 /* BNCServerRequestQueue.m in Sources */, 7FEE77A7181ED8EF000F684A /* OSKAppDotNetActivity.m in Sources */, 7FEE7798181ED8EF000F684A /* OSKActivitiesManager.m in Sources */, 7FEE77D3181ED8EF000F684A /* OSKTwitterTextEntity.m in Sources */, 7FEE77BF181ED8EF000F684A /* OSKNavigationController.m in Sources */, 7FEE77D7181ED8EF000F684A /* OSKWebViewController.m in Sources */, 7FEE77A0181ED8EF000F684A /* OSKActivityOperation.m in Sources */, + D24CF72F1A6FF57000540A64 /* UIViewController+BNCDebugging.m in Sources */, 7FEE77A9181ED8EF000F684A /* OSKAppDotNetUtility.m in Sources */, 7F55A30018425C46004A3BCC /* OSKSessionController_Pad.m in Sources */, 7FEE77C9181ED8EF000F684A /* OSKRPSTPasswordManagementAppService.m in Sources */, + D24CF72E1A6FF57000540A64 /* BranchServerInterface.m in Sources */, 7FEE77AC181ED8EF000F684A /* OSKChromeActivity.m in Sources */, 7FEE7795181ED8EF000F684A /* OSK1PasswordSearchActivity.m in Sources */, 7F55A2FF18425C46004A3BCC /* OSKSession.m in Sources */, + D24CF72C1A6FF57000540A64 /* BNCSystemObserver.m in Sources */, 7FEE77D2181ED8EF000F684A /* OSKTwitterText.m in Sources */, 7FEE7799181ED8EF000F684A /* OSKActivity.m in Sources */, 7FEE77C2181ED8EF000F684A /* OSKPagedHorizontalLayout.m in Sources */, + D24CF7271A6FF57000540A64 /* BNCPreferenceHelper.m in Sources */, 7FEE77C8181ED8EF000F684A /* OSKReadabilityUtility.m in Sources */, 7FEE77D6181ED8EF000F684A /* OSKUsernamePasswordViewController.m in Sources */, 7FEE77AB181ED8EF000F684A /* OSKBorderedButton.m in Sources */, @@ -1927,6 +2001,7 @@ FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "../../../Dependencies/GooglePlus-SDK", + "/Users/scott/Code/ObjC/overshare-deeplinking-kit/Dependencies/Branch-iOS-SDK", ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Overshare/Overshare-Prefix.pch"; @@ -1949,6 +2024,7 @@ FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "../../../Dependencies/GooglePlus-SDK", + "/Users/scott/Code/ObjC/overshare-deeplinking-kit/Dependencies/Branch-iOS-SDK", ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Overshare/Overshare-Prefix.pch"; diff --git a/Projects/iOS App/Overshare/Overshare/OSKAppDelegate.m b/Projects/iOS App/Overshare/Overshare/OSKAppDelegate.m index 8fb91c9..4fbc586 100644 --- a/Projects/iOS App/Overshare/Overshare/OSKAppDelegate.m +++ b/Projects/iOS App/Overshare/Overshare/OSKAppDelegate.m @@ -14,6 +14,9 @@ #import "SampleTimelineViewController.h" +// Include Branch +#import "Branch.h" + @implementation OSKAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions @@ -21,6 +24,49 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( #warning You must replace this key with your own app's key! [[PocketAPI sharedAPI] setConsumerKey:@"19568-eab36ebc89e751893a754475"]; +#warning You must set your own Branch API key in Overshare-Info.plist as bnc_app_key (String). Find it here: https://dashboard.branch.io/#/settings + // Initialize Branch SDK + /* + http://branch.io + Branch enables custom downloads for every new user. + Drive higher conversions and more engagement using deep links that pass data through install and open. + + 1. Track how many installs/opens come from each shared link. + 2. Calculate viral kFactor + 3. Insight into which share channels are driving the most downloads: Facebook, Twitter, etc. + 4. Insight and analytics on which users are you rbiggest influencers and driving the most downloads. + 5. Embed custom dictionaries that live on through clicking a link - even through the app store - to build a customized experience for each new user and make it really easy to deep link. + 6. Customize links with OG tags to display content in Facebook, Twitter, etc. + 7. Reward new or reffering users! Power the link with referral tracking, reward attribution, and credit balance! + + For full documentation, see README.md in https://github.com/BranchMetrics/Branch-iOS-SDK + */ + + // Signleton instance of Branch. The first time this is called in the app lifecycle, a Branch instance is synchronously instatiated. + Branch *branch = [Branch getInstance]; + +#ifdef DEBUG + // Verbose logs for debugging + [Branch setDebug]; +#endif + + // Initiates a Branch session, and registers a callback. If you created a custom link with your own custom dictionary data, you probably want to know when the user session init finishes, so you can check that data. Think of this callback as your "deep link router". If your app opens with some data, you want to route the user depending on the data you passed in. Otherwise, send them to a generic install flow. + [branch initSessionWithLaunchOptions:launchOptions isReferrable:YES andRegisterDeepLinkHandler:^(NSDictionary *params, NSError *error) { + if (!error) { + NSLog(@"finished init with params = %@", [params description]); + + // example dictionary data + // NSString *name = [params objectForKey:@"user"]; + // NSString *profileUrl = [params objectForKey:@"profile_pic"]; + // NSString *description = [params objectForKey:@"description"]; + + // --- Setting User Identity with Branch --- + // If you want to track indidvidual users in Branch and/or store reward point baances for referral, pass in a unique user id string here! This method could be implemented a number of ways. You'll most certainly want to implement the setIdentity method on app launch if the user is already logged in, and the ID is stored in the user preferences for example. You will also want to implement this method whent he user signs up or authenticates into your app. + // OvershareKit does have a number of authentication services for Facebook, Twitter, App.net, etc. However, note that each one of these services will return a unique user_id. So if one time the user authenticates in with Twitter, then a different time or on a different device, authenticates with Facebook, they will not be identified as the same user! + [[Branch getInstance] setIdentity:@"your user id"]; + } + }]; + UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; [self setWindow:window]; @@ -62,7 +108,20 @@ - (void)applicationWillTerminate:(UIApplication *)application #warning Don't forget to override this method so that Pocket, App.net and Google+ authentication have the opportunity to respond! - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { + BOOL success = NO; + + // ========== Branch ========== + // Branch deep link handeler + // pass the url to the handle deep link call + // if handleDeepLink returns YES, and you registered a callback in initSessionAndRegisterDeepLinkHandler, the callback will be called with the data associated with the deep link. + if (![[Branch getInstance] handleDeepLink:url]) { + + // do other deep link routing for the Facebook SDK, Pinterest SDK, etc + } + // ========== End Branch ========== + + // OvershareKit deep link routing if ([[OSKADNLoginManager sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation]) { success = YES; } diff --git a/Projects/iOS App/Overshare/Overshare/Overshare-Info.plist b/Projects/iOS App/Overshare/Overshare/Overshare-Info.plist index 25826cc..a5dd7ad 100644 --- a/Projects/iOS App/Overshare/Overshare/Overshare-Info.plist +++ b/Projects/iOS App/Overshare/Overshare/Overshare-Info.plist @@ -90,5 +90,7 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + bnc_app_key + 84499351119855798 diff --git a/Projects/iOS App/Overshare/Overshare/SampleTimelineViewController.m b/Projects/iOS App/Overshare/Overshare/SampleTimelineViewController.m index 563b4e3..9bce14a 100644 --- a/Projects/iOS App/Overshare/Overshare/SampleTimelineViewController.m +++ b/Projects/iOS App/Overshare/Overshare/SampleTimelineViewController.m @@ -17,11 +17,11 @@ @interface SampleTimelineViewController () < - SampleTimelineCellDelegate, - OSKPresentationViewControllers, - OSKPresentationStyle, - OSKPresentationColor, - OSKXCallbackURLInfo +SampleTimelineCellDelegate, +OSKPresentationViewControllers, +OSKPresentationStyle, +OSKPresentationColor, +OSKXCallbackURLInfo > @property (assign, nonatomic) OSKActivitySheetViewControllerStyle sheetStyle; @@ -64,31 +64,188 @@ - (void)viewDidLoad { } -#pragma mark - Sharing +#pragma mark - Intro to Overshare Kit Demo - (void)showShareSheetForTappedCell:(SampleTimelineCell *)tappedCell { - // 1) Create the shareable content from the user's source content. + // 1) Grab the user's data that will be shared. NSString *text = @"Me and my dad make models of clipper ships. #Clipperships sail on the ocean."; + NSArray *images = @[[UIImage imageNamed:@"soda.jpg"], [UIImage imageNamed:@"rain.jpg"], [UIImage imageNamed:@"type.jpg"]]; - NSString *canonicalURL = @"http://github.com/overshare/overshare-kit"; + + NSString *canonicalURL = @"https://twitter.com/testochango/status/453193613900410881"; NSString *authorName = @"testochango"; + + // 2) Create the shareable content from the user's source data. + + // Original OvershareKit Shareable Content Method + // This fork of OvershareKit is 100% backwards compatible, meaning the original shareable content items will still work. If the Branch API key is not present, OvershareKit will behave exactly as it does without Branch: directing the user to the URL that is provided. + /* + OSKShareableContent *content = [OSKShareableContent contentFromMicroblogPost:text + authorName:authorName + canonicalURL:canonicalURL + images:images]; + */ + + // ========== Branch ========== + // Now let's use Branch!! + // Provided you have set the Branch API key provided to you here: https://dashboard.branch.io/#/settings + // ...the following methods will seamlessly generate OSK shareable content items, and attach a Branch Short URL to each content channel AND automatically tag it with "facebook," "bookmark," etc. for each channel! + // To see this in action, let's setup some dummy data that we'd like to be passed thru download and install of sharing content with another user + + // For a complete explanation of creating Branch links, see: https://github.com/BranchMetrics/Branch-Integration-Guides/blob/master/url-creation-guide.md + + // Branch tags + // ==================================================== + // Accepts an unlimited number of strings in an NSArray. + // This is more a free form entry of anything that + // helps you collect your thoughts. It’s a place where + // you can add meaningful labels for organizing links + // that aren’t confined to a channel or campaign + NSArray *branchTags = @[@"test_tag1", @"test_tag2"]; + + // Brach deep link params + // ==================================================== + // These are the params you want passed thru the link. + // This could be _anything_ you want: A user id of who shared the content, + // an image URL, an internal URI to direct the user to the content within + // your app, etc. Here are just a few samples... + NSMutableDictionary *branchParams = [[NSMutableDictionary alloc] init]; + // Example params Deep Link data + [branchParams setObject:@"Joe" forKey:@"user"]; + [branchParams setObject:@"https://s3-us-west-1.amazonaws.com/myapp/joes_pic.jpg" forKey:@"profile_pic"]; + [branchParams setObject:@"Joe likes long walks on the beach..." forKey:@"description"]; + + // OpenGraph tags + // ==================================================== + // OpenGraph tags are a way of sharing content attributes + // with social media platforms: http://ogp.me/) <<-- Thanks Facebook! + // These can also be set in the params. A Great thing to do + // If you want your app's name or icon to show up on a Facebook timeline + // when a user shares this on Facebook. + [branchParams setObject:@"Joe is a super cool guy!" forKey:@"$og_title"]; + [branchParams setObject:@"https://branch.io/img/logo_icon_black.png" forKey:@"$og_image_url"]; + [branchParams setObject:@"Because he likes long walks on the beach..." forKey:@"$og_description"]; + + // Branch Stage + // ==================================================== + // This is a label typically used to categorize the progress + // or category of a user when the link was generated. For example, + // if the customer has an invite system accessible on level 1, level 3 and 5, + // the customer could differentiate links generated at each level with this parameter + NSString *branchStage = @"test_stage"; + + // Branch Feature + // ==================================================== + // This is the feature of the customer’s product that the + // link might be associated with. For example, if the customer + // had built a referral program in their app, they might have + // tagged all links with the String ‘referral’. + NSString *branchFeature = @"test_feature"; + + // OSK Content with Branch params + // ==================================================== + // These methods all return a instance of an OSKShareableContent object + // but they also automatically generate a Branch Short URL with all of the Branch + // params they are provided with! + // you can also call contentFromURL with all of these optional params. + + // OSK Content with all arguments OSKShareableContent *content = [OSKShareableContent contentFromMicroblogPost:text authorName:authorName canonicalURL:canonicalURL - images:images]; + images:images + branchTrackingTags:branchTags + branchParams:branchParams + branchStage:branchStage + branchFeature:branchFeature]; + /* + // OSK with tracking tags + OSKShareableContent *content = [OSKShareableContent contentFromMicroblogPost:text + authorName:authorName canonicalURL:canonicalURL + images:images branchTrackingTags:branchTags]; + */ - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { - [self showShareSheet_Phone:content]; - } else { - [self showShareSheet_Pad_FromCell:tappedCell content:content]; - } + // OSK with Branch tags and Params for deep links + /* + OSKShareableContent *content = [OSKShareableContent contentFromMicroblogPost:text + authorName:authorName canonicalURL:canonicalURL + images:images branchTrackingTags:branchTags branchParams:branchParams]; + */ + + // OSK with Params for deep links + /* + OSKShareableContent *content = [OSKShareableContent contentFromMicroblogPost:text + authorName:authorName + canonicalURL:canonicalURL + images:images + branchParams:branchParams]; + */ + // OSK with Branch tags, Params for deep links, and Branch Stage + /* + OSKShareableContent *content = [OSKShareableContent contentFromMicroblogPost:text + authorName:authorName + canonicalURL:canonicalURL + images:images + branchTrackingTags:branchTags + branchParams:branchParams + branchStage:branchStage]; + */ + + // OSK with Branch tags and Branch Stage + /* + OSKShareableContent *content = [OSKShareableContent contentFromMicroblogPost:text + authorName:authorName + canonicalURL:canonicalURL + images:images + branchTrackingTags:branchTags + branchStage:branchStage]; + */ + + // OSK with Branch Params for deep links and Branch Stage + /* + OSKShareableContent *content = [OSKShareableContent contentFromMicroblogPost:text + authorName:authorName + canonicalURL:canonicalURL + images:images + branchParams:branchParams + branchStage:branchStage]; + */ + + // OSK with Branch Stage + /* + OSKShareableContent *content = [OSKShareableContent contentFromMicroblogPost:text + authorName:authorName + canonicalURL:canonicalURL + images:images + branchStage:branchStage]; + */ + + // OSK with Branch Feature + /* + OSKShareableContent *content = [OSKShareableContent contentFromMicroblogPost:text + authorName:authorName + canonicalURL:canonicalURL + images:images + branchFeature:branchFeature]; + */ + + // ========== End Branch ========== + + // 3) Present the activity sheet via the presentation manager. + + [[OSKPresentationManager sharedInstance] presentActivitySheetForContent:content + presentingViewController:self + options:nil]; } + +#pragma mark - Sharing + - (void)showShareSheet_Pad_FromCell:(SampleTimelineCell *)tappedCell content:(OSKShareableContent *)content { [self setIPadPresentingIndexPath:[self.tableView indexPathForCell:tappedCell]]; @@ -99,7 +256,7 @@ - (void)showShareSheet_Pad_FromCell:(SampleTimelineCell *)tappedCell content:(OS // 3) Create the options dictionary. See OSKActivity.h for more options. NSDictionary *options = @{ OSKPresentationOption_ActivityCompletionHandler : completionHandler, - OSKPresentationOption_PresentationEndingHandler : dismissalHandler}; + OSKPresentationOption_PresentationEndingHandler : dismissalHandler}; // 4) Prep the iPad-specific presentation needs. CGRect presentationRect = [self presentationRectForCell:tappedCell]; @@ -132,22 +289,6 @@ - (void)showShareSheet_Pad_FromBarButtonItem:(UIBarButtonItem *)barButtonItem co options:options]; } -- (void)showShareSheet_Phone:(OSKShareableContent *)content { - - // 2) Setup optional completion and dismissal handlers - OSKActivityCompletionHandler completionHandler = [self activityCompletionHandler]; - OSKPresentationEndingHandler dismissalHandler = [self dismissalHandler]; - - // 3) Create the options dictionary. See OSKActivity.h for more options. - NSDictionary *options = @{ OSKPresentationOption_ActivityCompletionHandler : completionHandler, - OSKPresentationOption_PresentationEndingHandler : dismissalHandler}; - - // 4) Present the activity sheet via the presentation manager. - [[OSKPresentationManager sharedInstance] presentActivitySheetForContent:content - presentingViewController:self - options:options]; -} - #pragma mark - OSKActivitiesManager X-Callback-URL Delegate @@ -175,10 +316,22 @@ - (OSKActivitySheetViewControllerStyle)osk_activitySheetStyle { } - (BOOL)osk_toolbarsUseUnjustifiablyBorderlessButtons { -#warning Override this to use bordered navigation bar buttons. +#warning Override this and return NO to enable bordered navigation bar buttons. return YES; } +/* +- (UIFontDescriptor *)osk_normalFontDescriptor { + NSDictionary *attributes = @{UIFontDescriptorNameAttribute : @"AvenirNext-Regular"}; + UIFontDescriptor *descriptor = [UIFontDescriptor fontDescriptorWithFontAttributes:attributes]; + return descriptor; +} +- (UIFontDescriptor *)osk_boldFontDescriptor { + NSDictionary *attributes = @{UIFontDescriptorNameAttribute : @"AvenirNext-Bold"}; + UIFontDescriptor *descriptor = [UIFontDescriptor fontDescriptorWithFontAttributes:attributes]; + return descriptor; +} +*/ #pragma mark - OSKPresentationManager Color Delegate @@ -244,7 +397,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } -#pragma mark - SampleTimelineViewController +#pragma mark - SampleTimelineViewController - (void)accountManagerButtonTapped:(id)sender { [self showAccountsManagement]; diff --git a/README.md b/README.md index 5716eca..2af2e0b 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,10 @@ OvershareKit - [URL Schemes](#url-schemes) - [Dependencies](#dependencies) - [In-App Purchases](#in-app-purchases) +- [Branch Setup](#branch-setup) +- [Branch Links](#branch-links-in-osk-content) +- [Branch Identity](#setting-branch-identity) +- [Branch Events](#branch-events) - [So Much More](#so-much-more) - [Contributors](#contributors) - [Apps Using OvershareKit](#apps-using-oversharekit) @@ -36,6 +40,8 @@ OvershareKit makes it trivial to add rich sharing options to your iOS apps. In a - Built-in integration with popular third-party services like App.net, Instapaper, and more. +- Built-in integration with Branch.io, enabling custom downloads for every new user. + - Complete multi-account management, including authentication and storing credentials securely in the Keychain. - Killer text editing views with as-you-type Twitter syntax highlighting, [Riposte](http://riposteapp.net)-style swipe gesture cursor navigation, and automatic smart quotes. @@ -127,6 +133,8 @@ The list of services currently requiring application credentials are: - **Google Plus:** You'll need to obtain an application key by registering your app with Google Plus. +- **Branch:** Branch enables custom downloads for every new user. Visit http://branch.io for more information. You'll need to obtain an API key by registering your app with Branch. + If you have any questions about this setup process, don’t hesitate to [ask]. ### URL Schemes @@ -139,12 +147,14 @@ If you have any questions about this setup process, don’t hesitate to [ask]. OvershareKit is almost entirely a standalone library. All of its categories and classes have been properly namespaced with the `OSK` prefix to avoid collisions. -There are two required external libraries, which are included as git submodules in the Depedencies directory: +There are three required external libraries, which are included as git submodules in the Depedencies directory: - [App.net Login SDK](https://github.com/appdotnet/ADNLogin-SDK-iOS) - [Pocket-iOS-SDK](https://github.com/Pocket/Pocket-ObjC-SDK) +- [Branch-iOS-SDK](https://github.com/BranchMetrics/Branch-iOS-SDK) + *The Google Plus framework in the Dependencies directory is not a submodule.* @@ -152,6 +162,119 @@ There are two required external libraries, which are included as git submodules You can optionally configure certain activity types to require in-app purchase. OvershareKit does not handle purchasing or receipt validation, but it does handle the logic around presenting your custom purchasing view controller at the appropriate time. OvershareKit will even badge the activity icons with cute little price tags when they have not yet been purchased. See the header files for `OSKActivitiesManager` and `OSKPurchasingViewController` for more details. +## Branch Setup +Branch.io enables tracking, and personalized downloads for every user of your app through deep links, that pass data **thourgh install and open**. An example use case: Your app has a microblog post the user shares via OvershareKit. Rather than the user sharing the original URL, the Branch integration with OvershareKit automatically converts the original URL into a unique Brach short url for each action. Each short URL auto embeds the sharing channel (facebook, twitter, etc), and extends the OvershareKit Content methods to easily pass in deep link parameters, and tags to track app stage, and specific features. + +Ideally, you want to use Branch links any time you have an external link pointing to your app (share, invite, referral, etc) because: + +1. The Branch dashboard can tell you where your installs are coming from +2. Branch links are the highest possible converting channel to new downloads and users +3. You can pass shared data across install to give new users a custom welcome or show them the content they expect to see + +Our linking infrastructure will support anything you want to build. If it doesn't, we'll fix it so that it does: just reach out to [alex@branch.io](mailto:alex@branch.io) with requests. + +The original Branch iOS SDK and Documentation can [be found here](https://github.com/BranchMetrics/Branch-iOS-SDK) + +**To get started** with the Branch integration in OvershareKit, first signup for a [Branch account](https://dashboard.branch.io/) + +**Add the Branch API key** found in the [Settings panel](https://dashboard.branch.io/#/settings) of the dashboard, to your app's plist file, as "bnc_app_key". To do this, open the "Info" tab in your XCode project, and add a key to the "Custom iOS Target Properties." + +**Register a URI scheme** in your app's plist file, so your app responds to direct deep links (example: myapp://...). This step is optional, but highly recomended. Full instructions [found here](https://github.com/BranchMetrics/Branch-iOS-SDK#register-a-uri-scheme-direct-deep-linking-optional-but-recommended) + +**Initialize the Branch SDK**. Branch has a singleton instance that can be refferenced by calling [Branch getInstance]. The first time this is called, a singleton is allocated that can be referrenced throughout the app. To initliaize a Branch session, call: +```objc +[[Branch getInstance] initSessionWithLaunchOptions andRegisterDeepLinkHandler:^(NSDictionary *params, NSError *error) {...}]; +``` +There is an example of this in the OvershareKit Sample App in the app delegate. + +**Register for deeplinks**. You'll likely want your app to respond to it's customer URI scheme, and handle showing the user the correct content with the data your app is passed via the Branch deep link. To do this, your app delegate should respond to +```objc +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; +``` +The url passed in via this method, should be sent to the Branch singleton with: +```objc +[[Branch getInstance] handleDeepLink:url]; +``` +There is also an example of this in the OvershareKit sample app delegate. + +## Branch Links in OSK Content +Once you've setup the Branch Integration with the steps in the previous section, you're ready to initiate an OvershareKit Content with Branch short URLs! Normally, you call contentFromMicroblogPost or contentFromURL on an OSKShareableContent instance to setup a collection of Content Items for each share channel (Facebook, Twitter, etc). This integration extends those methods to include the Branch parameters: tracking tags, stage, feature, and deep linking & OG params. An example of this can be seen in the OvershareKit Sample app, in SampleTimelineViewController.m starting at line 82. + +These methods will seamlessly generate OSK shareable content items, and attach a Branch Short URL to each content channel AND automatically tag it with "facebook," "bookmark," etc. for each channel! If you do not have the Branch API key set, OSK will behave as it does without Branch. + +####All availabe Branch OSK extended methods +(All of these methods also available as contentFromMicroblogPost) + +```objc ++ (instancetype)contentFromURL:(NSURL *)url branchTrackingTags:(NSArray *)branchTrackingTags branchParams:(NSDictionary *)branchParams branchStage:(NSString *)branchStage branchFeature:(NSString *)branchFeature; + ++ (instancetype)contentFromURL:(NSURL *)url branchTrackingTags:(NSArray *)branchTrackingTags; + ++ (instancetype)contentFromURL:(NSURL *)url branchTrackingTags:(NSArray *)branchTrackingTags branchParams:(NSDictionary *)branchPrams; + ++ (instancetype)contentFromURL:(NSURL *)url branchParams:(NSDictionary *)branchPrams; + ++ (instancetype)contentFromURL:(NSURL *)url branchTrackingTags:(NSArray *)branchTrackingTags branchParams:(NSDictionary branchStage:(NSString *)branchStage; + ++ (instancetype)contentFromURL:(NSURL *)url branchTrackingTags:(NSArray *)branchTrackingTags branchStage:(NSString *)branchStage; + ++ (instancetype)contentFromURL:(NSURL *)url branchStage:(NSString *)branchStage; + ++ (instancetype)contentFromURL:(NSURL *)url branchTrackingTags:(NSArray *)branchTrackingTags branchParams:(NSDictionary *)branchParams branchFeature:(NSString *)branchFeature; + ++ (instancetype)contentFromURL:(NSURL *)url branchTrackingTags:(NSArray *)branchTrackingTags branchStage:(NSString *)branchStage branchFeature:(NSString *)branchFeature; + ++ (instancetype)contentFromURL:(NSURL *)url branchParams:(NSDictionary *)branchParams branchStage:(NSString *)branchStage branchFeature:(NSString *)branchFeature; + ++ (instancetype)contentFromURL:(NSURL *)url branchParams:(NSDictionary *)branchParams branchFeature:(NSString *)branchFeature; + ++ (instancetype)contentFromURL:(NSURL *)url branchStage:(NSString *)branchStage branchFeature:(NSString *)branchFeature; + ++ (instancetype)contentFromURL:(NSURL *)url branchTrackingTags:(NSArray *)branchTrackingTags branchFeature:(NSString *)branchFeature; + ++ (instancetype)contentFromURL:(NSURL *)url branchFeature:(NSString *)branchFeature; +``` +## Setting Branch Identity + +Often, you might have your own user IDs, or want referral and event data to persist across platforms or uninstall/reinstall. It's helpful if you know your users access your service from different devices. This where we introduce the concept of an 'identity'. + +To identify a user, just call: +```objc + [[Branch getInstance] setIdentity:@"your user id"]; +``` +**Note:** +OvershareKit does have a number of authentication services for Facebook, Twitter, App.net, etc. However, each one of these services will return a unique user id. So if one time the user authenticates in with Twitter, then a different time or on a different device, authenticates with Facebook, they will not be identified as the same user! Therefore, you'll need to be sure that you authenticate users on Branch via the same method, or in a way that returns the same user id. + +#### Logout + +If you provide a logout function in your app, be sure to clear the user when the logout completes. This will ensure that all the stored parameters get cleared and all events are properly attributed to the right identity. + +**Warning** this call will clear the referral credits and attribution on the device. + +```objc +[[Branch getInstance] logout]; +``` + +## Branch Events +The Branch OvershareKit integration automatically registers four events: +- **click_share** registered when a user clicks a share channel option in OvershareKit +- **cancelled_share** registered when a user cancelles sharing a link +- **successful_share** registered when the OvershareKit completion handeler returns with a successful response +- **failed_share** registered when the OvershareKit completion handeler returns with a unseccessful response + +#### Register custom events + +This is very easy to do by calling: +```objc +Branch *branch = [Branch getInstance]; +[branch userCompletedAction:@"your_custom_event"]; +``` +Optionally, you can save the app state with the event: +```objc +Branch *branch = [Branch getInstance]; +[branch userCompletedAction:@"your_custom_event" withState:(NSDictionary *)appState]; +``` + ## So Much More There’s a ton of stuff to work with in OvershareKit. All of the major and many of the minor classes have been documented with [appledoc](http://gentlebytes.com/appledoc/) syntax. More documentation is coming. If you have questions, please reach out to us.