diff --git a/README.md b/README.md index f0e2515a..ec9abd86 100644 --- a/README.md +++ b/README.md @@ -324,7 +324,8 @@ request is an object containing: - `body` : The message displayed in the notification alert. - `badge` The number to display as the app's icon badge. Setting the number to 0 removes the icon badge. - `fireDate` : The date and time when the system should deliver the notification. -- `repeats` : Sets notification to repeat daily. Must be used with fireDate. +- `repeats` : Sets notification to repeat. Must be used with fireDate and repeatsComponent. +- `repeatsComponent`: An object indicating which parts of fireDate should be repeated. - `sound` : The sound played when the notification is fired. - `category` : The category of this notification, required for actionable notifications. - `isSilent` : If true, the notification will appear without sound. @@ -332,6 +333,38 @@ request is an object containing: - `criticalSoundVolume` : A number between 0 and 1 for volume of critical notification. Default volume will be used if not specified. - `userInfo` : An object containing additional notification data. +request.repeatsComponent is an object containing (each field is optionnal): + +- `month`: Will repeat every selected month in your fireDate. +- `day`: Will repeat every selected day in your fireDate. +- `hour`: Will repeat every selected hour in your fireDate. +- `minute`: Will repeat every selected minute in your fireDate. +- `second`: Will repeat every selected second in your fireDate. +- `nanosecond`: Will repeat every selected nanosecond in your fireDate. + +For example, let’s say you want to have a notification repeating every day at 23:54, starting tomorrow, you will use something like this: + +```javascript +const getCorrectDate = () => { + const date = new Date(); + date.setDate(date.getDate() + 1); + date.setHours(23); + date.setMinutes(54); + return date; +}; + +PushNotificationIOS.addNotificationRequest({ + fireDate: getCorrectDate(), + repeats: true, + repeatsComponent: { + hour: true, + minute: true, + }, +}); +``` + +If you want to repeat every time the clock reach 54 minutes (like 00:54, 01:54, and so on), just switch hour to false. Every field is used to indicate at what time the notification should be repeated, exactly like you could do on iOS. + --- ### `setNotificationCategories()` diff --git a/ios/RCTConvert+Notification.m b/ios/RCTConvert+Notification.m index 9efb776a..08bfc2e9 100644 --- a/ios/RCTConvert+Notification.m +++ b/ios/RCTConvert+Notification.m @@ -93,18 +93,17 @@ @implementation RCTConvert (UNNotificationRequest) + (UNNotificationRequest *)UNNotificationRequest:(id)json { NSDictionary *details = [self NSDictionary:json]; - + BOOL isSilent = [RCTConvert BOOL:details[@"isSilent"]]; BOOL isCritical = [RCTConvert BOOL:details[@"isCritical"]]; float criticalSoundVolume = [RCTConvert float:details[@"criticalSoundVolume"]]; NSString* identifier = [RCTConvert NSString:details[@"id"]]; - - + UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init]; - content.title= [RCTConvert NSString:details[@"title"]]; - content.subtitle= [RCTConvert NSString:details[@"subtitle"]]; - content.body =[RCTConvert NSString:details[@"body"]]; - content.badge = [RCTConvert NSNumber:details[@"badge"]]; + content.title = [RCTConvert NSString:details[@"title"]]; + content.subtitle = [RCTConvert NSString:details[@"subtitle"]]; + content.body = [RCTConvert NSString:details[@"body"]]; + content.badge = [RCTConvert NSNumber:details[@"badge"]]; content.categoryIdentifier = [RCTConvert NSString:details[@"category"]]; NSString* threadIdentifier = [RCTConvert NSString:details[@"threadId"]]; @@ -112,6 +111,14 @@ + (UNNotificationRequest *)UNNotificationRequest:(id)json content.threadIdentifier = threadIdentifier; } + NSDictionary *userDateComps = [RCTConvert NSDictionary:details[@"repeatsComponent"]]; + BOOL month = [RCTConvert BOOL:userDateComps[@"month"]]; + BOOL day = [RCTConvert BOOL:userDateComps[@"day"]]; + BOOL hour = [RCTConvert BOOL:userDateComps[@"hour"]]; + BOOL minute = [RCTConvert BOOL:userDateComps[@"minute"]]; + BOOL second = [RCTConvert BOOL:userDateComps[@"second"]]; + BOOL nanosecond = [RCTConvert BOOL:userDateComps[@"nanosecond"]]; + content.userInfo = [RCTConvert NSDictionary:details[@"userInfo"]]; if (!isSilent) { if (isCritical) { @@ -122,18 +129,31 @@ + (UNNotificationRequest *)UNNotificationRequest:(id)json } } else { content.sound = [RCTConvert NSString:details[@"sound"]] ? [UNNotificationSound soundNamed:[RCTConvert NSString:details[@"sound"]]] : [UNNotificationSound defaultSound]; - } + }``` } NSDate* fireDate = [RCTConvert NSDate:details[@"fireDate"]]; BOOL repeats = [RCTConvert BOOL:details[@"repeats"]]; - NSDateComponents *triggerDate = fireDate ? [[NSCalendar currentCalendar] - components:NSCalendarUnitYear + - NSCalendarUnitMonth + NSCalendarUnitDay + - NSCalendarUnitHour + NSCalendarUnitMinute + - NSCalendarUnitSecond + NSCalendarUnitTimeZone - fromDate:fireDate] : nil; - + NSCalendarUnit defaultDateComponents = + NSCalendarUnitYear | + NSCalendarUnitMonth | + NSCalendarUnitDay | + NSCalendarUnitHour | + NSCalendarUnitMinute | + NSCalendarUnitSecond; + NSCalendarUnit repeatDateComponents = + (month ? NSCalendarUnitMonth : 0) | + (day ? NSCalendarUnitDay : 0) | + (hour ? NSCalendarUnitHour : 0) | + (minute ? NSCalendarUnitMinute : 0) | + (second ? NSCalendarUnitSecond : 0) | + (nanosecond ? NSCalendarUnitNanosecond : 0); + NSDateComponents *triggerDate = fireDate + ? [[NSCalendar currentCalendar] + components:(repeats ? repeatDateComponents : defaultDateComponents) | NSCalendarUnitTimeZone + fromDate:fireDate] + : nil; + UNCalendarNotificationTrigger* trigger = triggerDate ? [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:triggerDate repeats:repeats] : nil; UNNotificationRequest* notification = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger]; diff --git a/js/index.js b/js/index.js index 1d3ae7d0..b2cd9502 100644 --- a/js/index.js +++ b/js/index.js @@ -146,8 +146,12 @@ class PushNotificationIOS { request.fireDate instanceof Date ? {...request, fireDate: request.fireDate.toISOString()} : request; + const finalRequest = { + ...handledRequest, + repeatsComponent: request.repeatsComponent || {}, + }; - RNCPushNotificationIOS.addNotificationRequest(handledRequest); + RNCPushNotificationIOS.addNotificationRequest(finalRequest); } /** diff --git a/js/types.js b/js/types.js index 0e9a3b62..8248e665 100644 --- a/js/types.js +++ b/js/types.js @@ -45,6 +45,18 @@ export type NotificationRequest = {| * Must be used with fireDate. */ repeats?: boolean, + /** + * Define what components should be used in the fireDate during repeats. + * Must be used with repeats and fireDate. + */ + repeatsComponent?: { + month?: boolean, + day?: boolean, + hour?: boolean, + minute?: boolean, + second?: boolean, + nanosecond?: boolean, + }, /** * Sets notification to be silent */