プログラムの実装

設定後、モバイルアプリに初期化コードと受信ハンドラーを実装します。

APNs へのデバイスの登録

プッシュ通知の初期化処理を AppDelegate の application:didFinishLaunchingWithOptions: メソッドに追加します。追加する API の実行には、UserNotifications の import が必要です。

実装済みの Kii Cloud の初期化処理を含めると、ソースコードは最終的に次のようになります。

  • import UserNotifications
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
      Kii.begin(withID: "___APPID___", andKey: "___APPKEY___", andSite: KiiSite.JP)
    
      // Register the device to APNs.
      if #available(iOS 10, *) {
        // For iOS 10
        UNUserNotificationCenter.current().requestAuthorization(options:[.alert, .sound, .badge]) { (granted: Bool, error: Error?) in
          if (error != nil) {
            print("Failed to request authorization")
            return
          }
          if granted {
            application.registerForRemoteNotifications()
          } else {
            print("The user refused the push notification")
          }
        }
      } else {
        // For iOS 8/iOS 9
        let notificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
        application.registerUserNotificationSettings(notificationSettings)
        application.registerForRemoteNotifications()
      }
    
      return true
    }
  • import UserNotifications
    
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
      Kii.beginWithID("___APPID___", andKey: "___APPKEY___", andSite: KiiSite.JP)
    
      // Register the device to APNs.
      if #available(iOS 10, *) {
        // For iOS 10
        UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Alert, .Sound, .Badge], completionHandler: { (granted: Bool, error: NSError?) in
          if (error != nil) {
            print("Failed to request authorization")
            return
          }
          if granted {
            application.registerForRemoteNotifications()
          } else {
            print("The user refused the push notification")
          }
        })
      } else {
        // For iOS 8/iOS 9
        let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Sound, .Badge], categories: nil)
        application.registerUserNotificationSettings(notificationSettings)
        application.registerForRemoteNotifications()
      }
    
      return true
    }
  • @import UserNotifications;
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
      [Kii beginWithID:@"___APPID___"
                andKey:@"___APPKEY___"
               andSite:kiiSiteJP];
    
      // Register the device to APNs.
      if ([[UNUserNotificationCenter class] respondsToSelector:@selector(currentNotificationCenter)]) {
        // For iOS 10
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge)
                              completionHandler:^(BOOL granted, NSError * _Nullable error) {
          if (error != nil) {
            NSLog(@"Failed to request authorization");
            return;
          }
          if (granted) {
            [application registerForRemoteNotifications];
          } else {
            NSLog(@"The user refused the push notification");
          }
        }];
      } else {
        // For iOS 8/iOS 9
        UIUserNotificationSettings* notificationSettings =
            [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert |
                                                         UIUserNotificationTypeSound |
                                                         UIUserNotificationTypeBadge
                                              categories:nil];
        [application registerUserNotificationSettings:notificationSettings];
        [application registerForRemoteNotifications];
      }
    
      return YES;
    }

ここでは、ユーザーにプッシュ通知の許可を求めて、APNs にデバイスを登録する処理を行います。サンプルコードでは、テキスト(.alert)、サウンド(.sound)、アイコンバッジ(.badge)を使用することが宣言されているため、画面上のメッセージもそれに応じて表示されます。

初期化処理で使用する API は、iOS 10 以降とそれ以前の環境で異なります。

  • iOS 10 以降

    UNUserNotificationCenterrequestAuthorization メソッドを呼び出してユーザーに許可を求めます。

    ユーザーが入力すると、completionHandler が呼び出されます。引数 granted にはユーザーがプッシュ通知を許可したかどうかのフラグが入っています。許可された場合には registerForRemoteNotifications メソッドを呼び出して、APNs にデバイスを登録します。

  • iOS 8/iOS 9

    iOS 10 以前では、許可を求めるメッセージをユーザーに表示する registerUserNotificationSettings とデバイスの登録処理を行う registerForRemoteNotifications を順番に実行します。

Kii Cloud へのインストール

次に、取得できた APNs のデバイストークンを、ユーザーと紐付けて Kii Cloud に登録します。

APNs への登録処理が成功すると、取得できた APNs のデバイストークンを引数として application:didRegisterForRemoteNotificationsWithDeviceToken: メソッドが呼び出されます。また、登録処理が失敗すると application:didFailToRegisterForRemoteNotificationsWithError: メソッドが呼び出されます。

ここでは以下のような処理を実装します。

  • func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
      let username = "user1"
      let password = "123ABC"
      KiiUser.authenticate(username, withPassword: password) { (user: KiiUser?, error: Error?) -> Void in
        if (error != nil) {
          print("Failed to authenticate: \((error! as NSError).userInfo["description"])")
          return
        }
        KiiPushInstallation.install(withDeviceToken: deviceToken, andDevelopmentMode: true) { (installation: KiiPushInstallation?, error: Error?) -> Void in
          if (error != nil) {
            print("Failed to install the device token: \((error! as NSError).userInfo["description"])")
            return
          }
          print("Push installed!")
        }
      }
    }
    
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
      print("Failed to register to APNs: \(error)")
    }
  • func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
      let username = "user1"
      let password = "123ABC"
      KiiUser.authenticate(username, withPassword: password) { (user: KiiUser?, error: NSError?) -> Void in
        if (error != nil) {
          print("Failed to authenticate: \(error!.userInfo["description"])")
          return
        }
        KiiPushInstallation.installWithDeviceToken(deviceToken, andDevelopmentMode: true) { (installation: KiiPushInstallation?, error: NSError?) -> Void in
          if (error != nil) {
            print("Failed to install the device token: \(error!.userInfo["description"])")
            return
          }
          print("Push installed!")
        }
      }
    }
    
    func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
      print("Failed to register to APNs: \(error)")
    }
  • - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
      NSString *username = @"user1";
      NSString *password = @"123ABC";
      [KiiUser authenticate:username withPassword:password andBlock:^(KiiUser *user, NSError *error) {
        if (error != nil) {
          NSLog(@"Failed to authenticate: %@", error.userInfo[@"description"]);
          return;
        }
        [KiiPushInstallation installWithDeviceToken:deviceToken
                                 andDevelopmentMode:YES
                                      andCompletion:^(KiiPushInstallation *installation, NSError *error2) {
          if (error != nil) {
            NSLog(@"Failed to install the device token: %@", error2.userInfo[@"description"]);
            return;
          }
          NSLog(@"Push installed!");
        }];
      }];
    }
    
    - (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {
      NSLog(@"Failed to register to APNs: (%@)", error);
    }

APNs へのデバイスの登録が成功すると、application:didRegisterForRemoteNotificationsWithDeviceToken: メソッドが呼び出されます。ここでは、ユーザーのログイン処理とデバイスのインストール処理を行います。

まず、KiiUserauthenticate メソッドによって、Kii Cloud にログインします。usernamepassword には アプリ作成時 に作成したテストユーザーを指定しています。ユーザー名を user1、パスワードを 123ABC としたため、それらの固定の文字列を使って簡易的にログインしています。

ログインに成功したときは、KiiPushInstallationinstall メソッドを使って APNs のデバイストークンを Kii Cloud にインストールします。これは、ログイン中のユーザーの権限で実行されるため、Kii Cloud 上でユーザーとデバイストークンが紐付けられます。以降、ユーザー指定のプッシュ通知は、このデバイスに届くようになります。

なお、このサンプルコードは、開発用の APNs を指定して初期化しています。配布用でプッシュ通知を受信する場合は、andDevelopmentModefalse (NO) にします。

インストール処理の毎回実行

デバイストークンのインストール処理は、デバイスの起動ごとに必要です。デバイストークンの取得処理と Kii Cloud へのインストール処理は他のクラスに移動できますが、これらはモバイルアプリの起動ごとに毎回実行されるようにしてください。

Apple 公式の Local and Remote Notification Programming Guide にも、モバイルアプリの起動ごとに APNs に登録する必要があることが記載されています。Kii Cloud のサーバーは、APNs 側でデバイストークンが無効になったことを検出すると、Kii Cloud 上に登録されているデバイストークンを削除することがあります。この際、デバイス側からの再登録がないと、以降のプッシュ通知が行われなくなります。

受信ハンドラーの追加

次に、プッシュメッセージを受け取った時に実行される受信ハンドラーを実装します。ここでは、単純にログを出力するだけとしますが、実際のアプリでは受信したメッセージから必要なデータを取り出して、アプリの機能を実現することになるはずです。

  • func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
      print("Received the push notification: \(userInfo)")
      completionHandler(.newData)
    }
  • func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
      print("Received the push notification: \(userInfo)")
      completionHandler(.NewData)
    }
  • - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result)) completionHandler {
      NSLog(@"Received the push notification: %@", userInfo);
      completionHandler(UIBackgroundFetchResultNewData);
    }

実際のプログラムでプッシュ通知を実装する場合は、初期化処理と受信処理の実装 の情報を参考にして、その他のハンドラーの実装を検討してください。プッシュ通知のテストはこのメソッドだけで実行できます。

以上で全ての実装作業は完了です。次のステップ テストメッセージの送信 で実際にテストメッセージを送信してみましょう。


<< Xcode の設定 テストメッセージの送信 >>