From c5d456a84ddbddd5b0143f3b37a90fef2816ec9c Mon Sep 17 00:00:00 2001 From: Ben Lei Date: Thu, 5 Jan 2017 15:08:04 +0800 Subject: [PATCH 1/4] Attach bundle identifier when register device --- Example/Podfile.lock | 10 +++++----- .../Tests/SKYRegisterDeviceOperationTests.m | 20 +++++++++++++------ .../Operations/SKYRegisterDeviceOperation.h | 9 +++++++-- .../Operations/SKYRegisterDeviceOperation.m | 18 ++++++++++++++++- Pod/Classes/SKYContainer.m | 3 ++- 5 files changed, 45 insertions(+), 15 deletions(-) diff --git a/Example/Podfile.lock b/Example/Podfile.lock index b187674..66c6a8c 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -25,12 +25,12 @@ PODS: - OHHTTPStubs/NSURLSession (4.6.0): - OHHTTPStubs/Core - OHHTTPStubs/OHPathHelpers (4.6.0) - - SKYKit (0.19.0): - - SKYKit/Core (= 0.19.0) - - SKYKit/Core (0.19.0): + - SKYKit (0.20.0): + - SKYKit/Core (= 0.20.0) + - SKYKit/Core (0.20.0): - FMDB (~> 2.5) - SocketRocket (~> 0.4) - - SKYKit/Facebook (0.19.0): + - SKYKit/Facebook (0.20.0): - FBSDKCoreKit (~> 4.0) - SKYKit/Core - SocketRocket (0.5.1) @@ -55,7 +55,7 @@ SPEC CHECKSUMS: FMDB: 854a0341b4726e53276f2a8996f06f1b80f9259a OCMock: 28def049ef47f996b515a8eeea958be7ccab2dbb OHHTTPStubs: cb1aefbbeb4de4e741644455d4b945538e5248a2 - SKYKit: 14d7ffed0350e0ca95aa60c76f2aaa5d7bbb24d2 + SKYKit: 0639950ad14f99cdfe5a4013de4ae69993d83aa8 SocketRocket: d57c7159b83c3c6655745cd15302aa24b6bae531 Specta: ac94d110b865115fe60ff2c6d7281053c6f8e8a2 diff --git a/Example/Tests/SKYRegisterDeviceOperationTests.m b/Example/Tests/SKYRegisterDeviceOperationTests.m index ef94336..01f3692 100644 --- a/Example/Tests/SKYRegisterDeviceOperationTests.m +++ b/Example/Tests/SKYRegisterDeviceOperationTests.m @@ -36,7 +36,8 @@ it(@"new device request", ^{ SKYRegisterDeviceOperation *operation = [SKYRegisterDeviceOperation - operationWithDeviceToken:[SKYHexer dataWithHexString:@"abcdef1234567890"]]; + operationWithDeviceToken:[SKYHexer dataWithHexString:@"abcdef1234567890"] + topic:@"com.example.app"]; operation.container = container; [operation prepareForRequest]; @@ -47,11 +48,12 @@ expect(request.payload[@"type"]).to.equal(@"ios"); expect(request.payload[@"device_token"]).to.equal(@"abcdef1234567890"); expect(request.payload[@"id"]).to.beNil(); + expect(request.payload[@"topic"]).to.equal(@"com.example.app"); }); it(@"new device request without device token", ^{ SKYRegisterDeviceOperation *operation = - [SKYRegisterDeviceOperation operationWithDeviceToken:nil]; + [SKYRegisterDeviceOperation operationWithDeviceToken:nil topic:@"com.example.app"]; operation.container = container; [operation prepareForRequest]; @@ -62,11 +64,13 @@ expect(request.payload[@"type"]).to.equal(@"ios"); expect(request.payload[@"device_token"]).to.beNil(); expect(request.payload[@"id"]).to.beNil(); + expect(request.payload[@"topic"]).to.equal(@"com.example.app"); }); it(@"update device request", ^{ SKYRegisterDeviceOperation *operation = [SKYRegisterDeviceOperation - operationWithDeviceToken:[SKYHexer dataWithHexString:@"abcdef1234567890"]]; + operationWithDeviceToken:[SKYHexer dataWithHexString:@"abcdef1234567890"] + topic:@"com.example.app"]; operation.deviceID = @"DEVICE_ID"; operation.container = container; [operation prepareForRequest]; @@ -78,11 +82,13 @@ expect(request.payload[@"type"]).to.equal(@"ios"); expect(request.payload[@"device_token"]).to.equal(@"abcdef1234567890"); expect(request.payload[@"id"]).to.equal(@"DEVICE_ID"); + expect(request.payload[@"topic"]).to.equal(@"com.example.app"); }); it(@"new device response", ^{ SKYRegisterDeviceOperation *operation = [SKYRegisterDeviceOperation - operationWithDeviceToken:[SKYHexer dataWithHexString:@"abcdef1234567890"]]; + operationWithDeviceToken:[SKYHexer dataWithHexString:@"abcdef1234567890"] + topic:@"com.example.app"]; [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { return YES; @@ -113,7 +119,8 @@ it(@"error with response without id", ^{ SKYRegisterDeviceOperation *operation = [SKYRegisterDeviceOperation - operationWithDeviceToken:[SKYHexer dataWithHexString:@"abcdef1234567890"]]; + operationWithDeviceToken:[SKYHexer dataWithHexString:@"abcdef1234567890"] + topic:@"com.example.app"]; [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { return YES; @@ -142,7 +149,8 @@ it(@"pass error", ^{ SKYRegisterDeviceOperation *operation = [SKYRegisterDeviceOperation - operationWithDeviceToken:[SKYHexer dataWithHexString:@"abcdef1234567890"]]; + operationWithDeviceToken:[SKYHexer dataWithHexString:@"abcdef1234567890"] + topic:@"com.example.app"]; [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { return YES; } diff --git a/Pod/Classes/Operations/SKYRegisterDeviceOperation.h b/Pod/Classes/Operations/SKYRegisterDeviceOperation.h index b25f0b1..47c9859 100644 --- a/Pod/Classes/Operations/SKYRegisterDeviceOperation.h +++ b/Pod/Classes/Operations/SKYRegisterDeviceOperation.h @@ -22,7 +22,9 @@ @interface SKYRegisterDeviceOperation : SKYOperation -- (instancetype)initWithDeviceToken:(NSData *)deviceToken; +- (instancetype)initWithDeviceToken:(NSData *)deviceToken + __attribute__((deprecated("Use -(void)initWithDeviceToken:topic: instead"))); +- (instancetype)initWithDeviceToken:(NSData *)deviceToken topic:(NSString *)topic; /** Returns an instance of operation that registers a device without supplying a device token. @@ -32,9 +34,12 @@ instead of remote notification. */ + (instancetype)operation; -+ (instancetype)operationWithDeviceToken:(NSData *)deviceToken; ++ (instancetype)operationWithDeviceToken:(NSData *)deviceToken + __attribute__((deprecated("Use +(instancetype)operationWithDeviceToken:topic: instead"))); ++ (instancetype)operationWithDeviceToken:(NSData *)topic topic:(NSString *)topic; @property (nonatomic, readonly, copy) NSData *deviceToken; +@property (nonatomic, readonly, copy) NSString *topic; @property (nonatomic, readwrite, copy) NSString *deviceID; @property (nonatomic, copy) void (^registerCompletionBlock)(NSString *deviceID, NSError *error); diff --git a/Pod/Classes/Operations/SKYRegisterDeviceOperation.m b/Pod/Classes/Operations/SKYRegisterDeviceOperation.m index f9136d7..f700ea1 100644 --- a/Pod/Classes/Operations/SKYRegisterDeviceOperation.m +++ b/Pod/Classes/Operations/SKYRegisterDeviceOperation.m @@ -29,16 +29,22 @@ @interface SKYRegisterDeviceOperation () @implementation SKYRegisterDeviceOperation -- (instancetype)initWithDeviceToken:(NSData *)deviceToken +- (instancetype)initWithDeviceToken:(NSData *)deviceToken topic:(NSString *)topic { self = [super init]; if (self) { _deviceToken = [deviceToken copy]; + _topic = [topic copy]; _deviceID = nil; } return self; } +- (instancetype)initWithDeviceToken:(NSData *)deviceToken +{ + return [self initWithDeviceToken:deviceToken topic:nil]; +} + + (instancetype)operation { return [[self alloc] initWithDeviceToken:nil]; @@ -49,6 +55,11 @@ + (instancetype)operationWithDeviceToken:(NSData *)deviceToken return [[self alloc] initWithDeviceToken:deviceToken]; } ++ (instancetype)operationWithDeviceToken:(NSData *)deviceToken topic:(NSString *)topic +{ + return [[self alloc] initWithDeviceToken:deviceToken topic:topic]; +} + - (NSString *)hexDeviceToken { if (!self.deviceToken) { @@ -80,6 +91,11 @@ - (void)prepareForRequest payload[@"device_token"] = deviceToken; } + NSString *topic = self.topic; + if (topic.length) { + payload[@"topic"] = topic; + } + NSString *deviceID = self.deviceID; if (deviceID.length) { payload[@"id"] = deviceID; diff --git a/Pod/Classes/SKYContainer.m b/Pod/Classes/SKYContainer.m index 27c63ea..3bf797a 100644 --- a/Pod/Classes/SKYContainer.m +++ b/Pod/Classes/SKYContainer.m @@ -593,8 +593,9 @@ - (void)registerRemoteNotificationDeviceToken:(NSData *)deviceToken existingDeviceID:(NSString *)existingDeviceID completionHandler:(void (^)(NSString *, NSError *))completionHandler { + NSString *topic = [[NSBundle mainBundle] bundleIdentifier]; SKYRegisterDeviceOperation *op = - [[SKYRegisterDeviceOperation alloc] initWithDeviceToken:deviceToken]; + [[SKYRegisterDeviceOperation alloc] initWithDeviceToken:deviceToken topic:topic]; op.deviceID = existingDeviceID; op.registerCompletionBlock = ^(NSString *deviceID, NSError *error) { BOOL willRetry = NO; From a2f92e3199f6bf353e80cdde76ffc0784f563c19 Mon Sep 17 00:00:00 2001 From: Ben Lei Date: Thu, 5 Jan 2017 16:43:04 +0800 Subject: [PATCH 2/4] Add device registration to example project --- Example/Swift Example/AppDelegate.swift | 48 +++++++++++++++++-------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/Example/Swift Example/AppDelegate.swift b/Example/Swift Example/AppDelegate.swift index c1fc9ea..5dae21f 100644 --- a/Example/Swift Example/AppDelegate.swift +++ b/Example/Swift Example/AppDelegate.swift @@ -36,28 +36,48 @@ class AppDelegate: UIResponder, UIApplicationDelegate { if let apiKeyValue = apiKey { SKYContainer.defaultContainer().configureWithAPIKey(apiKeyValue) } + + application.registerUserNotificationSettings(UIUserNotificationSettings( + forTypes: [.Alert, .Badge, .Sound], + categories: nil + )) + return true } - func applicationWillResignActive(application: UIApplication) { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. - } + func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) { + guard !notificationSettings.types.isEmpty else { + print("User does not allow notification") + return + } - func applicationDidEnterBackground(application: UIApplication) { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + application.registerForRemoteNotifications() } - func applicationWillEnterForeground(application: UIApplication) { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. - } + func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) { + print("Successfully registered remote notification") - func applicationDidBecomeActive(application: UIApplication) { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + let skygear = SKYContainer.defaultContainer() + guard skygear.currentUser != nil else { + print("User not yet login, abort registering device") + return + } + + skygear.registerRemoteNotificationDeviceToken(deviceToken) { (deviceID, error) in + guard error == nil else { + print("Failed to register device: \(error.localizedDescription)") + return + } + + if let id = deviceID { + print("Successfully registered device with ID: \(id)") + } else { + print("Warning: Got nil device ID") + } + } } - func applicationWillTerminate(application: UIApplication) { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) { + print("Failed to register remote notification: \(error.localizedDescription)") } } From 6781ee8ff07c0e2bf9c489c0397526bdc4897906 Mon Sep 17 00:00:00 2001 From: Ben Lei Date: Thu, 5 Jan 2017 16:57:53 +0800 Subject: [PATCH 3/4] Enable sending push notification by topic --- .../SKYSendPushNotificationOperationTests.m | 19 +++++++ .../SKYSendPushNotificationOperation.h | 22 ++++++-- .../SKYSendPushNotificationOperation.m | 51 ++++++++++++++++--- 3 files changed, 83 insertions(+), 9 deletions(-) diff --git a/Example/Tests/SKYSendPushNotificationOperationTests.m b/Example/Tests/SKYSendPushNotificationOperationTests.m index b57ae89..a3758fc 100644 --- a/Example/Tests/SKYSendPushNotificationOperationTests.m +++ b/Example/Tests/SKYSendPushNotificationOperationTests.m @@ -98,6 +98,25 @@ }); }); + it(@"topic", ^{ + SKYSendPushNotificationOperation *operation = [SKYSendPushNotificationOperation + operationWithNotificationInfo:notificationInfo + userIDsToSend:@[ @"johndoe" ] + topic:@"io.skygear.example"]; + operation.container = container; + [operation prepareForRequest]; + + SKYRequest *request = operation.request; + expect([request class]).to.beSubclassOf([SKYRequest class]); + expect(request.APIKey).to.equal(container.APIKey); + expect(request.action).to.equal(@"push:user"); + expect(request.payload).to.equal(@{ + @"user_ids" : @[ @"johndoe" ], + @"notification" : expectedNotificationPayload, + @"topic" : @"io.skygear.example" + }); + }); + it(@"make request", ^{ SKYSendPushNotificationOperation *operation = [SKYSendPushNotificationOperation operationWithNotificationInfo:notificationInfo diff --git a/Pod/Classes/Operations/SKYSendPushNotificationOperation.h b/Pod/Classes/Operations/SKYSendPushNotificationOperation.h index 7817ecc..fecb2be 100644 --- a/Pod/Classes/Operations/SKYSendPushNotificationOperation.h +++ b/Pod/Classes/Operations/SKYSendPushNotificationOperation.h @@ -29,17 +29,33 @@ typedef enum : NSUInteger { @interface SKYSendPushNotificationOperation : SKYOperation -- (instancetype)initWithNotificationInfo:(SKYNotificationInfo *)noteInfo +- (instancetype)initWithNotificationInfo:(SKYNotificationInfo *)notificationInfo pushTarget:(SKYPushTarget)pushTarget IDsToSend:(NSArray *)IDsToSend; -+ (instancetype)operationWithNotificationInfo:(SKYNotificationInfo *)noteInfo + +- (instancetype)initWithNotificationInfo:(SKYNotificationInfo *)notificationInfo + pushTarget:(SKYPushTarget)pushTarget + IDsToSend:(NSArray *)IDsToSend + topic:(NSString *)topic; + ++ (instancetype)operationWithNotificationInfo:(SKYNotificationInfo *)notificationInfo userIDsToSend:(NSArray *)userIDsToSend; -+ (instancetype)operationWithNotificationInfo:(SKYNotificationInfo *)noteInfo + ++ (instancetype)operationWithNotificationInfo:(SKYNotificationInfo *)notificationInfo + userIDsToSend:(NSArray *)userIDsToSend + topic:(NSString *)topic; + ++ (instancetype)operationWithNotificationInfo:(SKYNotificationInfo *)notificationInfo deviceIDsToSend:(NSArray *)deviceIDsToSend; ++ (instancetype)operationWithNotificationInfo:(SKYNotificationInfo *)notificationInfo + deviceIDsToSend:(NSArray *)deviceIDsToSend + topic:(NSString *)topic; + @property (nonatomic, readwrite, copy) SKYNotificationInfo *notificationInfo; @property (nonatomic, readwrite) SKYPushTarget pushTarget; @property (nonatomic, readwrite, copy) NSArray *IDsToSend; +@property (nonatomic, readwrite, copy) NSString *topic; @property (nonatomic, copy) void (^perSendCompletionHandler)(NSString *userID, NSError *error); @property (nonatomic, copy) void (^sendCompletionHandler)(NSArray *userIDs, NSError *error); diff --git a/Pod/Classes/Operations/SKYSendPushNotificationOperation.m b/Pod/Classes/Operations/SKYSendPushNotificationOperation.m index ba88b74..d825b89 100644 --- a/Pod/Classes/Operations/SKYSendPushNotificationOperation.m +++ b/Pod/Classes/Operations/SKYSendPushNotificationOperation.m @@ -32,11 +32,23 @@ @implementation SKYSendPushNotificationOperation - (instancetype)initWithNotificationInfo:(SKYNotificationInfo *)notificationInfo pushTarget:(SKYPushTarget)pushTarget IDsToSend:(NSArray *)IDsToSend +{ + return [self initWithNotificationInfo:notificationInfo + pushTarget:pushTarget + IDsToSend:IDsToSend + topic:nil]; +} + +- (instancetype)initWithNotificationInfo:(SKYNotificationInfo *)notificationInfo + pushTarget:(SKYPushTarget)pushTarget + IDsToSend:(NSArray *)IDsToSend + topic:(NSString *)topic { self = [super init]; if (self) { _notificationInfo = [notificationInfo copy]; _IDsToSend = [IDsToSend copy]; + _topic = [topic copy]; _pushTarget = pushTarget; [_IDsToSend enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { @@ -52,20 +64,42 @@ - (instancetype)initWithNotificationInfo:(SKYNotificationInfo *)notificationInfo return self; } -+ (instancetype)operationWithNotificationInfo:(SKYNotificationInfo *)noteInfo ++ (instancetype)operationWithNotificationInfo:(SKYNotificationInfo *)notificationInfo userIDsToSend:(NSArray *)userIDsToSend { - return [[self alloc] initWithNotificationInfo:noteInfo + return [[self alloc] initWithNotificationInfo:notificationInfo pushTarget:SKYPushTargetIsUser - IDsToSend:userIDsToSend]; + IDsToSend:userIDsToSend + topic:nil]; } -+ (instancetype)operationWithNotificationInfo:(SKYNotificationInfo *)noteInfo ++ (instancetype)operationWithNotificationInfo:(SKYNotificationInfo *)notificationInfo + userIDsToSend:(NSArray *)userIDsToSend + topic:(NSString *)topic +{ + return [[self alloc] initWithNotificationInfo:notificationInfo + pushTarget:SKYPushTargetIsUser + IDsToSend:userIDsToSend + topic:topic]; +} + ++ (instancetype)operationWithNotificationInfo:(SKYNotificationInfo *)notificationInfo deviceIDsToSend:(NSArray *)deviceIDsToSend { - return [[self alloc] initWithNotificationInfo:noteInfo + return [[self alloc] initWithNotificationInfo:notificationInfo pushTarget:SKYPushTargetIsDevice - IDsToSend:deviceIDsToSend]; + IDsToSend:deviceIDsToSend + topic:nil]; +} + ++ (instancetype)operationWithNotificationInfo:(SKYNotificationInfo *)notificationInfo + deviceIDsToSend:(NSArray *)deviceIDsToSend + topic:(NSString *)topic +{ + return [[self alloc] initWithNotificationInfo:notificationInfo + pushTarget:SKYPushTargetIsDevice + IDsToSend:deviceIDsToSend + topic:topic]; } + (Class)responseClass @@ -105,6 +139,11 @@ - (void)prepareForRequest userInfo:nil]; } } + + if (self.topic.length) { + [payload setObject:self.topic forKey:@"topic"]; + } + self.request = [[SKYRequest alloc] initWithAction:action payload:payload]; self.request.APIKey = self.container.APIKey; } From 22698d1228c61e0b5435ba7dc6c08e914299f69b Mon Sep 17 00:00:00 2001 From: Ben Lei Date: Fri, 6 Jan 2017 15:30:14 +0800 Subject: [PATCH 4/4] Update the deprecated annotation --- Pod/Classes/Operations/SKYRegisterDeviceOperation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pod/Classes/Operations/SKYRegisterDeviceOperation.h b/Pod/Classes/Operations/SKYRegisterDeviceOperation.h index 47c9859..c565b22 100644 --- a/Pod/Classes/Operations/SKYRegisterDeviceOperation.h +++ b/Pod/Classes/Operations/SKYRegisterDeviceOperation.h @@ -23,7 +23,7 @@ @interface SKYRegisterDeviceOperation : SKYOperation - (instancetype)initWithDeviceToken:(NSData *)deviceToken - __attribute__((deprecated("Use -(void)initWithDeviceToken:topic: instead"))); + __attribute__((deprecated("Use -initWithDeviceToken:topic: instead"))); - (instancetype)initWithDeviceToken:(NSData *)deviceToken topic:(NSString *)topic; /** @@ -35,7 +35,7 @@ */ + (instancetype)operation; + (instancetype)operationWithDeviceToken:(NSData *)deviceToken - __attribute__((deprecated("Use +(instancetype)operationWithDeviceToken:topic: instead"))); + __attribute__((deprecated("Use +operationWithDeviceToken:topic: instead"))); + (instancetype)operationWithDeviceToken:(NSData *)topic topic:(NSString *)topic; @property (nonatomic, readonly, copy) NSData *deviceToken;