From 46a443b8f8d69f4a67d1eb08af73ff8922ac95f7 Mon Sep 17 00:00:00 2001 From: Lidan Hifi Date: Sat, 23 Apr 2016 11:46:25 +0300 Subject: [PATCH] fix background queue for notification actions and background notifications --- RNNotifications/RNNotifications.m | 83 +++++++++++-------- RNNotifications/RNNotificationsBridgeQueue.h | 10 ++- RNNotifications/RNNotificationsBridgeQueue.m | 81 ++++++++++++++++++ example/index.ios.js | 5 +- .../project.pbxproj | 52 ++++++------ .../ios/NotificationsExampleApp/AppDelegate.m | 2 +- index.ios.js | 8 +- test/index.ios.spec.js | 17 +++- 8 files changed, 186 insertions(+), 72 deletions(-) diff --git a/RNNotifications/RNNotifications.m b/RNNotifications/RNNotifications.m index 80a45c0..7f16b12 100644 --- a/RNNotifications/RNNotifications.m +++ b/RNNotifications/RNNotifications.m @@ -124,15 +124,6 @@ RCT_EXPORT_MODULE() selector:@selector(handleNotificationActionTriggered:) name:RNNotificationActionTriggered object:nil]; - - NSDictionary* lastActionInfo = [RNNotificationsBridgeQueue sharedInstance].lastAction; - if (lastActionInfo) { - [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationActionTriggered - object:self - userInfo:lastActionInfo]; - [RNNotificationsBridgeQueue sharedInstance].lastAction = nil; - } - } /* @@ -220,9 +211,14 @@ RCT_EXPORT_MODULE() } } - [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationReceivedBackground - object:self - userInfo:notification]; + // if Js thread is ready- post notification to bridge. otherwise- post it to the bridge queue + if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady == YES) { + [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationReceivedBackground + object:self + userInfo:notification]; + } else { + [[RNNotificationsBridgeQueue sharedInstance] postNotification:notification]; + } } + (void)didNotificationOpen:(NSDictionary *)notification @@ -300,17 +296,8 @@ RCT_EXPORT_MODULE() return [result copy]; } -+ (void)requestPermissionsWithCategories:(NSArray *)json ++ (void)requestPermissionsWithCategories:(NSMutableSet *)categories { - NSMutableSet* categories = nil; - - if ([json count] > 0) { - categories = [[NSMutableSet alloc] init]; - for (NSDictionary* categoryJson in json) { - [categories addObject:[RCTConvert UIMutableUserNotificationCategory:categoryJson]]; - } - } - UIUserNotificationType types = (UIUserNotificationType) (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert); UIUserNotificationSettings* settings = [UIUserNotificationSettings settingsForTypes:types categories:categories]; @@ -319,7 +306,8 @@ RCT_EXPORT_MODULE() + (void)emitNotificationActionForIdentifier:(NSString *)identifier responseInfo:(NSDictionary *)responseInfo userInfo:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler { - NSMutableDictionary* info = [[NSMutableDictionary alloc] initWithDictionary:@{ @"identifier": identifier }]; + NSString* completionKey = [NSString stringWithFormat:@"%@.%@", identifier, [NSString stringWithFormat:@"%d", (long)[[NSDate date] timeIntervalSince1970]]]; + NSMutableDictionary* info = [[NSMutableDictionary alloc] initWithDictionary:@{ @"identifier": identifier, @"completionKey": completionKey }]; // add text NSString* text = [responseInfo objectForKey:UIUserNotificationActionResponseTypedTextKey]; @@ -332,13 +320,14 @@ RCT_EXPORT_MODULE() info[@"notification"] = userInfo; } - // Emit event - [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationActionTriggered - object:self - userInfo:info]; + // Emit event to the queue (in order to store the completion handler). if JS thread is ready, post it also to the notification center (to the bridge). + [[RNNotificationsBridgeQueue sharedInstance] postAction:info withCompletionKey:completionKey andCompletionHandler:completionHandler]; - [RNNotificationsBridgeQueue sharedInstance].lastAction = info; - [RNNotificationsBridgeQueue sharedInstance].lastCompletionHandler = completionHandler; + if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady == YES) { + [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationActionTriggered + object:self + userInfo:info]; + } } + (void)registerPushKit @@ -401,7 +390,16 @@ RCT_EXPORT_MODULE() */ RCT_EXPORT_METHOD(requestPermissionsWithCategories:(NSArray *)json) { - [RNNotifications requestPermissionsWithCategories:json]; + NSMutableSet* categories = nil; + + if ([json count] > 0) { + categories = [[NSMutableSet alloc] init]; + for (NSDictionary* categoryJson in json) { + [categories addObject:[RCTConvert UIMutableUserNotificationCategory:categoryJson]]; + } + } + + [RNNotifications requestPermissionsWithCategories:categories]; } RCT_EXPORT_METHOD(log:(NSString *)message) @@ -409,13 +407,9 @@ RCT_EXPORT_METHOD(log:(NSString *)message) NSLog(message); } -RCT_EXPORT_METHOD(completionHandler) +RCT_EXPORT_METHOD(completionHandler:(NSString *)completionKey) { - void (^completionHandler)() = [RNNotificationsBridgeQueue sharedInstance].lastCompletionHandler; - if (completionHandler) { - completionHandler(); - [RNNotificationsBridgeQueue sharedInstance].lastCompletionHandler = nil; - } + [[RNNotificationsBridgeQueue sharedInstance] completeAction:completionKey]; } RCT_EXPORT_METHOD(abandonPermissions) @@ -434,4 +428,21 @@ RCT_EXPORT_METHOD(backgroundTimeRemaining:(RCTResponseSenderBlock)callback) callback(@[ [NSNumber numberWithDouble:remainingTime] ]); } +RCT_EXPORT_METHOD(consumeBackgroundQueue) +{ + [[RNNotificationsBridgeQueue sharedInstance] consumeActionsQueue:^(NSDictionary* action) { + [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationActionTriggered + object:self + userInfo:action]; + }]; + + [[RNNotificationsBridgeQueue sharedInstance] consumeNotificationsQueue:^(NSDictionary* notification) { + [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationReceivedBackground + object:self + userInfo:notification]; + }]; + + [RNNotificationsBridgeQueue sharedInstance].jsIsReady = YES; +} + @end diff --git a/RNNotifications/RNNotificationsBridgeQueue.h b/RNNotifications/RNNotificationsBridgeQueue.h index 6e0503e..0d3409d 100644 --- a/RNNotifications/RNNotificationsBridgeQueue.h +++ b/RNNotifications/RNNotificationsBridgeQueue.h @@ -2,9 +2,15 @@ @interface RNNotificationsBridgeQueue : NSObject -@property (nonatomic, retain) NSDictionary* lastAction; -@property (nonatomic, copy) void (^lastCompletionHandler)(); +@property BOOL jsIsReady; + (nonnull instancetype)sharedInstance; +- (void)postAction:(NSDictionary *)action withCompletionKey:(NSString *)completionKey andCompletionHandler:(void (^)())completionHandler; +- (void)postNotification:(NSDictionary *)notification; + +- (void)consumeActionsQueue:(void (^)(NSDictionary *))block; +- (void)consumeNotificationsQueue:(void (^)(NSDictionary *))block; + +- (void)completeAction:(NSString *)completionKey; @end \ No newline at end of file diff --git a/RNNotifications/RNNotificationsBridgeQueue.m b/RNNotifications/RNNotificationsBridgeQueue.m index 5167f97..90960f2 100644 --- a/RNNotifications/RNNotificationsBridgeQueue.m +++ b/RNNotifications/RNNotificationsBridgeQueue.m @@ -2,6 +2,10 @@ @implementation RNNotificationsBridgeQueue +NSMutableArray* actionsQueue; +NSMutableArray* backgroundNotificationsQueue; +NSMutableDictionary* actionCompletionHandlers; + + (nonnull instancetype)sharedInstance { static RNNotificationsBridgeQueue* sharedInstance = nil; static dispatch_once_t onceToken; @@ -11,4 +15,81 @@ return sharedInstance; } + +- (instancetype)init +{ + actionsQueue = [NSMutableArray new]; + backgroundNotificationsQueue = [NSMutableArray new]; + actionCompletionHandlers = [NSMutableDictionary new]; + self.jsIsReady = NO; + + return self; +} + +- (void)postNotification:(NSDictionary *)notification +{ + if (!backgroundNotificationsQueue) return; + [backgroundNotificationsQueue insertObject:notification atIndex:0]; +} + +- (NSDictionary *)dequeueSingleNotification +{ + if (!backgroundNotificationsQueue || backgroundNotificationsQueue.count == 0) return nil; + + NSDictionary* notification = [backgroundNotificationsQueue lastObject]; + [backgroundNotificationsQueue removeLastObject]; + + return notification; +} + +- (void)consumeNotificationsQueue:(void (^)(NSDictionary *))block +{ + NSDictionary* notification; + + while ((notification = [self dequeueSingleNotification]) != nil) { + block(notification); + } + + backgroundNotificationsQueue = nil; +} + +- (void)postAction:(NSDictionary *)action withCompletionKey:(NSString *)completionKey andCompletionHandler:(void (^)())completionHandler +{ + // store completion handler + actionCompletionHandlers[completionKey] = completionHandler; + + if (!actionsQueue) return; + [actionsQueue insertObject:action atIndex:0]; +} + +- (NSDictionary *)dequeueSingleAction +{ + if (!actionsQueue || actionsQueue.count == 0) return nil; + + NSDictionary* action = [actionsQueue lastObject]; + [actionsQueue removeLastObject]; + + return action; +} + +- (void)consumeActionsQueue:(void (^)(NSDictionary *))block +{ + NSDictionary* lastActionInfo; + + while ((lastActionInfo = [self dequeueSingleAction]) != nil) { + block(lastActionInfo); + } + + actionsQueue = nil; +} + +- (void)completeAction:(NSString *)completionKey +{ + void (^completionHandler)() = (void (^)())[actionCompletionHandlers valueForKey:completionKey]; + if (completionHandler) { + completionHandler(); + [actionCompletionHandlers removeObjectForKey:completionKey]; + } +} + @end \ No newline at end of file diff --git a/example/index.ios.js b/example/index.ios.js index 95fc1f3..9abdb82 100644 --- a/example/index.ios.js +++ b/example/index.ios.js @@ -50,6 +50,8 @@ class NotificationsExampleApp extends Component { NotificationsIOS.addEventListener('remoteNotificationsRegistered', this.onPushRegistered.bind(this)); NotificationsIOS.requestPermissions([cat]); + NotificationsIOS.consumeBackgroundQueue(); + NotificationsIOS.addEventListener('pushKitRegistered', this.onPushKitRegistered.bind(this)); NotificationsIOS.registerPushKit(); @@ -73,8 +75,7 @@ class NotificationsExampleApp extends Component { onNotificationReceivedBackground(notification) { NotificationsIOS.log("Notification Received Background: " + JSON.stringify(notification)); - NotificationsIOS.backgroundTimeRemaining(time => NotificationsIOS.log("remaining background time: " + time)); - + // NotificationsIOS.backgroundTimeRemaining(time => NotificationsIOS.log("remaining background time: " + time)); } onNotificationOpened(notification) { diff --git a/example/ios/NotificationsExampleApp.xcodeproj/project.pbxproj b/example/ios/NotificationsExampleApp.xcodeproj/project.pbxproj index 6c548c4..2480ea9 100644 --- a/example/ios/NotificationsExampleApp.xcodeproj/project.pbxproj +++ b/example/ios/NotificationsExampleApp.xcodeproj/project.pbxproj @@ -17,14 +17,13 @@ 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; - D86588561CA2F4EF0076A9C8 /* libRCTPushNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D86588551CA2F49C0076A9C8 /* libRCTPushNotification.a */; }; + D85193341CCB6C8F008B3C99 /* libRNNotifications.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D85193331CCB6C82008B3C99 /* libRNNotifications.a */; }; D892FB7C1CB5AD7600B2CCF9 /* SmartNotificationsAppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D892FB7B1CB5AD7600B2CCF9 /* SmartNotificationsAppTests.m */; }; D89EF3AC1CB586FE0029DCD6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D89EF3A71CB586FE0029DCD6 /* AppDelegate.m */; }; D89EF3AD1CB586FE0029DCD6 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D89EF3A91CB586FE0029DCD6 /* Images.xcassets */; }; D89EF3AE1CB586FE0029DCD6 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = D89EF3AA1CB586FE0029DCD6 /* Info.plist */; }; D89EF3AF1CB586FE0029DCD6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D89EF3AB1CB586FE0029DCD6 /* main.m */; }; D89EF3BE1CB5871B0029DCD6 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = D89EF3BC1CB5871B0029DCD6 /* LaunchScreen.xib */; }; - D8CDE9D11CB588F000DC8E35 /* libRNNotifications.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D8CDE9D01CB588CF00DC8E35 /* libRNNotifications.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -105,19 +104,19 @@ remoteGlobalIDString = 58B5119B1A9E6C1200147676; remoteInfo = RCTText; }; - D86588541CA2F49C0076A9C8 /* PBXContainerItemProxy */ = { + D85193321CCB6C82008B3C99 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = D86588501CA2F49C0076A9C8 /* RCTPushNotification.xcodeproj */; + containerPortal = D851932E1CCB6C82008B3C99 /* RNNotifications.xcodeproj */; proxyType = 2; remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTPushNotification; + remoteInfo = RNNotifications; }; - D8CDE9CF1CB588CF00DC8E35 /* PBXContainerItemProxy */ = { + D86588541CA2F49C0076A9C8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = D8CDE9CB1CB588CF00DC8E35 /* RNNotifications.xcodeproj */; + containerPortal = D86588501CA2F49C0076A9C8 /* RCTPushNotification.xcodeproj */; proxyType = 2; remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RNNotifications; + remoteInfo = RCTPushNotification; }; /* End PBXContainerItemProxy section */ @@ -135,6 +134,7 @@ 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; + D851932E1CCB6C82008B3C99 /* RNNotifications.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNNotifications.xcodeproj; path = ../../RNNotifications/RNNotifications.xcodeproj; sourceTree = ""; }; D86588501CA2F49C0076A9C8 /* RCTPushNotification.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTPushNotification.xcodeproj; path = "../node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj"; sourceTree = ""; }; D892FB7B1CB5AD7600B2CCF9 /* SmartNotificationsAppTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SmartNotificationsAppTests.m; sourceTree = ""; }; D89EF3A71CB586FE0029DCD6 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = NotificationsExampleApp/AppDelegate.m; sourceTree = ""; }; @@ -143,7 +143,6 @@ D89EF3AA1CB586FE0029DCD6 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = NotificationsExampleApp/Info.plist; sourceTree = ""; }; D89EF3AB1CB586FE0029DCD6 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = NotificationsExampleApp/main.m; sourceTree = ""; }; D89EF3BD1CB5871B0029DCD6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = NotificationsExampleApp/Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - D8CDE9CB1CB588CF00DC8E35 /* RNNotifications.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNNotifications.xcodeproj; path = "../node_modules/react-native-notifications/RNNotifications/RNNotifications.xcodeproj"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -158,8 +157,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D8CDE9D11CB588F000DC8E35 /* libRNNotifications.a in Frameworks */, - D86588561CA2F4EF0076A9C8 /* libRCTPushNotification.a in Frameworks */, + D85193341CCB6C8F008B3C99 /* libRNNotifications.a in Frameworks */, 146834051AC3E58100842450 /* libReact.a in Frameworks */, 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, @@ -281,7 +279,7 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( - D8CDE9CB1CB588CF00DC8E35 /* RNNotifications.xcodeproj */, + D851932E1CCB6C82008B3C99 /* RNNotifications.xcodeproj */, D86588501CA2F49C0076A9C8 /* RCTPushNotification.xcodeproj */, 146833FF1AC3E56700842450 /* React.xcodeproj */, 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, @@ -326,18 +324,18 @@ name = Products; sourceTree = ""; }; - D86588511CA2F49C0076A9C8 /* Products */ = { + D851932F1CCB6C82008B3C99 /* Products */ = { isa = PBXGroup; children = ( - D86588551CA2F49C0076A9C8 /* libRCTPushNotification.a */, + D85193331CCB6C82008B3C99 /* libRNNotifications.a */, ); name = Products; sourceTree = ""; }; - D8CDE9CC1CB588CF00DC8E35 /* Products */ = { + D86588511CA2F49C0076A9C8 /* Products */ = { isa = PBXGroup; children = ( - D8CDE9D01CB588CF00DC8E35 /* libRNNotifications.a */, + D86588551CA2F49C0076A9C8 /* libRCTPushNotification.a */, ); name = Products; sourceTree = ""; @@ -461,8 +459,8 @@ ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; }, { - ProductGroup = D8CDE9CC1CB588CF00DC8E35 /* Products */; - ProjectRef = D8CDE9CB1CB588CF00DC8E35 /* RNNotifications.xcodeproj */; + ProductGroup = D851932F1CCB6C82008B3C99 /* Products */; + ProjectRef = D851932E1CCB6C82008B3C99 /* RNNotifications.xcodeproj */; }, ); projectRoot = ""; @@ -544,18 +542,18 @@ remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - D86588551CA2F49C0076A9C8 /* libRCTPushNotification.a */ = { + D85193331CCB6C82008B3C99 /* libRNNotifications.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; - path = libRCTPushNotification.a; - remoteRef = D86588541CA2F49C0076A9C8 /* PBXContainerItemProxy */; + path = libRNNotifications.a; + remoteRef = D85193321CCB6C82008B3C99 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - D8CDE9D01CB588CF00DC8E35 /* libRNNotifications.a */ = { + D86588551CA2F49C0076A9C8 /* libRCTPushNotification.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; - path = libRNNotifications.a; - remoteRef = D8CDE9CF1CB588CF00DC8E35 /* PBXContainerItemProxy */; + path = libRCTPushNotification.a; + remoteRef = D86588541CA2F49C0076A9C8 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXReferenceProxy section */ @@ -686,8 +684,7 @@ "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../node_modules/react-native/React/**", - "$(SRCROOT)/../node_modules/react-native/Libraries/PushNotificationIOS/**", - "$(SRCROOT)/../node_modules/react-native-notifications/RNNotifications/**", + "$(SRCROOT)/../../RNNotifications/**", ); INFOPLIST_FILE = NotificationsExampleApp/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -706,8 +703,7 @@ "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../node_modules/react-native/React/**", - "$(SRCROOT)/../node_modules/react-native/Libraries/PushNotificationIOS/**", - "$(SRCROOT)/../node_modules/react-native-notifications/RNNotifications/**", + "$(SRCROOT)/../../RNNotifications/**", ); INFOPLIST_FILE = NotificationsExampleApp/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; diff --git a/example/ios/NotificationsExampleApp/AppDelegate.m b/example/ios/NotificationsExampleApp/AppDelegate.m index 4286d2f..18a646a 100644 --- a/example/ios/NotificationsExampleApp/AppDelegate.m +++ b/example/ios/NotificationsExampleApp/AppDelegate.m @@ -33,7 +33,7 @@ * on the same Wi-Fi network. */ - jsCodeLocation = [NSURL URLWithString:@"http://172.31.8.67:8081/index.ios.bundle?platform=ios&dev=true"]; + jsCodeLocation = [NSURL URLWithString:@"http://192.168.1.15:8081/index.ios.bundle?platform=ios&dev=true"]; /** * OPTION 2 diff --git a/index.ios.js b/index.ios.js index c99ae9c..d9c8377 100644 --- a/index.ios.js +++ b/index.ios.js @@ -99,7 +99,9 @@ export default class NotificationsIOS { if (actionHandler) { action.notification = new IOSNotification(action.notification); - actionHandler(action, () => { NativeRNNotifications.completionHandler(); }); + actionHandler(action, () => { + NativeRNNotifications.completionHandler(action.completionKey); + }); } } @@ -155,6 +157,10 @@ export default class NotificationsIOS { NativeRNNotifications.backgroundTimeRemaining(callback); } + static consumeBackgroundQueue() { + NativeRNNotifications.consumeBackgroundQueue(); + } + static log(message) { NativeRNNotifications.log(message); } diff --git a/test/index.ios.spec.js b/test/index.ios.spec.js index e6eeb4d..9b1cb54 100644 --- a/test/index.ios.spec.js +++ b/test/index.ios.spec.js @@ -22,7 +22,8 @@ describe("NotificationsIOS", () => { nativeRequestPermissionsWithCategories, nativeAbandonPermissions, nativeRegisterPushKit, - nativeBackgroundTimeRemaining; + nativeBackgroundTimeRemaining, + nativeConsumeBackgroundQueue; let NotificationsIOS, NotificationAction, NotificationCategory; let someHandler = () => {}; /*eslint-enable indent*/ @@ -36,6 +37,7 @@ describe("NotificationsIOS", () => { nativeAbandonPermissions = sinon.spy(); nativeRegisterPushKit = sinon.spy(); nativeBackgroundTimeRemaining = sinon.spy(); + nativeConsumeBackgroundQueue = sinon.spy(); let libUnderTest = proxyquire("../index.ios", { "react-native": { @@ -44,7 +46,8 @@ describe("NotificationsIOS", () => { requestPermissionsWithCategories: nativeRequestPermissionsWithCategories, abandonPermissions: nativeAbandonPermissions, registerPushKit: nativeRegisterPushKit, - backgroundTimeRemaining: nativeBackgroundTimeRemaining + backgroundTimeRemaining: nativeBackgroundTimeRemaining, + consumeBackgroundQueue: nativeConsumeBackgroundQueue } }, NativeAppEventEmitter: { @@ -79,6 +82,7 @@ describe("NotificationsIOS", () => { nativeAbandonPermissions.reset(); nativeRegisterPushKit.reset(); nativeBackgroundTimeRemaining.reset(); + nativeConsumeBackgroundQueue.reset(); }); after(() => { @@ -90,6 +94,7 @@ describe("NotificationsIOS", () => { nativeAbandonPermissions = null; nativeRegisterPushKit = null; nativeBackgroundTimeRemaining = null; + nativeConsumeBackgroundQueue = null; NotificationsIOS = null; NotificationAction = null; @@ -210,4 +215,12 @@ describe("NotificationsIOS", () => { expect(nativeBackgroundTimeRemaining).to.have.been.calledWith(someCallback); }); }); + + describe("Get background remaining time", () => { + it("should call native consume background queue method", () => { + NotificationsIOS.consumeBackgroundQueue(); + + expect(nativeConsumeBackgroundQueue).to.have.been.called; + }); + }); }); -- 2.26.2