NWPusherで手軽にiPhone実機へプッシュ通知を送り、テストをする

iPhoneアプリのデバッグ過程でプッシュ通知をテスト端末に送る必要があったのですが、
NWPusherのおかげで手軽に何度もプッシュ通知を送ることができ、とても捗りました！

## NWPusherをインストールする
GitHubのページは以下です。
[GitHub - noodlewerk/NWPusher: OS X and iOS application and framework to play with the Apple Push Notification service (APNs)](https://github.com/noodlewerk/NWPusher)

Readmeに記載されていますが、*Homebrew caskでのインストール*がオススメです。

```bash
brew cask install pusher
```

Homeberwを使わない場合は最新のバイナリーがダウンロードできます。
[Latest Release · noodlewerk/NWPusher · GitHub](https://github.com/noodlewerk/NWPusher/releases/latest)

インストールできたら、NWPusher（以下Pusher）を起動します。

## p12ファイルのインポート
p12ファイルが手元にない場合は、作成するか、権限のある人に依頼しましょう！
[【iOS】複雑な証明書周りをあっさり整理してみた – ゆるtech。](https://shigu493.com/%E3%80%90ios%E3%80%91%E8%A4%87%E9%9B%91%E3%81%AA%E8%A8%BC%E6%98%8E%E6%9B%B8%E5%91%A8%E3%82%8A%E3%82%92%E3%81%82%E3%81%A3%E3%81%95%E3%82%8A%E6%95%B4%E7%90%86/)

p12ファイルを入手できたら、
Pusherアプリの`Import PKCS  #12 file (.p12)...`からインポートします。

## デバイストークンの入手
プッシュ通知の送り先を識別するための端末個別のトークンが必要なので、下記のオーバーライドメソッドで取得します。
8桁×8の英数字文字列がコンソールに出力されるのでコピーしましょう。

### Swift
```AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // ① プッシュ通知利用許可のリクエスト
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
        guard granted else { return }

        DispatchQueue.main.async {
            // ② プッシュ通知利用の登録
            UIApplication.shared.registerForRemoteNotifications()
        }
    }
    return true
}

// ③ プッシュ通知の利用登録が成功した場合（引数でデバイストークンが取れる）
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    print("Device token: \(deviceToken)")
}

// ④ （省略可）プッシュ通知の利用登録が失敗した場合はこちらが呼ばれる
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    print("Failed to register to APNs: \(error)")
}
```

### Objective-C
```objc:AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // ① プッシュ通知利用許可のリクエスト
    [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (granted) {
            dispatch_async(dispatch_get_main_queue(), ^{
                // ② プッシュ通知利用の登録
                [UIApplication.sharedApplication registerForRemoteNotifications];
            });
        }
    }];
    return YES;
}

// ③ プッシュ通知の利用登録が成功した場合（引数でデバイストークンが取れる）
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    NSLog(@"Device token: %@", deviceToken);
}

// ④ （省略可）プッシュ通知の利用登録が失敗した場合はこちらが呼ばれる
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    NSLog(@"Failed to register to APNs: %@", error);
}
```

## デバイストークンの入力
コピーしたデバイストークン（8桁×8の英数字文字列）をPusherアプリに入力します。
8桁ごとにスペースで区切られたままでも大丈夫です。

* Expiry（有効期限）
* Priority（優先度）

を設定することもできますが、デフォルトの`None`でも問題ありません。

## 書かなかったこと
以下のことは試していないです。
GitHubのReadmeに詳しくHow-toが書いてありました。

* CocoaPodsまたはCarthageを用いて、iPhoneアプリにフレームワークを入れればiPhoneからプッシュ通知を送ることができる。
* iOS, macOS で、プログラムを書いて通知を送信するためのフレームワークとしても使用できる。

## 参考リンク
[iOS13におけるプッシュ通知に必要なデバイストークンの取得方法 - Takahiro Octopress Blog](https://grandbig.github.io/blog/2019/09/28/ios-devicetoken-2/)