From 954e4d5df13b14aee9c1112db67a23729d12acfd Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Mon, 9 Jul 2018 14:33:41 -0700 Subject: avoid calling [UIApplication sharedApplication] in app extensions (#1503) --- Firebase/Messaging/FIRMessaging.m | 11 +++++++++-- .../Messaging/FIRMessagingContextManagerService.m | 7 ++++++- Firebase/Messaging/FIRMessagingReceiver.m | 19 ++++++++++++------- .../Messaging/FIRMessagingRemoteNotificationsProxy.m | 7 ++++++- Firebase/Messaging/FIRMessagingUtilities.h | 6 +++++- Firebase/Messaging/FIRMessagingUtilities.m | 15 +++++++++++++++ 6 files changed, 53 insertions(+), 12 deletions(-) diff --git a/Firebase/Messaging/FIRMessaging.m b/Firebase/Messaging/FIRMessaging.m index 5dd7004..a92f185 100644 --- a/Firebase/Messaging/FIRMessaging.m +++ b/Firebase/Messaging/FIRMessaging.m @@ -378,7 +378,10 @@ NSString *const kFIRMessagingPlistAutoInitEnabled = }); return; } - UIApplication *application = [UIApplication sharedApplication]; + UIApplication *application = FIRMessagingUIApplication(); + if (!application) { + return; + } id appDelegate = application.delegate; SEL continueUserActivitySelector = @selector(application:continueUserActivity:restorationHandler:); @@ -611,7 +614,11 @@ NSString *const kFIRMessagingPlistAutoInitEnabled = // We require a token from Instance ID NSString *token = self.defaultFcmToken; // Only on foreground connections - UIApplicationState applicationState = [UIApplication sharedApplication].applicationState; + UIApplication *application = FIRMessagingUIApplication(); + if (!application) { + return NO; + } + 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 f79e79c..b4aac8b 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,11 @@ typedef NS_ENUM(NSUInteger, FIRMessagingContextManagerMessageType) { } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - [[UIApplication sharedApplication] scheduleLocalNotification:notification]; + 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 981dfb1..7567eda 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,23 @@ static int downstreamMessageID = 0; SEL oldNotificationSelector = @selector(application:didReceiveRemoteNotification:); dispatch_async(dispatch_get_main_queue(), ^{ - id appDelegate = [[UIApplication sharedApplication] delegate]; + UIApplication *application = FIRMessagingUIApplication(); + if (!application) { + return; + } + 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 c5ad337..7cea178 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,11 @@ static NSString *kReceiveDataMessageSelectorString = @"messaging:didReceiveMessa return; } - NSObject *appDelegate = [[UIApplication sharedApplication] delegate]; + UIApplication *application = FIRMessagingUIApplication(); + if (!application) { + return; + } + 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 45770bf..206ff07 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 60f3f28..fa3a233 100644 --- a/Firebase/Messaging/FIRMessagingUtilities.m +++ b/Firebase/Messaging/FIRMessagingUtilities.m @@ -20,6 +20,8 @@ #import "FIRMessagingLogger.h" +#import + // Convert the macro to a string #define STR_EXPAND(x) #x #define STR(x) STR_EXPAND(x) @@ -171,3 +173,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]; +} -- cgit v1.2.3