1#if __has_include(<EXBranch/EXBranchManager.h>)
2
3// Copyright 2015-present 650 Industries. All rights reserved.
4
5#import "EXScopedBranchManager.h"
6#import "EXScopedBranch.h"
7
8#import "EXEnvironment.h"
9#import "EXKernel.h"
10#import "EXKernelAppRecord.h"
11#import "EXScopedBranch.h"
12
13// These constants need to stay in sync with the ones in RNBranch.
14NSString * const EXBranchLinkOpenedNotificationErrorKey = @"error";
15NSString * const EXBranchLinkOpenedNotificationParamsKey = @"params";
16NSString * const EXBranchLinkOpenedNotificationUriKey = @"uri";
17NSString * const EXBranchLinkOpenedNotification = @"RNBranchLinkOpenedNotification";
18
19@interface EXScopedBranchModuleAvoidWarnings
20- (void)onInitSessionFinished:(NSNotification *)notification;
21@end
22
23@implementation EXScopedBranchManager
24{
25  NSDictionary *_launchOptions;
26  BOOL _isInitialized;
27  NSURL *_url;
28}
29
30EX_REGISTER_SINGLETON_MODULE(BranchManager);
31
32- (void)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
33{
34  _launchOptions = launchOptions;
35  _url = launchOptions[UIApplicationLaunchOptionsURLKey];
36  [super application:application didFinishLaunchingWithOptions:launchOptions];
37}
38
39- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
40{
41  _url = userActivity.webpageURL;
42  return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
43}
44
45- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation
46{
47  _url = url;
48  return [super application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
49}
50
51- (void)branchModuleDidInit:(id)versionedBranchModule
52{
53  if (_isInitialized || ![[self class] isBranchEnabled]) {
54    return;
55  }
56
57  EXScopedBranch *branchModule = (EXScopedBranch *)versionedBranchModule;
58  EXKernelAppRecord *appForModule = [[EXKernel sharedInstance].appRegistry newestRecordWithScopeKey:branchModule.scopeKey];
59  if (appForModule && appForModule == [EXKernel sharedInstance].appRegistry.standaloneAppRecord) {
60    _isInitialized = YES;
61
62    // branch is going to retain the init callback
63    __block typeof(self) blockSelf = self;
64
65    [[Branch getInstance] initSessionWithLaunchOptions:_launchOptions
66                                          isReferrable:YES
67                            andRegisterDeepLinkHandler:^(NSDictionary *params, NSError *error) {
68      NSMutableDictionary *result = [NSMutableDictionary dictionary];
69      if (error) {
70        result[EXBranchLinkOpenedNotificationErrorKey] = error;
71      }
72      if (params) {
73        result[EXBranchLinkOpenedNotificationParamsKey] = params;
74      }
75      if (blockSelf->_url) {
76        result[EXBranchLinkOpenedNotificationUriKey] = blockSelf->_url;
77      }
78
79      // We can't use RNBranch static methods directly because it uses event dispatch
80      // and every instance of the native module will register to it causing duplicate
81      // events (one for each bridge). As a workaround call the event listener manually
82      // on the native module of the standalone app.
83      NSNotification *notification =
84        [[NSNotification alloc] initWithName:EXBranchLinkOpenedNotification object:self userInfo:result];
85      [versionedBranchModule onInitSessionFinished:notification];
86    }];
87  }
88}
89
90@end
91
92#endif
93