1
- #import < Foundation/Foundation.h>
2
1
#import < objc/runtime.h>
3
- #if TARGET_OS_OSX
4
- #import < AppKit/AppKit.h>
5
- #import " MSNSAppDelegate.h"
6
- #else
7
- #import < UIKit/UIKit.h>
8
- #import " MSUIAppDelegate.h"
9
- #endif
10
2
3
+ #import " MSCustomApplicationDelegate.h"
11
4
#import " MSAppDelegateForwarderPrivate.h"
12
5
#import " MSAppCenterInternal.h"
13
6
#import " MSLogger.h"
18
11
static NSString *const kMSIsAppDelegateForwarderEnabledKey = @" AppCenterAppDelegateForwarderEnabled" ;
19
12
20
13
// Original selectors with special handling.
21
- static NSString *const kMSDidReceiveRemoteNotificationFetchHandler =
22
- @" application:didReceiveRemoteNotification:fetchCompletionHandler:" ;
23
14
static NSString *const kMSOpenURLSourceApplicationAnnotation = @" application:openURL:sourceApplication:annotation:" ;
24
15
static NSString *const kMSOpenURLOptions = @" application:openURL:options:" ;
25
16
26
- static NSHashTable <id <MSAppDelegate >> *_delegates = nil ;
17
+ static NSHashTable <id <MSCustomApplicationDelegate >> *_delegates = nil ;
27
18
static NSMutableSet <NSString *> *_selectorsToSwizzle = nil ;
28
- static NSArray <NSString *> *_selectorsNotToOverride = nil ;
29
19
static NSDictionary <NSString *, NSString *> *_deprecatedSelectors = nil ;
30
20
static NSMutableDictionary <NSString *, NSValue *> *_originalImplementations = nil ;
31
21
static NSMutableArray <dispatch_block_t > *traceBuffer = nil ;
@@ -75,27 +65,18 @@ + (instancetype)sharedInstance {
75
65
76
66
#pragma mark - Accessors
77
67
78
- + (NSHashTable <id<MSAppDelegate >> *)delegates {
68
+ + (NSHashTable <id<MSCustomApplicationDelegate >> *)delegates {
79
69
return _delegates ?: (_delegates = [NSHashTable weakObjectsHashTable ]);
80
70
}
81
71
82
- + (void )setDelegates : (NSHashTable <id<MSAppDelegate >> *)delegates {
72
+ + (void )setDelegates : (NSHashTable <id<MSCustomApplicationDelegate >> *)delegates {
83
73
_delegates = delegates;
84
74
}
85
75
86
76
+ (NSMutableSet <NSString *> *)selectorsToSwizzle {
87
77
return _selectorsToSwizzle ?: (_selectorsToSwizzle = [NSMutableSet new ]);
88
78
}
89
79
90
- + (NSArray <NSString *> *)selectorsNotToOverride {
91
- if (!_selectorsNotToOverride) {
92
- #if !TARGET_OS_OSX
93
- _selectorsNotToOverride = @[ kMSDidReceiveRemoteNotificationFetchHandler ];
94
- #endif
95
- }
96
- return _selectorsNotToOverride;
97
- }
98
-
99
80
+ (NSDictionary <NSString *, NSString *> *)deprecatedSelectors {
100
81
if (!_deprecatedSelectors) {
101
82
#if TARGET_OS_OSX
@@ -152,15 +133,15 @@ + (void)setEnabled:(BOOL)enabled {
152
133
153
134
#pragma mark - Delegates
154
135
155
- + (void )addDelegate : (id <MSAppDelegate >)delegate {
136
+ + (void )addDelegate : (id <MSCustomApplicationDelegate >)delegate {
156
137
@synchronized (self) {
157
138
if (self.enabled ) {
158
139
[self .delegates addObject: delegate];
159
140
}
160
141
}
161
142
}
162
143
163
- + (void )removeDelegate : (id <MSAppDelegate >)delegate {
144
+ + (void )removeDelegate : (id <MSCustomApplicationDelegate >)delegate {
164
145
@synchronized (self) {
165
146
if (self.enabled ) {
166
147
[self .delegates removeObject: delegate];
@@ -184,8 +165,7 @@ + (void)swizzleOriginalDelegate:(id<MSApplicationDelegate>)originalDelegate {
184
165
if (originalImp) {
185
166
186
167
// Save the original implementation for later use.
187
- MSAppDelegateForwarder.originalImplementations [selectorString] =
188
- [NSValue valueWithBytes: &originalImp objCType: @encode (IMP )];
168
+ self.originalImplementations [selectorString] = [NSValue valueWithBytes: &originalImp objCType: @encode (IMP )];
189
169
}
190
170
}
191
171
[self .selectorsToSwizzle removeAllObjects ];
@@ -208,18 +188,7 @@ + (IMP)swizzleOriginalSelector:(SEL)originalSelector
208
188
209
189
// Replace original implementation by the custom one.
210
190
if (originalMethod) {
211
-
212
- /*
213
- * Also, some selectors should not be overridden mostly because the original implementation highly
214
- * depend on the SDK return value for its own logic so customers already have to call the SDK API
215
- * in their implementation which makes swizzling useless.
216
- */
217
- if (![self .selectorsNotToOverride containsObject: originalSelectorStr]) {
218
- originalImp = method_setImplementation (originalMethod, customImp);
219
- } else {
220
- warningMsg =
221
- [NSString stringWithFormat: @" This selector is not supported when already implemented. %@ " , remediationMsg];
222
- }
191
+ originalImp = method_setImplementation (originalMethod, customImp);
223
192
} else if (![originalClass instancesRespondToSelector: originalSelector]) {
224
193
225
194
// Check for deprecation.
@@ -326,6 +295,7 @@ - (void)custom_setDelegate:(id<MSApplicationDelegate>)delegate {
326
295
#pragma mark - Custom UIApplicationDelegate
327
296
328
297
#if !TARGET_OS_OSX
298
+
329
299
/*
330
300
* Those methods will never get called but their implementation will be used by swizzling.
331
301
* Those implementations will run within the delegate context. Meaning that `self` will point
@@ -375,103 +345,6 @@ - (BOOL)custom_application:(UIApplication *)application
375
345
}
376
346
#endif
377
347
378
- #if TARGET_OS_OSX
379
- - (void )custom_application:(NSApplication *)application
380
- #else
381
- - (void )custom_application:(UIApplication *)application
382
- #endif
383
- didRegisterForRemoteNotificationsWithDeviceToken: (NSData *)deviceToken {
384
- IMP originalImp = NULL ;
385
-
386
- // Forward to the original delegate.
387
- [MSAppDelegateForwarder.originalImplementations[NSStringFromSelector (_cmd )] getValue: &originalImp];
388
- if (originalImp) {
389
- #if TARGET_OS_OSX
390
- ((void (*)(id , SEL , NSApplication *, NSData *))originalImp)(self, _cmd, application, deviceToken);
391
- #else
392
- ((void (*)(id , SEL , UIApplication *, NSData *))originalImp)(self, _cmd, application, deviceToken);
393
- #endif
394
- }
395
-
396
- // Forward to custom delegates.
397
- [[MSAppDelegateForwarder sharedInstance ] application: application
398
- didRegisterForRemoteNotificationsWithDeviceToken: deviceToken];
399
- }
400
-
401
- #if TARGET_OS_OSX
402
- - (void )custom_application:(NSApplication *)application
403
- #else
404
- - (void )custom_application:(UIApplication *)application
405
- #endif
406
- didFailToRegisterForRemoteNotificationsWithError: (NSError *)error {
407
- IMP originalImp = NULL ;
408
-
409
- // Forward to the original delegate.
410
- [MSAppDelegateForwarder.originalImplementations[NSStringFromSelector (_cmd )] getValue: &originalImp];
411
- if (originalImp) {
412
- #if TARGET_OS_OSX
413
- ((void (*)(id , SEL , NSApplication *, NSError *))originalImp)(self, _cmd, application, error);
414
- #else
415
- ((void (*)(id , SEL , UIApplication *, NSError *))originalImp)(self, _cmd, application, error);
416
- #endif
417
- }
418
-
419
- // Forward to custom delegates.
420
- [[MSAppDelegateForwarder sharedInstance ] application: application
421
- didFailToRegisterForRemoteNotificationsWithError: error];
422
- }
423
-
424
- #if TARGET_OS_OSX
425
- - (void )custom_application:(NSApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
426
- #else
427
- - (void )custom_application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
428
- #endif
429
- IMP originalImp = NULL ;
430
-
431
- // Forward to the original delegate.
432
- [MSAppDelegateForwarder.originalImplementations[NSStringFromSelector (_cmd )] getValue: &originalImp];
433
- if (originalImp) {
434
- #if TARGET_OS_OSX
435
- ((void (*)(id , SEL , NSApplication *, NSDictionary *))originalImp)(self, _cmd, application, userInfo);
436
- #else
437
- ((void (*)(id , SEL , UIApplication *, NSDictionary *))originalImp)(self, _cmd, application, userInfo);
438
- #endif
439
- }
440
-
441
- // Forward to custom delegates.
442
- [[MSAppDelegateForwarder sharedInstance ] application: application didReceiveRemoteNotification: userInfo];
443
- }
444
-
445
- #if !TARGET_OS_OSX
446
- - (void )custom_application:(UIApplication *)application
447
- didReceiveRemoteNotification:(NSDictionary *)userInfo
448
- fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
449
-
450
- // Collect `UIBackgroundFetchResult` from delegates in order to call the original completion handler later.
451
- __block UIBackgroundFetchResult forwardedFetchResult = UIBackgroundFetchResultNoData;
452
- void (^forwardedCompletionHandler)(UIBackgroundFetchResult) = ^(UIBackgroundFetchResult fetchResult) {
453
- forwardedFetchResult = fetchResult;
454
- };
455
-
456
- /*
457
- * FIXME: We still need to chain the forwardedFetchResult somehow in case of multiple custom delegate implementing
458
- * this selector.
459
- */
460
-
461
- /*
462
- * Forward to custom delegates. This method doesn't override original the delegate implementation so there is no need
463
- * to forward to the original implementation. As a consequence customers must call the corresponding APIs in the SDK
464
- * if they implement this selector in their delegate.
465
- */
466
- [[MSAppDelegateForwarder sharedInstance ] application: application
467
- didReceiveRemoteNotification: userInfo
468
- fetchCompletionHandler: forwardedCompletionHandler];
469
-
470
- // Must call the original completion handler.
471
- completionHandler (forwardedFetchResult);
472
- }
473
- #endif
474
-
475
348
#pragma mark - Forwarding
476
349
477
350
- (void )forwardInvocation: (NSInvocation *)invocation {
@@ -490,7 +363,7 @@ - (void)forwardInvocation:(NSInvocation *)invocation {
490
363
}
491
364
492
365
// Forward to delegates executing a custom method.
493
- for (id <MSAppDelegate > delegate in [self class ].delegates ) {
366
+ for (id <MSCustomApplicationDelegate > delegate in [self class ].delegates ) {
494
367
if ([delegate respondsToSelector: invocation.selector]) {
495
368
[invocation invokeWithTarget: delegate];
496
369
0 commit comments