[Objective C][APNS] Apple push notification service 推播
更新日期:1. 在Apple developer 上註冊Certificate
2. download 下來放入keychain access
3. 打開keychain, 左半下面有一個category, 點擊Certificates
4. 如果有正確放入keychain access 會看到 Apple Development iOS Push Services: app identifier
按右鍵 -> export Apple Development iOS Push Services: app identifier
存成.p12檔, 範例使用名稱 apns-dev-cert.p12
5. 打開Apple Development iOS Push Services: app identifier 的下拉會看到private key
一樣按右鍵 -> export [User Name]
存成.p12檔, 範例使用名稱 apns-dev-key.p12
6. 使用command將.p12轉成 PEM
openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12
openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns-dev-key.p12 <=== 會要求自訂密碼
7. 移除自訂密碼
openssl rsa -in apns-dev-key.pem -out apns-dev-key-noenc.pem
8. 將兩個PEM組合成最終我們要的
cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem
// ===========================================================
使用第三方程式測試
在apple store 下載 Easy APNs provider
其中裡面的certificate使用的是從Apple developer下載下來的那份,不是自己組出來的
// ===========================================================
iOS 程式
1. 專案檔 => Capability => 開啟 push notifications
2. AppDelegate
AppDelegate.h 加入
#import <UserNotifications/UserNotifications.h>
AppDelegate.m
// app lifecycle 加入
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[self registerForRemoteNotifications];
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// 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.
UIApplication.sharedApplication.applicationIconBadgeNumber = 0;
}
//另外加入的code
用來判斷ios 版本, 新舊註冊方式不同
#define SYSTEM_VERSION_GRATERTHAN_OR_EQUALTO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
- (void)registerForRemoteNotifications {
if(SYSTEM_VERSION_GRATERTHAN_OR_EQUALTO(@"10.0")){
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){
if(!error){
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}];
}
else {
// Code for old versions
}
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog(@"User Info : %@",notification.request.content.userInfo);
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
//Called to let your app know which action was selected by the user for a given notification.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{
NSLog(@"User Info : %@",response.notification.request.content.userInfo);
UIApplication.sharedApplication.applicationIconBadgeNumber = 0;
completionHandler();
}
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken: (NSData *)deviceToken
{
//將Device Token由NSData轉換為字串
const unsigned *tokenBytes = [deviceToken bytes];
NSString *iOSDeviceToken =
[NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
//6301ea515ec3d622e8da8a05de64a21abc227e0795d780f4264de1eed0ca0787
//將Device Token傳給Provider...
NSLog(@"%@", iOSDeviceToken);
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError: (NSError *)err {
//錯誤處理...
}