20230126æŽæ°
XcodeïŒSwiftïŒã§äœæãããã€ãã£ãã¢ããªã«ããã¯ã© mobile backendã®ãããã·ã¥éç¥ãæ©èœã®ïŒã€ã§ãããã·ã¥éç¥ã«URLãèšå®ãé ä¿¡ã§ããããªããããã·ã¥ãæ©èœãå®è£ ãããµã³ãã«ãããžã§ã¯ãã§ãããªããããã·ã¥æ©èœã䜿ããšããŠãŒã¶ãŒãããã·ã¥éç¥ãéå°ããéã«ãç»é¢ã«æå®ããWebããŒãžããWebViewãã§è¡šç€ºãããããšãå¯èœã§ã
ã¹ããŒããã©ã³ã¢ããªã®ããã¯ãšã³ãæ©èœïŒããã·ã¥éç¥ã»ããŒã¿ã¹ãã¢ã»äŒå¡ç®¡çã»ãã¡ã€ã«ã¹ãã¢ã»SNSé£æºã»äœçœ®æ å ±æ€çŽ¢ã»ã¹ã¯ãªããïŒãéçºäžèŠãç¡æ(泚1)ãã䜿ããã¯ã©ãŠããµãŒãã¹ã§ãã
泚1ïŒè©³ããã¯ãã¡ããã芧ãã ãã
ãããžã§ã¯ãã«çµã¿èŸŒãã§ããããã¯ã© mobile backendã®SDKã®ããŒãžã§ã³ã¯ããã¥ã¡ã³ãæŽæ°æç¹ã§ææ°ã® v1.3.1 ã§ãããã®ããŒãžã§ã³ã§ã®åäœç°å¢ã¯äžèšã§ãã
- Swift version 4.2, 5.x
- iOS 13.x ïœ iOS 16.x
- Xcode 13.2.1 ã Xcode 14.x
- armv7k, arm64, arm64e ã¢ãŒããã¯ãã£
SDKã®ããŒãžã§ã³ã¢ãããè¡ãå Žåã¯ãã¡ãïŒåèïŒSDKã®ã¢ããããŒãã«ã€ããŠïŒãåèã«æŽæ°ããé¡ãããŸãããŸããææ°ã®SDKããŒãžã§ã³åã³åäœç°å¢ã«ã€ããŠã¯mobile backend Swift SDK | GitHubããåç §ãã ããã ãããžã§ã¯ãäœææã«åäœæ€èšŒãè¡ã£ã端æ«æ å ±ã䜵ããŠèšèŒããŠãããŸãã
- macOS Monterey 12.6.1
- Xcode 14.0.1
- iOS 15.7 (iPhone 11 Pro)
â»ããã·ã¥éç¥ã®åäœæ€èšŒã«ã¯å®æ©ãã«ããå¿ é ã§ã
- ããã¯ã© mobile backendã®ããã·ã¥éç¥ã¯ãiOSãæäŸããŠããéç¥ãµãŒãã¹ïŒAPNsïŒApple Push Notification ServiceïŒïŒãå©çšããŠããŸã
- APNsãå©çšããã«ã¯èšŒææžãå©çšããèªèšŒãå¿ èŠã§ã
- äžèšã®ããã¥ã¡ã³ããã芧ã®äžãèªèšŒã«å¿
èŠãªèšŒææžé¡ã®äœæãããŸã
- ããã·ã¥éç¥ã«å¿ èŠãªèšŒææžã®äœãæ¹ | Qiita
- ãªã蚌ææžã®äœæã«ã¯Apple Developer Programã®ç»é²ïŒææïŒãå¿ èŠã§ã
- äžèšãªã³ã¯ããããã¯ã© mobile backendã®äŒå¡ç»é²ïŒç¡æïŒSNS IDïŒããã°ã€ã³ãããŸã
- ãã¢ããªã®æ°èŠäœæãç»é¢ïŒæ¢ã«ã¢ããªãäœææžã¿ã®å Žåã¯ã+æ°ããã¢ããªããã¯ãªãã¯ããïŒã§ã¢ããªåïŒäŸïŒSwiftRichPushAppïŒãå ¥åãã¢ããªãäœæããŸã
- ã¢ããªãäœæããããšAPIããŒïŒïŒçš®é¡ïŒãçºè¡ãããŸã
- APIããŒïŒã¢ããªã±ãŒã·ã§ã³ããŒãšã¯ã©ã€ã¢ã³ãããŒïŒã¯ãã®åŸãã3. APIããŒã®èšå®ãã§Xcodeã«ã€ã³ããŒããããµã³ãã«ã¢ããªäžã§äœ¿çšããŸã
- ãOKããã¯ãªãã¯ãããšããã·ã¥ããŒãã衚瀺ãããŸã
- å³äžã®ãã¢ããªèšå®ããã¯ãªãã¯ãããããã·ã¥éç¥ããéããŸã
- ãããã·ã¥éç¥ãïŒãããã·ã¥éç¥ã®èš±å¯ãã§ãèš±å¯ããããéžæãããä¿åããããã¯ãªãã¯ããŸã
- ãiOSããã·ã¥éç¥(p12)ãïŒã蚌ææžïŒp12ïŒãã®ã蚌ææžã®éžæããã¿ã³ãã¯ãªãã¯ããŠã0.ããã·ã¥éç¥æ©èœã䜿ãããã®æºåãã§äœæãããâŠAPNsçšèšŒææž(.p12)ããéžæããã¢ããããŒãããã¿ã³ãã¯ãªãã¯ããŠèšå®ããŸã
- ã蚌ææžã¯èšå®ãããŠããŸããããšè¡šç€ºãããã°OKã§ã
- äžèšãªã³ã¯ãã¯ãªãã¯ããŠãããžã§ã¯ããããŠã³ããŒãããŸã
- ããŠã³ããŒããããã©ã«ããéãããSwiftRichPushApp.xcodeprojããããã«ã¯ãªãã¯ããŠXcodeã§ãããžã§ã¯ããèµ·åããŸã
- SwiftRichPushApp ãã©ã«ãé
äžã®
AppDelegate.swift
ãç·šéããŸã - å
çšããã¯ã© mobile backendã®ããã·ã¥ããŒãäžã§ç¢ºèªããAPIããŒããããã
YOUR_APPLICATION_KEY
ãšYOUR_CLIENT_KEY
ã®éšåã«è²ŒããæžãæããŸã- APIããŒã¯ãããã¯ã© mobile backend管çç»é¢ãå³äžã®ãã¢ããªèšå®ããã確èªã§ããŸã
- ïŒã€ãã€ã³ããŒãã¿ã³ã§ã³ããŒããŠè²Œãä»ããŠãã ãã
- ãã®ãšããããã«ã¯ã©ãŒããŒã·ã§ã³ïŒ
"
ïŒãæ¶ããªãããã«æ³šæããŠãã ãã
- æžãæãçµãã£ãã
command + s
ããŒã§ä¿åãããŸã
å§ããŠå®æ©ãã«ããããå Žåã¯ãXcodeã«ã¢ã«ãŠã³ãïŒApple IDïŒã®ç»é²ãããŸãã
- ã¡ãã¥ãŒããŒã®ãXcodeãïŒãPreferences...ãïŒãAccountsããéžæããŸã
- å·Šäžã®ãïŒãïŒãApple IDããã¯ãªãã¯ããŸã
- ãApple IDããå
¥åããŠãNextãããPasswordããå
¥åããŠãNextããã¯ãªãã¯ãããšè¿œå ãããŸã
- èªèšŒã®ããã³ãŒããèŠæ±ãããå Žåã¯åŸã£ãŠãã ãã
- è¿œå ãããããã®ç»é¢ã¯éããŸã
ãã«ãã«å¿ èŠãªèšå®ãããŠãããŸãã
- ãããžã§ã¯ããéžæããŠããSigning & CapabilitiesããéããŸã
- ã0.ããã·ã¥éç¥æ©èœã䜿ãããã®æºåãã§äœæãããâ¡éçºçšãã«ã蚌ææž(.cer)ããšãâ€ããããžã§ãã³ã°ãããã¡ã€ã«ããèšå®ããŸã
- ããããããâ¡éçºçšãã«ã蚌ææž(.cer)ããšãâ€ããããžã§ãã³ã°ãããã¡ã€ã«ãã¯ããã«ã¯ãªãã¯ãããããŒãã§ãŒã³ã¢ã¯ã»ã¹ãšçŽã¥ããŠãããŸããã
- ãTeamãã§ãApple IDããéžæãããBundle IdentiIdentierãã«ã0.ããã·ã¥éç¥æ©èœã䜿ãããã®æºåãã§äœæãããâ¢AppIDããèšå ¥ããŸã
- ç¡äºé£æºãããã°ãProvisioning ProfileãããSigning Certificateãã衚瀺ãããŸã
å®æ©ã«ãã«ãããŸãã
- ã0.ããã·ã¥éç¥æ©èœã䜿ãããã®æºåãã®ãâ£ç«¯æ«ã®ç»é²ãã§ç»é²ãããåäœç¢ºèªçšiPhoneãMacã«ã€ãªããŸã
- iOS16以äžã§ãã¹ãã¢ããªããã«ãããå ŽåãiPhoneïŒç«¯æ«åŽïŒã®èšå®ã§ããããããã¢ãŒãããæå¹ã«ããå¿ èŠããããŸã
- ãèšå®ãïŒããã©ã€ãã·ãŒãšã»ãã¥ãªãã£ãïŒããããããã¢ãŒãããONã«ããŠããå®è¡ããŠãã ãã
- æ¥ç¶ããiPhoneãéžã³ãå®è¡ãã¿ã³ïŒããããã®åçããŒã¯ïŒãã¯ãªãã¯ããŸã
- iOSã®ããŒãžã§ã³ãäžèŽãããã«ããšã©ãŒãšãªãå Žåã¯ããGeneralãïŒãMinimum Deploymentsãã§å¯Ÿè±¡OSãå€æŽããŠãã ãã
- ãã«ããããã¢ããªã¯èªåã§èµ·åããŸã
- ããã·ã¥éç¥ã®èš±å¯ãæ±ããã¢ã©ãŒããåºãã®ã§ãå¿
ãèš±å¯ããŸã
- èš±å¯ããªããšããã·ã¥éç¥ãå±ããŸãã
- ãã®æç¹ã§ããã€ã¹ããŒã¯ã³ãAPNsããååŸãããããã¯ã© mobile backendã«ä¿åãããŸã
- æ£ããä¿åããããšãXcodeåŽã«ãã°ïŒ
ä¿åã«æåããŸãã
ïŒãåºåãããŸã
- æ£ããä¿åããããšãXcodeåŽã«ãã°ïŒ
- ããã¯ã© mobile backendã®ç®¡çç»é¢ãããããŒã¿ã¹ãã¢ãïŒãinstallationãã¯ã©ã¹ã確èªããŠã¿ãŸããã
- 端æ«åŽã§èµ·åããã¢ããªã¯äžåºŠéããŠïŒå®å šã«çµäºããŠïŒãããŸã
å®éã«ããã·ã¥éç¥ãéã£ãŠã¿ãŸããã
- ããã¯ã© mobile backend ã®ããã·ã¥ããŒãã§ãããã·ã¥éç¥ãïŒãïŒæ°ããããã·ã¥éç¥ããã¯ãªãã¯ããŸã
- ããã·ã¥éç¥ã®ãã©ãŒã ãéãããŸã
- å¿ èŠãªé ç®ãå ¥åããŠããã·ã¥éç¥ãäœæããŸã
- ãªããããã·ã¥ãé
ä¿¡ããã«ã¯ã
- å¿ ãæå¹ãªURLããURLãã«å ¥åããŠãã ãã
- å¿ ããcontent-availableãããæå¹ã«ãããããŠãã ãã
- 端æ«ã確èªããŸããã
- å°ãåŸ ã€ãšããã·ã¥éç¥ãå±ãã®ã§ãå±ããããã·ã¥éç¥ãã¿ããããŠã¢ããªãéããšWebãã¥ãŒã衚瀺ãããèšå®ããURLã®ããŒãžã衚瀺ãããŸã
ã¢ããªã®ç¶æ ã«ãããWebViewïŒãªããããã·ã¥ïŒã®è¡šç€ºã®ããæ¹ã¯ä»¥äžã®ããã«ãªããŸãããªãããããã衚瀺ãããWebViewãéããã«ã¯ãç»é¢äžã®ãCloseããã¿ããããŸããïŒãªããããã·ã¥ã«ãã£ãŠè¡šç€ºãããWebViewã¯äžåºŠãéãããšå衚瀺ã§ããŸããïŒ
- ã¢ããªã å®å šã«éããç¶æ ïŒKillïŒ ã§ããã·ã¥éç¥ãéã£ãå Žåã¯ãããã·ã¥éç¥ãåä¿¡ãããŸã
- åä¿¡ããããã·ã¥éç¥ãã¿ãããããšWebViewãç»é¢ã«è¡šç€ºãããŸã
- ã¢ããªãèµ·åããŠããïŒç»é¢ã«è¡šç€ºäžïŒç¶æ
ã§ããã·ã¥éç¥ãéã£ãå Žåã¯ãããã·ã¥éç¥èªäœã¯ 衚瀺ãããŸãã ïŒïŒiOSã®ä»æ§ïŒ
- èµ·åäžã®ã¢ããªã®ç»é¢ã«WebViewãç»é¢ã«è¡šç€ºãããŸã
- ã¢ããªãèµ·åããŠããïŒããã¯ã°ã©ãŠã³ãèµ·åäžïŒç¶æ
ã§ããã·ã¥éç¥ãéã£ãå Žåã¯ãããã·ã¥éç¥ãåä¿¡ãããŸã
- åä¿¡ããããã·ã¥éç¥ãã¿ããããããããã¯ã°ã©ãŠã³ãããã¢ããªãæåé¢ã«è¡šç€ºãããšWebViewãç»é¢ã確èªã§ããŸã
ãµã³ãã«ãããžã§ã¯ãã«å®è£ æžã¿ã®å 容ã®ã玹ä»ããŸãã
SDKã®å°å ¥ã¯Carthageå©çšããŠããŸãã
- ããã¯ã© mobile backend ã®ããã¥ã¡ã³ãïŒã¯ã€ãã¯ã¹ã¿ãŒãïŒ
AppDelegate.swift
ã®didFinishLaunchingWithOptions
ã¡ãœããã«APNsã«å¯ŸããŠããã€ã¹ããŒã¯ã³ã®èŠæ±ããã³ãŒããèšè¿°ããããã€ã¹ããŒã¯ã³ãååŸãããåŸã«åŒã³åºãããdidRegisterForRemoteNotificationsWithDeviceToken
ã¡ãœãããè¿œèšãããŸã
//
// AppDelegate.swift
// SwiftPushApp
//
// Created by ikeda.natsumo on 2023/01/06.
//
import UIKit
import NCMB
import UserNotifications
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// APIããŒã®èšå®ãšSDKåæå
NCMB.initialize(applicationKey: "YOUR_APPLICATION_KEY", clientKey: "YOUR_CLIENT_KEY")
// APNsã«ããã€ã¹ããŒã¯ã³ãèŠæ±
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
if((error) != nil) {
return
}
if granted {
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
//端æ«æ
å ±ãæ±ãNCMBInstallationã®ã€ã³ã¹ã¿ã³ã¹ãäœæ
let installation : NCMBInstallation = NCMBInstallation.currentInstallation
//Device Tokenãèšå®
installation.setDeviceTokenFromData(data: deviceToken)
//端æ«æ
å ±ãããŒã¿ã¹ãã¢ã«ç»é²
installation.saveInBackground(callback: { result in
switch result {
case .success:
//端æ«æ
å ±ã®ç»é²ãæåããå Žåã®åŠç
print("ä¿åã«æåããŸãã")
case let .failure(error):
//端æ«æ
å ±ã®ç»é²ã倱æããå Žåã®åŠç
print("ä¿åã«å€±æããŸãã: \(error)")
return;
}
})
}
// 以äžçç¥
}
- Xcodeã§ãããžã§ã¯ããéžæããŠããSigning & CapabilitiesããéããŸã
- ã+Capabilityããã¯ãªãã¯ããŠãæ€çŽ¢æ¬ã«ãPush Notificationsããšå ¥åãè¿œå ããŸã
äžèšããã€ã¹ããŒã¯ã³åŠçã®ã³ãŒãã«å ããïŒç®æïŒåŠçãå®è¡ããã¿ã€ãã³ã°ïŒã«ã³ãŒãã®è¿œå ãšè¿œå ã§èšå®ããå¿ èŠã§ãã
- ã¢ããªãèµ·åããããšãããã·ã¥éç¥ãéå°ãããå Žåã®åŠçã¯ã
didFinishLaunchingWithOptions
ã¡ãœããå ã«èšè¿°ããŸã
// MARK: ãªããããã·ã¥éç¥ã衚瀺ããã
if let notification = launchOptions?[.remoteNotification] as? [String: AnyObject] {
NCMBPush.handleRichPush(userInfo: notification)
}
- ã¢ããªãèµ·åããŠãããšãèµ·åäžã«éå°ããããã
didReceiveRemoteNotification
ã¡ãœãããè¿œèšããèšè¿°ããŸã
// ããã·ã¥éç¥ãåä¿¡ãããšãã®åŠç
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],fetchCompletionHandler completionHandler:@escaping (UIBackgroundFetchResult) -> Void) {
if let notiData = userInfo as? [String : AnyObject] {
// MARK: ãªããããã·ã¥éç¥ã衚瀺ããã
NCMBPush.handleRichPush(userInfo: notiData)
}
}
ïŒåèïŒå®è£
å®äºãã AppDelegate.swift
//
// AppDelegate.swift
// SwiftRichPushApp
//
// Created by ikeda.natsumo on 2023/01/06.
//
import UIKit
import NCMB
import UserNotifications
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// APIããŒã®èšå®ãšSDKåæå
NCMB.initialize(applicationKey: "YOUR_APPLICATION_KEY", clientKey: "YOUR_CLIENT_KEY")
// APNsã«ããã€ã¹ããŒã¯ã³ãèŠæ±
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
if((error) != nil) {
return
}
if granted {
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
// MARK: ãªããããã·ã¥éç¥ã衚瀺ããã
if let notification = launchOptions?[.remoteNotification] as? [String: AnyObject] {
NCMBPush.handleRichPush(userInfo: notification)
}
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
//端æ«æ
å ±ãæ±ãNCMBInstallationã®ã€ã³ã¹ã¿ã³ã¹ãäœæ
let installation : NCMBInstallation = NCMBInstallation.currentInstallation
//Device Tokenãèšå®
installation.setDeviceTokenFromData(data: deviceToken)
//端æ«æ
å ±ãããŒã¿ã¹ãã¢ã«ç»é²
installation.saveInBackground(callback: { result in
switch result {
case .success:
//端æ«æ
å ±ã®ç»é²ãæåããå Žåã®åŠç
print("ä¿åã«æåããŸãã")
case let .failure(error):
//端æ«æ
å ±ã®ç»é²ã倱æããå Žåã®åŠç
print("ä¿åã«å€±æããŸãã: \(error)")
return;
}
})
}
// ããã·ã¥éç¥ãåä¿¡ãããšãã®åŠç
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],fetchCompletionHandler completionHandler:@escaping (UIBackgroundFetchResult) -> Void) {
if let notiData = userInfo as? [String : AnyObject] {
// MARK: ãªããããã·ã¥éç¥ã衚瀺ããã
NCMBPush.handleRichPush(userInfo: notiData)
}
}
// 以äžçç¥
}
- Xcodeã§ãããžã§ã¯ããéžæããŠããSigning & CapabilitiesããéããŸã
- ã+Capabilityããã¯ãªãã¯ããŠãæ€çŽ¢æ¬ã«ãBackground Modesããšå ¥åãè¿œå ããŸã
- è¿œå åŸããRemote notificationsãã«ãã§ãã¯ãå ¥ãæå¹ã«ããŸã