@available(iOS 10.0, *)
import UserNotifications
NSUserNotification API Reference
UNNotificationSound API Reference
UNUserNotificationCenter API Reference
参考URL:
iOS 10 User Notifications Framework実装まとめ
★ 通知の許可を求める
// current() メソッドを使用してシングルトンオブジェクトを取得
let center = UNUserNotificationCenter.current()
// 通知の使用許可をリクエスト
center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
print(granted) // 許可している場合はtrue, していない場合はfalse
print(error ?? "") // nil
// 許可アラートが出た場合はボタンを選択時にBlockが呼ばれる,その後は即時に呼ばれる
}
★ UNAuthorizationOptions
/*
badge
sound
alert
carPlay
*/
★ 時限式のローカル通知を作成する
// UNMutableNotificationContentを作成
let content = UNMutableNotificationContent()
content.title = "iOS10"
content.subtitle = "SubTitle"
content.body = "UNUserNotificationCenter!"
content.badge = 2
content.userInfo = ["A": "a"]
content.sound = UNNotificationSound.default()
// content.sound = UNNotificationSound(named: "sample.m4a")
// 5秒後に発火するUNTimeIntervalNotificationTriggerを作成、
let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 5, repeats: false)
// identifier, content, trigger からUNNotificationRequestを作成
let request = UNNotificationRequest.init(identifier: "FiveSecondNotification", content: content, trigger: trigger)
// UNUserNotificationCenterにrequestを追加
let center = UNUserNotificationCenter.current()
center.add(request)
★ 画像を添付する場合
let fileURL = URL(fileURLWithPath: Bundle.main().pathForResource("apple", ofType: "png")!)
let attachment = try! UNNotificationAttachment(identifier: "image", url: fileURL, options: nil)
content.attachments = [attachment]
★ 指定日時に発火するローカル通知を作成する
// UNMutableNotificationContentを作成
let content = UNMutableNotificationContent()
content.title = "Hello!"
content.body = "It's time!"
content.sound = UNNotificationSound.default()
// UNCalendarNotificationTriggerを作成
let date = DateComponents(month:7, day:7, hour:12, minute:0)
let trigger = UNCalendarNotificationTrigger.init(dateMatching: date, repeats: false)
// id, content, triggerからUNNotificationRequestを作成
let request = UNNotificationRequest.init(identifier: "CalendarNotification", content: content, trigger: trigger)
// UNUserNotificationCenterにrequestを追加
let center = UNUserNotificationCenter.current()
center.add(request)
// リピート有りの場合
// let date = DateComponents(hour:8, minute:30)
// let trigger = UNCalendarNotificationTrigger.init(dateMatching: date, repeats: true)
// 次の発火日時を取得する
let nextTriggerDate = trigger.nextTriggerDate()
print(nextTriggerDate)
★ 位置情報に基づいて発火するローカル通知を作成する
// UNMutableNotificationContentを作成
let content = UNMutableNotificationContent()
content.title = "Hello!"
content.body = "Enter Headquarter"
content.sound = UNNotificationSound.default()
// UNLocationNotificationTriggerを作成
let coordinate = CLLocationCoordinate2DMake(35.697275, 139.774728)
let region = CLCircularRegion.init(center: coordinate, radius: 1000.0, identifier: "Headquarter")
region.notifyOnEntry = true;
region.notifyOnExit = false;
let trigger = UNLocationNotificationTrigger.init(region: region, repeats: false)
// id, content, triggerからUNNotificationRequestを作成
let request = UNNotificationRequest.init(identifier: "LocationNotification", content: content, trigger: trigger)
// UNUserNotificationCenterにrequestを追加
let center = UNUserNotificationCenter.current()
center.add(request)
★ 登録した通知を変更する(同じidentifierを使用して再登録する) print("didReceive Local Notification")
// 通知の定義
let updatedRequest = UNNotificationRequest(identifier: "CalendarNotification", content: content, trigger: trigger)
// 通知の登録(更新)
UNUserNotificationCenter.current().add(updatedRequest) { (error) in
print(error) // 正常に更新された場合 nil
}
★ アプリがForegroundで通知が来たことをDelegateメソッドで感知する
// UNUserNotificationCenterDelegateを継承する
class ViewController: UIViewController, UNUserNotificationCenterDelegate
let center = UNUserNotificationCenter.current()
// デリゲートを設定
center.delegate = self;
center.add(request)
// アプリが Foreground の時に通知を受け取った時に呼ばれるメソッド
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
print("fire! notification ID:\(notification.request.identifier)")
// Foregroundでも上から出てくる通知を出したいときは以下を記述
// 通知バナー表示、通知音の再生を指定
completionHandler([.alert, .sound])
}
★ アプリがBackgroundで通知タップ、通知センターでの通知タップで起動したことをDelegateメソッドで感知する
※ アプリが終了している場合はAppDelegateのlaunchOptionsでdelegateを設定しておかないと取得できない。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let center = UNUserNotificationCenter.current()
// デリゲートを設定
center.delegate = self;
return true
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
// 通知の情報を取得
let notification = response.notification
// リモート通知かローカル通知かを判別
if notification.request.trigger is UNPushNotificationTrigger {
print("didReceive Push Notification")
} else {
// UserInfoを取得
print(notification.request.content.userInfo)
print("didReceive Local Notification")
}
// 通知の ID を取得
print("notification.request.identifier: \(notification.request.identifier)")
// 処理完了時に呼ぶ
completionHandler()
}
★ 未配信の通知一覧を取得する
let center = UNUserNotificationCenter.current()
center.getPendingNotificationRequests { (requests: [UNNotificationRequest]) in
for request in requests {
print(request)
print("---------------")
}
}
★ 特定の未配信の通知を削除する(identifierを指定)
let center = UNUserNotificationCenter.current()
center.getPendingNotificationRequests { (requests: [UNNotificationRequest]) in
for request in requests {
if request.identifier == "CalendarNotification" {
center.removePendingNotificationRequests(withIdentifiers: [request.identifier])
}
}
}
★ 全ての未配信の通知を削除する
let center = UNUserNotificationCenter.current()
center.removeAllPendingNotificationRequests()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let center = UNUserNotificationCenter.current()
center.requestAuthorization([.alert, .sound]) { (granted, error) in
// 許可している場合はtrue, していない場合はfalse
if granted {
application.registerForRemoteNotifications()
}
}
return true
}
★ 通知センターにある通知一覧を取得する
let center = UNUserNotificationCenter.current()
center.getDeliveredNotifications { (notifications: [UNNotification]) in
for notification in notifications {
print(notification)
print("---------")
}
}
★ 通知センターから特定の通知を削除する
let center = UNUserNotificationCenter.current()
center.getDeliveredNotifications { (notifications: [UNNotification]) in
for notification in notifications {
if notification.request.identifier == "FiveSecondNotification" {
center.removeDeliveredNotifications(withIdentifiers: [notification.request.identifier])
}
}
}
★ 通知センターの通知を全て削除する
let center = UNUserNotificationCenter.current()
center.removeAllDeliveredNotifications()
通知にアクションボタンを配置する
// -----AppDelegate -----
import UIKit
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 10.0, *) {
// iOS 10
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.badge, .sound, .alert], completionHandler: { (granted, error) in
if error != nil {
return
}
if granted {
debugPrint("通知許可")
} else {
debugPrint("通知拒否")
}
})
} else {
// iOS 9
let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)
UIApplication.shared.registerUserNotificationSettings(settings)
}
return true
}
}
// -----ViewController -----
import UIKit
import UserNotifications
enum ActionIdentifier: String {
case attend
case absent
}
class ViewController: UIViewController, UNUserNotificationCenterDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBOutlet weak var a: UIButton!
@IBAction func g(_ sender: AnyObject) {
let attend = UNNotificationAction(identifier: ActionIdentifier.attend.rawValue,
title: "出席", options: [])
let absent = UNNotificationAction(identifier: ActionIdentifier.absent.rawValue,
title: "欠席",
options: [])
let category = UNNotificationCategory(identifier: "message", actions: [attend, absent], intentIdentifiers: [], options: [])
UNUserNotificationCenter.current().setNotificationCategories([category])
UNUserNotificationCenter.current().delegate = self
let content = UNMutableNotificationContent()
content.title = "出席確認"
content.body = "今日のイベントに参加しますか?"
content.sound = UNNotificationSound.default()
// categoryIdentifierを設定
content.categoryIdentifier = "message"
// 5秒後
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: "FiveSecond",
content: content,
trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Swift.Void) {
switch response.actionIdentifier {
case ActionIdentifier.attend.rawValue:
debugPrint("出席します")
case ActionIdentifier.absent.rawValue:
debugPrint("欠席します")
default:
()
}
completionHandler()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
★ UserInfoを便利に扱うための構造体
struct NotificationPayload {
let json: JSON
private var aps: JSON { return json["aps"] }
var alert: String? { return aps["alert"].string }
var badge: Int? { return aps["badge"].int }
var sound: String? { return aps["sound"].string }
var contentAvailable: Int? { return aps["content-available"].int }
var newsId: Int32? { return json["news_id"].int32 }
var notificationId: Int32? { return json["notification_id"].int32 }
init(userInfo: [AnyHashable : Any]) {
json = JSON(userInfo)
}
}
// 使い方
let payload = NotificationPayload(userInfo: userInfo)
if let badge = payload.badge {
}