iOSのUNLocalNotificationを3分で理解

iOSのプッシュ通知関連は鬼門だ。
プログラミングというよりOSの挙動をある程度理解していないとキツイ。

基本的なUNLocalNotificationの使い方をここにメモしておく。


## 通知のリクエストダイアログを表示
まずは、通知の許可をユーザーから得るダイアログを表示する。
このダイアログにユーザーが同意しないと、ローカル通知を表示させる事が出来ない。

```swift

    func requestNotificationPermission() -> Void {
        let options: UNAuthorizationOptions = [.alert, .sound, .badge]
        UNUserNotificationCenter.current().requestAuthorization(options: options) { granted, error in
          if let error = error {
            print("Error: \(error.localizedDescription)")
          } else if granted {
            print("Push notification permission is granted")
          } else {
            print("Push notification permission is rejected")
          }
        }
    }
```
viewDidLoadなどで、requestNotificationPermissionを呼び出そう。

2 AppDelegateに記述を加える。
AppDelegateを以下のように書き換えてください。


```swift

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Set up the UserNotificationCenter delegate
    UNUserNotificationCenter.current().delegate = self
    
    // Setup the NotificationCategories used in the future
    let foregroundAction = UNNotificationAction(identifier: "foregroundActionIdentifier", title: "foregroundAction", options: [.foreground])
    let category = UNNotificationCategory(identifier: "fooCategoryIdentifier", actions: [foregroundAction], intentIdentifiers: [], options: [.customDismissAction])
    UNUserNotificationCenter.current().setNotificationCategories([category])
    
    return true
  }

  // In order to show a notification in banner mode, `completionHandler` must be called with suitable option here
  func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    printLog("userNotificationCenter - willPresent")
    completionHandler([.alert, .badge, .sound])
  }
  
  func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    printLog("Clicked UNNotificationAction id: \(response.actionIdentifier)")
    completionHandler()
  }
  
  func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification?) {
    // Developer should present the notification settings page here
    printLog("userNotificationCenter - openSettingsFor")
  }
}
```

# ここから上までで日本語記事は終わりにして、あとはオプションで英語記事を読んでもらう。

その後、ViewControllerのviewDidLoadで、以下の関数を呼び出してください。
１秒後にローカル通知が表示されます。

```swift

    func showSampleNotification() -> Void {
        let notificationRequestId = "fooNotificationRequestId"

        // Create the content of a notification
        var content = UNMutableNotificationContent()
        content.title = "タイトル"
        content.subtitle = "サブタイトル"
        content.body = "本文"

        // １秒後に表示される通知トリガーを作成します。
        let timeIntervalNotificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)

        // ローカル通知を登録します。
        let request = UNNotificationRequest(identifier: notificationRequestId, content: content, trigger: timeIntervalNotificationTrigger)
        UNUserNotificationCenter.current().add(request) { (error) in
          if let error = error {
            print("Error: \(error.localizedDescription)")
          } else {
            print("Scheduled notification")
          }
        }
    }
```

完成！

## アプリがフォアグラウンドの時に通知を表示する。
通常バナー通知は、アプリがバックグラウンドまたはユーザーによってアプリが終了されている状態のみ表示される。
アプリがフォアグラウンドの時、ローカル通知を表示させたい場合は、

userNotificationCenter(_:willPresent:withCompletionHandler:) of UNUserNotificationCenterDelegate 
が、AppDelegateに実装されている必要がある。


```swift

extension AppDelegate: UNUserNotificationCenterDelegate {
  // Call the completionHandler to show a notification during app is at foreground
  func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    printLog("userNotificationCenter - willPresent")
    completionHandler([.alert, .badge, .sound])
  }
}
```

## 通知に画像を加えたり、特定の日時に通知を表示する。
色々なオプションがあるので、通知をカスタマイズしたい人は元記事を読んでください。

元記事
https://itnext.io/swift-local-notification-all-in-one-ee6027ea6e3