From 377a5850d18eeb4356667758ede60fa88abc907c Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Fri, 6 Jul 2018 16:35:44 -0700 Subject: [PATCH 1/4] avoid calling [UIApplication sharedApplication] in app extensions --- Firebase/Messaging/FIRMessaging.m | 5 +++-- .../FIRMessagingContextManagerService.m | 4 +++- Firebase/Messaging/FIRMessagingReceiver.m | 16 +++++++++------- .../FIRMessagingRemoteNotificationsProxy.m | 4 +++- Firebase/Messaging/FIRMessagingUtilities.h | 6 +++++- Firebase/Messaging/FIRMessagingUtilities.m | 19 +++++++++++++++++++ 6 files changed, 42 insertions(+), 12 deletions(-) diff --git a/Firebase/Messaging/FIRMessaging.m b/Firebase/Messaging/FIRMessaging.m index 5dd7004c3d3..bcc5e1415b7 100644 --- a/Firebase/Messaging/FIRMessaging.m +++ b/Firebase/Messaging/FIRMessaging.m @@ -378,7 +378,7 @@ - (void)handleIncomingLinkIfNeededFromMessage:(NSDictionary *)message { }); return; } - UIApplication *application = [UIApplication sharedApplication]; + UIApplication *application = FIRMessagingUIApplication(); id appDelegate = application.delegate; SEL continueUserActivitySelector = @selector(application:continueUserActivity:restorationHandler:); @@ -611,7 +611,8 @@ - (BOOL)shouldBeConnectedAutomatically { // We require a token from Instance ID NSString *token = self.defaultFcmToken; // Only on foreground connections - UIApplicationState applicationState = [UIApplication sharedApplication].applicationState; + UIApplication *application = FIRMessagingUIApplication(); + UIApplicationState applicationState = application.applicationState; BOOL shouldBeConnected = _shouldEstablishDirectChannel && (token.length > 0) && applicationState == UIApplicationStateActive; diff --git a/Firebase/Messaging/FIRMessagingContextManagerService.m b/Firebase/Messaging/FIRMessagingContextManagerService.m index f79e79cd642..bb39eaa652c 100644 --- a/Firebase/Messaging/FIRMessagingContextManagerService.m +++ b/Firebase/Messaging/FIRMessagingContextManagerService.m @@ -20,6 +20,7 @@ #import "FIRMessagingDefines.h" #import "FIRMessagingLogger.h" +#import "FIRMessagingUtilities.h" #define kFIRMessagingContextManagerPrefixKey @"google.c.cm." #define kFIRMessagingContextManagerNotificationKeyPrefix @"gcm.notification." @@ -174,7 +175,8 @@ + (void)scheduleLocalNotificationForMessage:(NSDictionary *)message } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - [[UIApplication sharedApplication] scheduleLocalNotification:notification]; + UIApplication *application = FIRMessagingUIApplication(); + [application scheduleLocalNotification:notification]; #pragma clang diagnostic pop } diff --git a/Firebase/Messaging/FIRMessagingReceiver.m b/Firebase/Messaging/FIRMessagingReceiver.m index 981dfb13172..9ccb8cc0048 100644 --- a/Firebase/Messaging/FIRMessagingReceiver.m +++ b/Firebase/Messaging/FIRMessagingReceiver.m @@ -19,8 +19,9 @@ #import #import "FIRMessaging.h" -#import "FIRMessaging_Private.h" #import "FIRMessagingLogger.h" +#import "FIRMessagingUtilities.h" +#import "FIRMessaging_Private.h" static NSString *const kUpstreamMessageIDUserInfoKey = @"messageID"; static NSString *const kUpstreamErrorUserInfoKey = @"error"; @@ -111,19 +112,20 @@ - (void)scheduleNotificationForMessage:(NSDictionary *)message { SEL oldNotificationSelector = @selector(application:didReceiveRemoteNotification:); dispatch_async(dispatch_get_main_queue(), ^{ - id appDelegate = [[UIApplication sharedApplication] delegate]; + UIApplication *application = FIRMessagingUIApplication(); + id appDelegate = [application delegate]; if ([appDelegate respondsToSelector:newNotificationSelector]) { // Try the new remote notification callback - [appDelegate application:[UIApplication sharedApplication] - didReceiveRemoteNotification:message - fetchCompletionHandler:^(UIBackgroundFetchResult result) {}]; + [appDelegate application:application + didReceiveRemoteNotification:message + fetchCompletionHandler:^(UIBackgroundFetchResult result) { + }]; } else if ([appDelegate respondsToSelector:oldNotificationSelector]) { // Try the old remote notification callback #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - [appDelegate application: - [UIApplication sharedApplication] didReceiveRemoteNotification:message]; + [appDelegate application:application didReceiveRemoteNotification:message]; #pragma clang diagnostic pop } else { FIRMessagingLoggerError(kFIRMessagingMessageCodeReceiver005, diff --git a/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.m b/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.m index c5ad3370b23..7adf076c0ba 100644 --- a/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.m +++ b/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.m @@ -21,6 +21,7 @@ #import "FIRMessagingConstants.h" #import "FIRMessagingLogger.h" +#import "FIRMessagingUtilities.h" #import "FIRMessaging_Private.h" static const BOOL kDefaultAutoRegisterEnabledValue = YES; @@ -98,7 +99,8 @@ - (void)swizzleMethodsIfPossible { return; } - NSObject *appDelegate = [[UIApplication sharedApplication] delegate]; + UIApplication *application = FIRMessagingUIApplication(); + NSObject *appDelegate = [application delegate]; [self swizzleAppDelegateMethods:appDelegate]; // Add KVO listener on [UNUserNotificationCenter currentNotificationCenter]'s delegate property diff --git a/Firebase/Messaging/FIRMessagingUtilities.h b/Firebase/Messaging/FIRMessagingUtilities.h index 45770bf4018..206ff073f7e 100644 --- a/Firebase/Messaging/FIRMessagingUtilities.h +++ b/Firebase/Messaging/FIRMessagingUtilities.h @@ -14,7 +14,7 @@ * limitations under the License. */ -#import +#import typedef NS_ENUM(int8_t, FIRMessagingProtoTag) { kFIRMessagingProtoTagInvalid = -1, @@ -51,4 +51,8 @@ FOUNDATION_EXPORT int64_t FIRMessagingCurrentTimestampInMilliseconds(void); FOUNDATION_EXPORT NSString *FIRMessagingCurrentAppVersion(void); FOUNDATION_EXPORT NSString *FIRMessagingAppIdentifier(void); +#pragma mark - Others + FOUNDATION_EXPORT uint64_t FIRMessagingGetFreeDiskSpaceInMB(void); +FOUNDATION_EXPORT UIApplication *FIRMessagingUIApplication(void); + diff --git a/Firebase/Messaging/FIRMessagingUtilities.m b/Firebase/Messaging/FIRMessagingUtilities.m index 60f3f28df5a..82ba1e2d2a0 100644 --- a/Firebase/Messaging/FIRMessagingUtilities.m +++ b/Firebase/Messaging/FIRMessagingUtilities.m @@ -20,6 +20,12 @@ #import "FIRMessagingLogger.h" +#ifdef COCOAPODS +#import +#else +#import "third_party/firebase/ios/Source/GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.h" +#endif + // Convert the macro to a string #define STR_EXPAND(x) #x #define STR(x) STR_EXPAND(x) @@ -171,3 +177,16 @@ uint64_t FIRMessagingGetFreeDiskSpaceInMB(void) { return 0; } } + +UIApplication *FIRMessagingUIApplication(void) { + static Class applicationClass = nil; + // iOS App extensions should not call [UIApplication sharedApplication], even if UIApplication + // responds to it. + if (![GULAppEnvironmentUtil isAppExtension]) { + Class cls = NSClassFromString(@"UIApplication"); + if (cls && [cls respondsToSelector:NSSelectorFromString(@"sharedApplication")]) { + applicationClass = cls; + } + } + return [applicationClass sharedApplication]; +} From 0b209d0b94ecb55d5c58593ab32a2f91c574ebee Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Fri, 6 Jul 2018 16:49:36 -0700 Subject: [PATCH 2/4] remove unnecessary converter --- Firebase/Messaging/FIRMessagingUtilities.m | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Firebase/Messaging/FIRMessagingUtilities.m b/Firebase/Messaging/FIRMessagingUtilities.m index 82ba1e2d2a0..fa3a2334b05 100644 --- a/Firebase/Messaging/FIRMessagingUtilities.m +++ b/Firebase/Messaging/FIRMessagingUtilities.m @@ -20,11 +20,7 @@ #import "FIRMessagingLogger.h" -#ifdef COCOAPODS #import -#else -#import "third_party/firebase/ios/Source/GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.h" -#endif // Convert the macro to a string #define STR_EXPAND(x) #x From 0ce3257990af53dc234bca6543d6b87a7368dc01 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Mon, 9 Jul 2018 12:50:53 -0700 Subject: [PATCH 3/4] Update FIRMessagingRemoteNotificationsProxy.m check the UIApplication is nil before swizzling --- Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.m b/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.m index 7adf076c0ba..7cea178edc8 100644 --- a/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.m +++ b/Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.m @@ -100,6 +100,9 @@ - (void)swizzleMethodsIfPossible { } UIApplication *application = FIRMessagingUIApplication(); + if (!application) { + return; + } NSObject *appDelegate = [application delegate]; [self swizzleAppDelegateMethods:appDelegate]; From f77115c073da002d4a4d1fe627576a53710d3a02 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Mon, 9 Jul 2018 13:51:19 -0700 Subject: [PATCH 4/4] add nil check of UIApplication for extension before proceed --- Firebase/Messaging/FIRMessaging.m | 6 ++++++ Firebase/Messaging/FIRMessagingContextManagerService.m | 3 +++ Firebase/Messaging/FIRMessagingReceiver.m | 3 +++ 3 files changed, 12 insertions(+) diff --git a/Firebase/Messaging/FIRMessaging.m b/Firebase/Messaging/FIRMessaging.m index bcc5e1415b7..a92f1851db6 100644 --- a/Firebase/Messaging/FIRMessaging.m +++ b/Firebase/Messaging/FIRMessaging.m @@ -379,6 +379,9 @@ - (void)handleIncomingLinkIfNeededFromMessage:(NSDictionary *)message { return; } UIApplication *application = FIRMessagingUIApplication(); + if (!application) { + return; + } id appDelegate = application.delegate; SEL continueUserActivitySelector = @selector(application:continueUserActivity:restorationHandler:); @@ -612,6 +615,9 @@ - (BOOL)shouldBeConnectedAutomatically { NSString *token = self.defaultFcmToken; // Only on foreground connections UIApplication *application = FIRMessagingUIApplication(); + if (!application) { + return NO; + } UIApplicationState applicationState = application.applicationState; BOOL shouldBeConnected = _shouldEstablishDirectChannel && (token.length > 0) && diff --git a/Firebase/Messaging/FIRMessagingContextManagerService.m b/Firebase/Messaging/FIRMessagingContextManagerService.m index bb39eaa652c..b4aac8b74bc 100644 --- a/Firebase/Messaging/FIRMessagingContextManagerService.m +++ b/Firebase/Messaging/FIRMessagingContextManagerService.m @@ -176,6 +176,9 @@ + (void)scheduleLocalNotificationForMessage:(NSDictionary *)message #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" UIApplication *application = FIRMessagingUIApplication(); + if (!application) { + return; + } [application scheduleLocalNotification:notification]; #pragma clang diagnostic pop } diff --git a/Firebase/Messaging/FIRMessagingReceiver.m b/Firebase/Messaging/FIRMessagingReceiver.m index 9ccb8cc0048..7567eda562f 100644 --- a/Firebase/Messaging/FIRMessagingReceiver.m +++ b/Firebase/Messaging/FIRMessagingReceiver.m @@ -113,6 +113,9 @@ - (void)scheduleNotificationForMessage:(NSDictionary *)message { dispatch_async(dispatch_get_main_queue(), ^{ UIApplication *application = FIRMessagingUIApplication(); + if (!application) { + return; + } id appDelegate = [application delegate]; if ([appDelegate respondsToSelector:newNotificationSelector]) { // Try the new remote notification callback