-
Notifications
You must be signed in to change notification settings - Fork 1.7k
use UNNotificationRequest to schedule local notification for iOS 10 and above #5667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
b278dbd
47df7f5
d007376
c11f6da
f2b6935
2e6ab38
4983308
341e7a6
14c46cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,11 @@ | |
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 || \ | ||
| __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_14 || __TV_OS_VERSION_MAX_ALLOWED >= __TV_10_0 || \ | ||
| __WATCH_OS_VERSION_MAX_ALLOWED >= __WATCHOS_3_0 || TARGET_OS_MACCATALYST | ||
| #import <UserNotifications/UserNotifications.h> | ||
| #endif | ||
|
|
||
| #import "FirebaseMessaging/Sources/FIRMessagingContextManagerService.h" | ||
|
|
||
|
|
@@ -22,6 +27,7 @@ | |
|
|
||
| #import <GoogleUtilities/GULAppDelegateSwizzler.h> | ||
|
|
||
| #define kFIRMessagingContextManagerPrefix @"gcm." | ||
| #define kFIRMessagingContextManagerPrefixKey @"google.c.cm." | ||
| #define kFIRMessagingContextManagerNotificationKeyPrefix @"gcm.notification." | ||
|
|
||
|
|
@@ -50,6 +56,7 @@ | |
| kFIRMessagingContextManagerNotificationKeyPrefix @"sound"; | ||
| NSString *const kFIRMessagingContextManagerContentAvailableKey = | ||
| kFIRMessagingContextManagerNotificationKeyPrefix @"content-available"; | ||
| static NSString *const kFIRMessagingID = kFIRMessagingContextManagerPrefix @"message_id"; | ||
| static NSString *const kFIRMessagingAPNSPayloadKey = @"aps"; | ||
|
|
||
| typedef NS_ENUM(NSUInteger, FIRMessagingContextManagerMessageType) { | ||
|
|
@@ -129,7 +136,70 @@ + (BOOL)handleContextManagerLocalTimeMessage:(NSDictionary *)message { | |
| return YES; | ||
| } | ||
|
|
||
| + (void)scheduleiOS10LocalNotificationForMessage:(NSDictionary *)message atDate:(NSDate *)date { | ||
| NSCalendar *calendar = [NSCalendar currentCalendar]; | ||
| if (@available(macOS 10.14, iOS 10.0, watchOS 3.0, tvOS 10.0, *)) { | ||
| NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | | ||
| NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; | ||
| NSDateComponents *dateComponents = [calendar components:(NSCalendarUnit)unit fromDate:date]; | ||
| UNCalendarNotificationTrigger *trigger = | ||
| [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:dateComponents | ||
| repeats:YES]; | ||
|
|
||
| UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; | ||
| NSDictionary *apsDictionary = message; | ||
|
|
||
| // Badge is universal | ||
| if (apsDictionary[kFIRMessagingContextManagerBadgeKey]) { | ||
| content.badge = apsDictionary[kFIRMessagingContextManagerBadgeKey]; | ||
| } | ||
| #if TARGET_OS_IOS || TARGET_OS_OSX || TARGET_OS_WATCH | ||
| // The following fields are not available on tvOS | ||
| if ([apsDictionary[kFIRMessagingContextManagerBodyKey] length]) { | ||
| content.body = apsDictionary[kFIRMessagingContextManagerBodyKey]; | ||
| } | ||
| if ([apsDictionary[kFIRMessagingContextManagerTitleKey] length]) { | ||
| content.title = apsDictionary[kFIRMessagingContextManagerTitleKey]; | ||
| } | ||
|
|
||
| if (apsDictionary[kFIRMessagingContextManagerSoundKey]) { | ||
| content.sound = apsDictionary[kFIRMessagingContextManagerSoundKey]; | ||
| } | ||
|
|
||
| if (apsDictionary[kFIRMessagingContextManagerCategoryKey]) { | ||
| content.categoryIdentifier = apsDictionary[kFIRMessagingContextManagerCategoryKey]; | ||
| } | ||
|
|
||
| NSDictionary *userInfo = [self parseDataFromMessage:message]; | ||
| if (userInfo.count) { | ||
| content.userInfo = userInfo; | ||
| } | ||
| #endif | ||
| NSString *identifier = apsDictionary[kFIRMessagingID]; | ||
| if (!identifier) { | ||
| identifier = [NSUUID UUID].UUIDString; | ||
| } | ||
|
|
||
| UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier | ||
| content:content | ||
| trigger:trigger]; | ||
| UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; | ||
| [center addNotificationRequest:request | ||
| withCompletionHandler:^(NSError *_Nullable error) { | ||
| if (error) { | ||
| FIRMessagingLoggerError( | ||
| kFIRMessagingMessageCodeContextManagerServiceFailedLocalSchedule, | ||
| @"Failed scheduling local timezone notification: %@.", error); | ||
| } | ||
| }]; | ||
| } | ||
| } | ||
|
|
||
| + (void)scheduleLocalNotificationForMessage:(NSDictionary *)message atDate:(NSDate *)date { | ||
| if (@available(macOS 10.14, iOS 10.0, watchOS 3.0, tvOS 10.0, *)) { | ||
| [self scheduleiOS10LocalNotificationForMessage:message atDate:date]; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we need to make any validation of the date (e.g. if it is in the past or in a distant future)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do check it here: https://github.com/firebase/firebase-ios-sdk/blob/master/FirebaseMessaging/Sources/FIRMessagingContextManagerService.m#L99 And if it's very near future we schedule right away. |
||
| return; | ||
| } | ||
| #if TARGET_OS_IOS | ||
| NSDictionary *apsDictionary = message; | ||
| #pragma clang diagnostic push | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder why
repeatsisYES? It looks like it won't repeat any time soon with the specified calendar units (maybe in the next era maybe :) ).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. I think this should be no as backend every day will send a new scheduled notification. And client has no way to set when to end, so this should be a backend control thing. I will double test again today and tomorrow.