メモ > 技術 > サービス: AmazonSNS > iOS: アプリにPush通知受信機能を実装
iOS: アプリにPush通知受信機能を実装
Xcodeのプロジェクトの「Signing & Capabilities」で「+Capabilities」をクリックし、一覧に表示される「Background Modes」をダブルクリックで選択する。
その後、画面に表示される「Remote notification」にチェックを入れる。
以下の記事に参考画面があるが、当時からUIは変更されている。
You've implemented -[ application: didReceiveRemoteNotification: fetchCompletionHandler:], but you still need to add "remote-notification" to the list of your supported UIBackgroundModes in your Info.plist.の解決法 - ゆーじのUnity開発日記
http://unity-yuji.xyz/youve-implemented-applicationdidreceiveremotenotification-remote-notification-...
プログラムは、主に以下の記事を参考に作成する。
SwiftUIでのプッシュ通知の最小構成 - すいすいSwift
https://swiswiswift.com/2022-03-03/
pushtest1App.swift
import SwiftUI
@main
struct pushtest1App: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate … 追加
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
ContentView.swift
import SwiftUI
struct ContentView: View { … ContentView内の処理を変更
let publisher = NotificationCenter.default.publisher(for: .deviceToken)
@State var deviceToken: String = ""
var body: some View {
VStack {
Text("DeviceToken")
TextField("Device Token is Empty", text: $deviceToken)
.padding()
}
.onReceive(publisher) { message in
if let deviceToken = message.object as? String {
self.deviceToken = deviceToken
print("Device Token: " + self.deviceToken)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
AppDelegate.swift(新規に作成する)
import UIKit
//@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Show Push Notification Dialogue
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
guard granted else { return }
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
UNUserNotificationCenter.current().delegate = self
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
extension Notification.Name {
static let deviceToken = Notification.Name("DeviceToken")
}
extension AppDelegate: UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = deviceToken.map { String(format: "%.2hhx", $0) }.joined()
print("Device token: \(token)")
NotificationCenter.default.post(name: .deviceToken, object: token)
}
func application(_ application: UIApplication, didReceiveRemoteNotification payload: [AnyHashable: Any]) {
print(payload)
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.sound, .badge])
}
}
※plistの編集は不要だった。
※CocoaPodsのインストールは不要だった。
※実際の実装では、トークンを画面に表示することなく「デバイス内に保存してサーバにも投げる」としておけば良さそう。
後述の「アプリ起動時にデバイストークンをサーバ側に記録」も参照。
■動作確認
アプリを実行すると、「"〇〇"は通知を送信します。よろしいですか?」が表示されるので「許可」をタップする。
画面にデバイストークンが表示されることを確認する。
また、ログにもデバイストークンが表示されるようにしている。
以下は実際に表示された値。
Device Token: d6cb5af49500000000002425020838f4d4792c2de946bce49ad240be4f19c9b2
この文字列をもとに、サーバサイドプログラムからプッシュ通知を送信する。
具体的な送信方法は引き続き後述する。
※エミュレータではプッシュ通知を受け取れないので、実機で実行する。