Skip to content

Commit c6ba481

Browse files
authored
Added [UIViewController bnc_currentViewController] category. (#755)
* Simplifies code in a number of cases. * Added the category. * Updated all uses of similar existing code. * Updated search window order. * Update case for split view controllers.
1 parent 53679d0 commit c6ba481

File tree

12 files changed

+129
-112
lines changed

12 files changed

+129
-112
lines changed

Branch-SDK/Branch-SDK/BNCSpotlightService.m

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ - (dispatch_queue_t) workQueue {
318318
- (void)indexUsingNSUserActivity:(NSDictionary *)params {
319319
self.userInfo = params[@"userInfo"];
320320
self.userInfo[CSSearchableItemActivityIdentifier] = params[@"spotlightId"];
321-
UIViewController *activeViewController = [self getActiveViewController];
321+
UIViewController *activeViewController = [UIViewController bnc_currentViewController];
322322
if (!activeViewController) {
323323
// if no view controller, don't index. Current use case: iMessage extensions
324324
return;
@@ -404,37 +404,7 @@ - (void)indexUsingSearchableItem:(NSDictionary*)indexingParam
404404
#undef IndexingNotAvalable
405405
}
406406

407-
#pragma mark Helper Methods
408-
409-
- (UIViewController *)getActiveViewController {
410-
Class UIApplicationClass = NSClassFromString(@"UIApplication");
411-
UIViewController *rootViewController = [UIApplicationClass sharedApplication].keyWindow.rootViewController;
412-
UIViewController *activeController;
413-
if ([rootViewController isKindOfClass:[UINavigationController class]]) {
414-
activeController = ((UINavigationController *)rootViewController).topViewController;
415-
} else if ([rootViewController isKindOfClass:[UITabBarController class]]) {
416-
activeController = ((UITabBarController *)rootViewController).selectedViewController;
417-
} else {
418-
activeController = rootViewController;
419-
}
420-
return activeController;
421-
}
422-
423-
- (UIViewController *)currentViewController {
424-
// TODO: Create a general 'currentViewController' utility function.
425-
Class UIApplicationClass = NSClassFromString(@"UIApplication");
426-
if (!UIApplicationClass) return nil;
427-
428-
UIViewController *current =
429-
[UIApplicationClass sharedApplication].keyWindow.rootViewController;
430-
while (current.presentedViewController &&
431-
![current.presentedViewController isKindOfClass:UIAlertController.class]) {
432-
current = current.presentedViewController;
433-
}
434-
return current;
435-
}
436-
437-
#pragma mark userActivity Delegate Methods
407+
#pragma mark - UserActivity Delegate Methods
438408

439409
- (void)userActivityWillSave:(NSUserActivity *)userActivity {
440410
[userActivity addUserInfoEntriesFromDictionary:self.userInfo];

Branch-SDK/Branch-SDK/BNCStrongMatchHelper.m

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#import "BNCSystemObserver.h"
1414
#import "BranchConstants.h"
1515
#import "BNCLog.h"
16+
#import "UIViewController+Branch.h"
1617
#import <objc/runtime.h>
1718

1819

@@ -259,37 +260,6 @@ - (BOOL) subclass:(Class)subclass selector:(SEL)selector {
259260
return YES;
260261
}
261262

262-
- (UIWindow*) keyWindow {
263-
Class UIApplicationClass = NSClassFromString(@"UIApplication");
264-
UIWindow *keyWindow = [UIApplicationClass sharedApplication].keyWindow;
265-
if (keyWindow) return keyWindow;
266-
// ToDo: Put different code for extensions here.
267-
return nil;
268-
}
269-
270-
/**
271-
Find the top view controller that is not of type UINavigationController, UITabBarController, UISplitViewController
272-
*/
273-
- (UIViewController *)topViewController:(UIViewController *)baseViewController {
274-
if ([baseViewController isKindOfClass:[UINavigationController class]]) {
275-
return [self topViewController: ((UINavigationController *)baseViewController).visibleViewController];
276-
}
277-
278-
if ([baseViewController isKindOfClass:[UITabBarController class]]) {
279-
return [self topViewController: ((UITabBarController *)baseViewController).selectedViewController];
280-
}
281-
282-
if ([baseViewController isKindOfClass:[UISplitViewController class]]) {
283-
return [self topViewController: ((UISplitViewController *)baseViewController).viewControllers.firstObject];
284-
}
285-
286-
if ([baseViewController presentedViewController] != nil) {
287-
return [self topViewController: [baseViewController presentedViewController]];
288-
}
289-
290-
return baseViewController;
291-
}
292-
293263
- (BOOL) willLoadViewControllerWithURL:(NSURL*)matchURL {
294264
if (self.primaryWindow) return NO;
295265

@@ -324,7 +294,7 @@ - (BOOL) willLoadViewControllerWithURL:(NSURL*)matchURL {
324294
}
325295

326296
BNCLogDebugSDK(@"Safari is initializing.");
327-
self.primaryWindow = [self keyWindow];
297+
self.primaryWindow = [UIViewController bnc_currentWindow];
328298

329299
self.matchViewController = [[BNCMatchViewControllerSubclass alloc] initWithURL:matchURL];
330300
if (!self.matchViewController) return NO;
@@ -336,7 +306,7 @@ - (BOOL) willLoadViewControllerWithURL:(NSURL*)matchURL {
336306
self.matchView.alpha = 1.0;
337307
[self.matchView addSubview:self.matchViewController.view];
338308

339-
UIViewController *rootViewController = [self topViewController:self.primaryWindow.rootViewController];
309+
UIViewController *rootViewController = [self.primaryWindow.rootViewController bnc_currentViewController];
340310

341311
[rootViewController addChildViewController:self.matchViewController];
342312
UIView *parentView = rootViewController.view ?: self.primaryWindow;

Branch-SDK/Branch-SDK/Branch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#import "BranchUniversalObject.h"
3636
#import "BranchView.h"
3737
#import "BranchViewHandler.h"
38+
#import "UIViewController+Branch.h"
3839

3940
/**
4041
`Branch` is the primary interface of the Branch iOS SDK. Currently, all interactions you will make are funneled through this class. It is not meant to be instantiated or subclassed, usage should be limited to the global instance.

Branch-SDK/Branch-SDK/Branch.m

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ void ForceCategoriesToLoad(void) {
8383
BNCForceNSErrorCategoryToLoad();
8484
BNCForceNSStringCategoryToLoad();
8585
BNCForceNSMutableDictionaryCategoryToLoad();
86+
BNCForceUIViewControllerCategoryToLoad();
8687
}
8788

8889
#pragma mark - BranchLink
@@ -1778,10 +1779,8 @@ - (BNCLinkData *)prepareLinkDataFor:(NSArray *)tags
17781779
return post;
17791780
}
17801781

1781-
17821782
#pragma mark - BranchUniversalObject methods
17831783

1784-
17851784
- (void)registerViewWithParams:(NSDictionary *)params andCallback:(callbackWithParams)callback {
17861785
[self initSessionIfNeededAndNotInProgress];
17871786
BranchUniversalObject *buo = [[BranchUniversalObject alloc] init];
@@ -1790,7 +1789,6 @@ - (void)registerViewWithParams:(NSDictionary *)params andCallback:(callbackWithP
17901789
if (callback) callback(@{}, nil);
17911790
}
17921791

1793-
17941792
#pragma mark - Application State Change methods
17951793

17961794
- (void)applicationDidBecomeActive {
@@ -1826,7 +1824,6 @@ - (void)callClose {
18261824
}
18271825
}
18281826

1829-
18301827
#pragma mark - Queue management
18311828

18321829
- (NSInteger) networkCount {
@@ -2086,7 +2083,6 @@ - (void)handleInitSuccess {
20862083
}
20872084
[self sendOpenNotificationWithLinkParameters:latestReferringParams error:nil];
20882085

2089-
Class UIApplicationClass = NSClassFromString(@"UIApplication");
20902086
if (self.shouldAutomaticallyDeepLink) {
20912087
// Find any matched keys, then launch any controllers that match
20922088
// TODO which one to launch if more than one match?
@@ -2105,8 +2101,8 @@ - (void)handleInitSuccess {
21052101
BNCLogWarning(@"The automatic deeplink view controller '%@' for key '%@' does not implement 'configureControlWithData:'.",
21062102
branchSharingController, key);
21072103
}
2108-
self.deepLinkPresentingController = [[[UIApplicationClass sharedApplication].delegate window] rootViewController];
2109-
2104+
2105+
self.deepLinkPresentingController = [UIViewController bnc_currentViewController];
21102106
if([self.deepLinkControllers[key] isKindOfClass:[BNCDeepLinkViewControllerInstance class]]) {
21112107
BNCDeepLinkViewControllerInstance* deepLinkInstance = self.deepLinkControllers[key];
21122108
UIViewController <BranchDeepLinkingController> *branchSharingController = deepLinkInstance.viewController;

Branch-SDK/Branch-SDK/BranchContentDiscoverer.m

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
// Copyright © 2016 Branch Metrics. All rights reserved.
77
//
88

9-
109
#import <CommonCrypto/CommonDigest.h>
1110
#import "BranchContentDiscoverer.h"
1211
#import "BranchContentDiscoveryManifest.h"
@@ -15,7 +14,7 @@
1514
#import "BranchConstants.h"
1615
#import "BNCEncodingUtils.h"
1716
#import "BNCLog.h"
18-
17+
#import "UIViewController+Branch.h"
1918

2019
@interface BranchContentDiscoverer ()
2120
@property (nonatomic, strong) NSString *lastViewControllerName;
@@ -73,7 +72,7 @@ - (void)stopDiscoveryTask {
7372

7473
- (void)readContentDataIfNeeded {
7574
if (_numOfViewsDiscovered < self.contentManifest.maxViewHistoryLength) {
76-
UIViewController *presentingViewController = [self getActiveViewController];
75+
UIViewController *presentingViewController = [UIViewController bnc_currentViewController];
7776
if (presentingViewController) {
7877
NSString *presentingViewControllerName = NSStringFromClass([presentingViewController class]);
7978
if (_lastViewControllerName == nil || ![_lastViewControllerName isEqualToString:presentingViewControllerName]) {
@@ -247,25 +246,6 @@ - (NSString *)getViewText:(NSString *)viewId
247246
return viewTxt;
248247
}
249248

250-
- (UIViewController *)getActiveViewController {
251-
Class UIApplicationClass = NSClassFromString(@"UIApplication");
252-
UIViewController *rootViewController = [UIApplicationClass sharedApplication].keyWindow.rootViewController;
253-
return [self getActiveViewController:rootViewController];
254-
255-
}
256-
257-
- (UIViewController *)getActiveViewController:(UIViewController *)rootViewController {
258-
UIViewController *activeController;
259-
if ([rootViewController isKindOfClass:[UINavigationController class]]) {
260-
activeController = ((UINavigationController *)rootViewController).topViewController;
261-
} else if ([rootViewController isKindOfClass:[UITabBarController class]]) {
262-
activeController = ((UITabBarController *)rootViewController).selectedViewController;
263-
} else {
264-
activeController = rootViewController;
265-
}
266-
return activeController;
267-
}
268-
269249
- (void)addFormattedContentData:(NSMutableArray *)contentDataArray
270250
withText:(NSString *)contentData
271251
clearText:(BOOL)isClearText {

Branch-SDK/Branch-SDK/BranchShareLink.m

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,7 @@ - (void) presentActivityViewControllerFromViewController:(UIViewController*_Null
193193
if ([viewController respondsToSelector:@selector(presentViewController:animated:completion:)]) {
194194
presentingViewController = viewController;
195195
} else {
196-
Class UIApplicationClass = NSClassFromString(@"UIApplication");
197-
UIViewController *rootController =
198-
[UIApplicationClass sharedApplication].delegate.window.rootViewController;
196+
UIViewController *rootController = [UIViewController bnc_currentViewController];
199197
if ([rootController respondsToSelector:@selector(presentViewController:animated:completion:)]) {
200198
presentingViewController = rootController;
201199
}

Branch-SDK/Branch-SDK/BranchUniversalObject.m

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -493,15 +493,14 @@ - (void)showShareSheetWithLinkProperties:(BranchLinkProperties *)linkProperties
493493
#pragma clang diagnostic pop
494494
}
495495

496-
UIViewController *presentingViewController;
496+
UIViewController *presentingViewController = nil;
497497
if (viewController && [viewController respondsToSelector:@selector(presentViewController:animated:completion:)]) {
498498
presentingViewController = viewController;
499499
}
500500
else {
501-
Class UIApplicationClass = NSClassFromString(@"UIApplication");
502-
if ([[[[UIApplicationClass sharedApplication].delegate window] rootViewController]
503-
respondsToSelector:@selector(presentViewController:animated:completion:)]) {
504-
presentingViewController = [[[UIApplicationClass sharedApplication].delegate window] rootViewController];
501+
UIViewController *rootViewController = [UIViewController bnc_currentViewController];
502+
if ([rootViewController respondsToSelector:@selector(presentViewController:animated:completion:)]) {
503+
presentingViewController = rootViewController;
505504
}
506505
}
507506

Branch-SDK/Branch-SDK/BranchViewHandler.m

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,7 @@ - (void)showView:(BranchView *)branchView {
8585
}
8686

8787
- (void)closeBranchView {
88-
Class UIApplicationClass = NSClassFromString(@"UIApplication");
89-
UIViewController *presentingViewController = [[[[UIApplicationClass sharedApplication] windows] firstObject] rootViewController];
88+
UIViewController *presentingViewController = [UIViewController bnc_currentViewController];
9089
[presentingViewController dismissViewControllerAnimated:YES completion:nil];
9190

9291
if (self.branchViewCallback) {
@@ -114,8 +113,8 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView {
114113
if (self.pendingBranchView != nil && self.pendingWebview != nil) {
115114
UIViewController *holderView = [[UIViewController alloc] init];
116115
[holderView.view insertSubview:self.pendingWebview atIndex:0];
117-
Class UIApplicationClass = NSClassFromString(@"UIApplication");
118-
UIViewController *presentingViewController = [[[[UIApplicationClass sharedApplication] windows] firstObject] rootViewController];
116+
117+
UIViewController *presentingViewController = [UIViewController bnc_currentViewController];
119118
[presentingViewController presentViewController:holderView animated:YES completion:nil];
120119

121120
[self.pendingBranchView updateUsageCount];
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//
2+
// UIViewController+Branch.h
3+
// Branch-SDK
4+
//
5+
// Created by Edward Smith on 11/16/17.
6+
// Copyright © 2017 Branch. All rights reserved.
7+
//
8+
9+
#if __has_feature(modules)
10+
@import UIKit;
11+
#else
12+
#import <UIKit/UIKit.h>
13+
#endif
14+
15+
@interface UIViewController (Branch)
16+
+ (UIWindow*_Nullable) bnc_currentWindow;
17+
+ (UIViewController*_Nullable) bnc_currentViewController;
18+
- (UIViewController*_Nonnull) bnc_currentViewController;
19+
@end
20+
21+
void BNCForceUIViewControllerCategoryToLoad(void) __attribute__((constructor));
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//
2+
// UIViewController+Branch.m
3+
// Branch-SDK
4+
//
5+
// Created by Edward Smith on 11/16/17.
6+
// Copyright © 2017 Branch. All rights reserved.
7+
//
8+
9+
#import "UIViewController+Branch.h"
10+
11+
@implementation UIViewController (Branch)
12+
13+
+ (UIWindow*_Nullable) bnc_currentWindow {
14+
Class UIApplicationClass = NSClassFromString(@"UIApplication");
15+
if (UIApplicationClass) {
16+
UIWindow *keyWindow = nil;
17+
18+
keyWindow = [UIApplicationClass sharedApplication].delegate.window;
19+
if (keyWindow && !keyWindow.isHidden && keyWindow.rootViewController) return keyWindow;
20+
21+
keyWindow = [UIApplicationClass sharedApplication].keyWindow;
22+
if (keyWindow && !keyWindow.isHidden && keyWindow.rootViewController) return keyWindow;
23+
24+
for (keyWindow in [UIApplicationClass sharedApplication].windows.reverseObjectEnumerator) {
25+
if (!keyWindow.isHidden && keyWindow.rootViewController) return keyWindow;
26+
}
27+
}
28+
29+
// ToDo: Put different code for extensions here.
30+
31+
return nil;
32+
}
33+
34+
+ (UIViewController*_Nullable) bnc_currentViewController {
35+
UIWindow *window = [UIViewController bnc_currentWindow];
36+
return [window.rootViewController bnc_currentViewController];
37+
}
38+
39+
- (UIViewController*_Nonnull) bnc_currentViewController {
40+
if ([self isKindOfClass:[UINavigationController class]]) {
41+
return [((UINavigationController *)self).visibleViewController bnc_currentViewController];
42+
}
43+
44+
if ([self isKindOfClass:[UITabBarController class]]) {
45+
return [((UITabBarController *)self).selectedViewController bnc_currentViewController];
46+
}
47+
48+
if ([self isKindOfClass:[UISplitViewController class]]) {
49+
return [((UISplitViewController *)self).viewControllers.lastObject bnc_currentViewController];
50+
}
51+
52+
if ([self isKindOfClass:[UIPageViewController class]]) {
53+
return [((UIPageViewController*)self).viewControllers.lastObject bnc_currentViewController];
54+
}
55+
56+
if (self.presentedViewController != nil && !self.presentedViewController.isBeingDismissed) {
57+
return [self.presentedViewController bnc_currentViewController];
58+
}
59+
60+
return self;
61+
}
62+
63+
@end
64+
65+
__attribute__((constructor)) void BNCForceUIViewControllerCategoryToLoad() {
66+
// Nothing here, but forces linker to load the category.
67+
}

0 commit comments

Comments
 (0)