進度條

[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 {

    //錯誤處理...
}