diff options
author | Paul Beusterien <paulbeusterien@google.com> | 2017-05-15 12:27:07 -0700 |
---|---|---|
committer | Paul Beusterien <paulbeusterien@google.com> | 2017-05-15 12:27:07 -0700 |
commit | 98ba64449a632518bd2b86fe8d927f4a960d3ddc (patch) | |
tree | 131d9c4272fa6179fcda6c5a33fcb3b1bd57ad2e /Firebase/Messaging/FIRMessagingContextManagerService.m | |
parent | 32461366c9e204a527ca05e6e9b9404a2454ac51 (diff) |
Initial
Diffstat (limited to 'Firebase/Messaging/FIRMessagingContextManagerService.m')
-rw-r--r-- | Firebase/Messaging/FIRMessagingContextManagerService.m | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/Firebase/Messaging/FIRMessagingContextManagerService.m b/Firebase/Messaging/FIRMessagingContextManagerService.m new file mode 100644 index 0000000..1c9f653 --- /dev/null +++ b/Firebase/Messaging/FIRMessagingContextManagerService.m @@ -0,0 +1,189 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRMessagingContextManagerService.h" + +#import <UIKit/UIKit.h> + +#import "FIRMessagingDefines.h" +#import "FIRMessagingLogger.h" + +#define kFIRMessagingContextManagerPrefixKey @"google.c.cm." +#define kFIRMessagingContextManagerNotificationKeyPrefix @"gcm.notification." + +static NSString *const kLogTag = @"FIRMessagingAnalytics"; + +static NSString *const kLocalTimeFormatString = @"yyyy-MM-dd HH:mm:ss"; + +static NSString *const kContextManagerPrefixKey = kFIRMessagingContextManagerPrefixKey; + +// Local timed messages (format yyyy-mm-dd HH:mm:ss) +NSString *const kFIRMessagingContextManagerLocalTimeStart = kFIRMessagingContextManagerPrefixKey @"lt_start"; +NSString *const kFIRMessagingContextManagerLocalTimeEnd = kFIRMessagingContextManagerPrefixKey @"lt_end"; + +// Local Notification Params +NSString *const kFIRMessagingContextManagerBodyKey = kFIRMessagingContextManagerNotificationKeyPrefix @"body"; +NSString *const kFIRMessagingContextManagerTitleKey = kFIRMessagingContextManagerNotificationKeyPrefix @"title"; +NSString *const kFIRMessagingContextManagerBadgeKey = kFIRMessagingContextManagerNotificationKeyPrefix @"badge"; +NSString *const kFIRMessagingContextManagerCategoryKey = + kFIRMessagingContextManagerNotificationKeyPrefix @"click_action"; +NSString *const kFIRMessagingContextManagerSoundKey = kFIRMessagingContextManagerNotificationKeyPrefix @"sound"; +NSString *const kFIRMessagingContextManagerContentAvailableKey = + kFIRMessagingContextManagerNotificationKeyPrefix @"content-available"; + +typedef NS_ENUM(NSUInteger, FIRMessagingContextManagerMessageType) { + FIRMessagingContextManagerMessageTypeNone, + FIRMessagingContextManagerMessageTypeLocalTime, +}; + +@implementation FIRMessagingContextManagerService + ++ (BOOL)isContextManagerMessage:(NSDictionary *)message { + // For now we only support local time in ContextManager. + if (![message[kFIRMessagingContextManagerLocalTimeStart] length]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeContextManagerService000, + @"Received message missing local start time, dropped."); + return NO; + } + + return YES; +} + ++ (BOOL)handleContextManagerMessage:(NSDictionary *)message { + NSString *startTimeString = message[kFIRMessagingContextManagerLocalTimeStart]; + if (startTimeString.length) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeContextManagerService001, + @"%@ Received context manager message with local time %@", kLogTag, + startTimeString); + return [self handleContextManagerLocalTimeMessage:message]; + } + + return NO; +} + ++ (BOOL)handleContextManagerLocalTimeMessage:(NSDictionary *)message { + NSString *startTimeString = message[kFIRMessagingContextManagerLocalTimeStart]; + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateFormat:kLocalTimeFormatString]; + NSDate *startDate = [dateFormatter dateFromString:startTimeString]; + + _FIRMessagingDevAssert(startDate, @"Invalid local start date format %@", startTimeString); + if (!startTimeString) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeContextManagerService002, + @"Invalid local start date format %@. Message dropped", + startTimeString); + return NO; + } + + NSDate *currentDate = [NSDate date]; + + if ([currentDate compare:startDate] == NSOrderedAscending) { + [self scheduleLocalNotificationForMessage:message + atDate:startDate]; + } else { + // check end time has not passed + NSString *endTimeString = message[kFIRMessagingContextManagerLocalTimeEnd]; + if (!endTimeString) { + FIRMessagingLoggerInfo( + kFIRMessagingMessageCodeContextManagerService003, + @"No end date specified for message, start date elapsed. Message dropped."); + return YES; + } + + NSDate *endDate = [dateFormatter dateFromString:endTimeString]; + + _FIRMessagingDevAssert(endDate, @"Invalid local end date format %@", endTimeString); + if (!endTimeString) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeContextManagerService004, + @"Invalid local end date format %@. Message dropped", endTimeString); + return NO; + } + + if ([endDate compare:currentDate] == NSOrderedAscending) { + // end date has already passed drop the message + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeContextManagerService005, + @"End date %@ has already passed. Message dropped.", endTimeString); + return YES; + } + + // schedule message right now (buffer 10s) + [self scheduleLocalNotificationForMessage:message + atDate:[currentDate dateByAddingTimeInterval:10]]; + } + return YES; +} + ++ (void)scheduleLocalNotificationForMessage:(NSDictionary *)message + atDate:(NSDate *)date { + NSDictionary *apsDictionary = message; + UILocalNotification *notification = [[UILocalNotification alloc] init]; + + // A great way to understand timezones and UILocalNotifications + // http://stackoverflow.com/questions/18424569/understanding-uilocalnotification-timezone + notification.timeZone = [NSTimeZone defaultTimeZone]; + notification.fireDate = date; + + // In the current solution all of the display stuff goes into a special "aps" dictionary + // being sent in the message. + if ([apsDictionary[kFIRMessagingContextManagerBodyKey] length]) { + notification.alertBody = apsDictionary[kFIRMessagingContextManagerBodyKey]; + } + if ([apsDictionary[kFIRMessagingContextManagerTitleKey] length]) { + // |alertTitle| is iOS 8.2+, so check if we can set it + if ([notification respondsToSelector:@selector(setAlertTitle:)]) { + notification.alertTitle = apsDictionary[kFIRMessagingContextManagerTitleKey]; + } + } + + if (apsDictionary[kFIRMessagingContextManagerSoundKey]) { + notification.soundName = apsDictionary[kFIRMessagingContextManagerSoundKey]; + } + if (apsDictionary[kFIRMessagingContextManagerBadgeKey]) { + notification.applicationIconBadgeNumber = + [apsDictionary[kFIRMessagingContextManagerBadgeKey] integerValue]; + } + if (apsDictionary[kFIRMessagingContextManagerCategoryKey]) { + // |category| is iOS 8.0+, so check if we can set it + if ([notification respondsToSelector:@selector(setCategory:)]) { + notification.category = apsDictionary[kFIRMessagingContextManagerCategoryKey]; + } + } + + NSDictionary *userInfo = [self parseDataFromMessage:message]; + if (userInfo.count) { + notification.userInfo = userInfo; + } + + [[UIApplication sharedApplication] scheduleLocalNotification:notification]; +} + ++ (NSDictionary *)parseDataFromMessage:(NSDictionary *)message { + NSMutableDictionary *data = [NSMutableDictionary dictionary]; + for (NSObject<NSCopying> *key in message) { + if ([key isKindOfClass:[NSString class]]) { + NSString *keyString = (NSString *)key; + if ([keyString isEqualToString:kFIRMessagingContextManagerContentAvailableKey]) { + continue; + } else if ([keyString hasPrefix:kContextManagerPrefixKey]) { + continue; + } + } + data[[key copy]] = message[key]; + } + return [data copy]; +} + +@end |