如何在 Swift 中设置推送通知
Posted
技术标签:
【中文标题】如何在 Swift 中设置推送通知【英文标题】:How to set up push notifications in Swift 【发布时间】:2014-07-22 22:59:44 【问题描述】:我正在尝试为我的应用程序设置推送通知系统。我有一个服务器和一个开发者许可证来设置推送通知服务。
我目前正在 Swift 中运行我的应用程序。我希望能够从我的服务器远程发送通知。我该怎么做?
【问题讨论】:
【参考方案1】:斯威夫特 2:
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()
【讨论】:
没有收到委托回叫...我已经尝试了所有可能的解决方案:网络正常,所有端口都打开,证书和配置文件正常,App ID 支持推送通知和推送功能通知已开启……最奇怪的是,相同的代码 sn-p 在 Objective-c 项目中运行良好(使用相同的证书、配置文件和互联网连接)……【参考方案2】:虽然处理推送通知的答案很好,但我仍然相信立即分享集成的完整案例以缓解:
为APNS注册应用程序,(在AppDelegate.swift中的didFinishLaunchingWithOptions方法中包含以下代码)
IOS 9
var settings : UIUserNotificationSettings = UIUserNotificationSettings(forTypes:UIUserNotificationType.Alert|UIUserNotificationType.Sound, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()
IOS 10 之后
引入 UserNotifications 框架:
导入UserNotifications框架,在AppDelegate.swift中添加UNUserNotificationCenterDelegate
注册申请APNS
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options:[.badge, .alert, .sound]) (granted, error) in
// If granted comes true you can enabled features based on authorization.
guard granted else return
application.registerForRemoteNotifications()
这将调用以下委托方法
func application(application: UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)
//send this device token to server
//Called if unable to register for APNS.
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError)
println(error)
收到通知后,代表将致电:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject])
println("Recived: \(userInfo)")
//Parsing userinfo:
var temp : NSDictionary = userInfo
if let info = userInfo["aps"] as? Dictionary<String, AnyObject>
var alertMsg = info["alert"] as! String
var alert: UIAlertView!
alert = UIAlertView(title: "", message: alertMsg, delegate: nil, cancelButtonTitle: "OK")
alert.show()
要确定我们可以使用的权限:
UNUserNotificationCenter.current().getNotificationSettings() (setttings) in
switch setttings.soundSetting
case .enabled:
print("enabled sound")
case .disabled:
print("not allowed notifications")
case .notSupported:
print("something went wrong here")
那么 APNS 的清单:
使用推送通知创建 AppId 允许 使用有效的证书和应用 ID 创建 SSL 证书 创建具有相同证书的配置文件,并确保添加设备以防沙箱(开发配置)注意:如果在 SSL 证书之后创建配置文件会很好。
带代码:
为推送通知注册应用程序 处理 didRegisterForRemoteNotificationsWithDeviceToken 方法 设置目标>能力>后台模式>远程通知 处理 didReceiveRemoteNotification【讨论】:
谢谢!它特别有助于解析用户信息。 UIAlertView 已弃用。改为使用 UIAlertController 和 UIAlertControllerStyleAlert 的preferredStyle。 您能否编辑您的答案,并展示如何使用 UIAlertController 自定义声音? @XcodeNOOB : 准确分享,你在找什么? @Arvind 我正在尝试显示与默认声音不同的警报。声音将来自 ios 系统中的库/声音。但无论我做什么,我都会得到默认声音(我知道可以从服务器端更改它,但我想从设备更改它,因为用户可以选择自己的声音)。现在在您的代码中,我可以看到您创建了 UIAlertView,如果您也可以共享代码以对其进行自定义,这样当警报出现时会听到不同的声音,那就太好了。【参考方案3】:要注册通过 Apple 推送服务接收推送通知,您必须调用 UIApplication
的 registerForRemoteNotifications()
方法。
如果注册成功,应用程序会调用您的应用程序委托对象的application:didRegisterForRemoteNotificationsWithDeviceToken:
方法并将设备令牌传递给它。
您应该将此令牌传递给您用来为设备生成推送通知的服务器。如果注册失败,则应用调用其应用代理的application:didFailToRegisterForRemoteNotificationsWithError:
方法。
查看Local and Push Notification Programming Guide。
【讨论】:
registerForRemoteNotifications()
只能从iOS 8
获得,iOS 7
应该用什么?
@JoshHarington iOS 7 不是在 在 Swift 之前发布的吗?
@11684 Swift 通过在应用程序中捆绑标准库来支持 iOS 7。
记得在 Target Settings -> Capabilities 中切换 ON Push Notifications
。
你为什么要用iOS7??【参考方案4】:
registerForRemoteNotification()
已从 ios8 中删除。
所以你应该使用UIUserNotification
代码示例:
var type = UIUserNotificationType.Badge | UIUserNotificationType.Alert | UIUserNotificationType.Sound;
var setting = UIUserNotificationSettings(forTypes: type, categories: nil);
UIApplication.sharedApplication().registerUserNotificationSettings(setting);
UIApplication.sharedApplication().registerForRemoteNotifications();
希望这会对你有所帮助。
【讨论】:
不要忘记这仅适用于 iOS 8+。如果您还想支持 iOS 7,请参阅***.com/a/28742391/131183 仅供参考,这不再适用于 Swift 2。对于 Swift 2,请参阅下面的 @AdamWaite 答案【参考方案5】:要支持 ios 8 及之前版本,请使用:
// Register for Push Notitications, if running iOS 8
if application.respondsToSelector("registerUserNotificationSettings:")
let types:UIUserNotificationType = (.Alert | .Badge | .Sound)
let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: types, categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
else
// Register for Push Notifications before iOS 8
application.registerForRemoteNotificationTypes(.Alert | .Badge | .Sound)
【讨论】:
【参考方案6】:斯威夫特 4
我认为这是在iOS 8
及以上设置的正确方法。
在Capabilities
选项卡中打开Push Notifications
导入UserNotifications
import UserNotifications
修改didFinishLaunchingWithOptions
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
if let notification = launchOptions?[.remoteNotification] as? [String: AnyObject]
// If your app wasn’t running and the user launches it by tapping the push notification, the push notification is passed to your app in the launchOptions
let aps = notification["aps"] as! [String: AnyObject]
UIApplication.shared.applicationIconBadgeNumber = 0
registerForPushNotifications()
return true
每次启动应用时都致电
registerUserNotificationSettings(_:)
非常重要。这是因为用户可以随时进入“设置”应用并更改通知权限。application(_:didRegisterUserNotificationSettings:)
将始终为您提供用户当前对您的应用允许的权限。
复制粘贴这个AppDelegate
扩展
// Push Notificaion
extension AppDelegate
func registerForPushNotifications()
if #available(iOS 10.0, *)
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge])
[weak self] (granted, error) in
print("Permission granted: \(granted)")
guard granted else
print("Please enable \"Notifications\" from App Settings.")
self?.showPermissionAlert()
return
self?.getNotificationSettings()
else
let settings = UIUserNotificationSettings(types: [.alert, .sound, .badge], categories: nil)
UIApplication.shared.registerUserNotificationSettings(settings)
UIApplication.shared.registerForRemoteNotifications()
@available(iOS 10.0, *)
func getNotificationSettings()
UNUserNotificationCenter.current().getNotificationSettings (settings) in
print("Notification settings: \(settings)")
guard settings.authorizationStatus == .authorized else return
DispatchQueue.main.async
UIApplication.shared.registerForRemoteNotifications()
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
let tokenParts = deviceToken.map data -> String in
return String(format: "%02.2hhx", data)
let token = tokenParts.joined()
print("Device Token: \(token)")
//UserDefaults.standard.set(token, forKey: DEVICE_TOKEN)
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error)
print("Failed to register: \(error)")
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any])
// If your app was running and in the foreground
// Or
// If your app was running or suspended in the background and the user brings it to the foreground by tapping the push notification
print("didReceiveRemoteNotification /(userInfo)")
guard let dict = userInfo["aps"] as? [String: Any], let msg = dict ["alert"] as? String else
print("Notification Parsing Error")
return
func showPermissionAlert()
let alert = UIAlertController(title: "WARNING", message: "Please enable access to Notifications in the Settings app.", preferredStyle: .alert)
let settingsAction = UIAlertAction(title: "Settings", style: .default) [weak self] (alertAction) in
self?.gotoAppSettings()
let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
alert.addAction(settingsAction)
alert.addAction(cancelAction)
DispatchQueue.main.async
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
private func gotoAppSettings()
guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else
return
if UIApplication.shared.canOpenURL(settingsUrl)
UIApplication.shared.openURL(settingsUrl)
签出:Push Notifications Tutorial: Getting Started
【讨论】:
application:didFailToRegisterForRemoteNotificationsWithError
在用户拒绝或存在其他网络错误或两者兼有时调用?
show(alert: alert) 和 registerForPushNotifications(application) 在您的代码中有问题 当我将您的应用程序复制到我的应用程序委托类时,我会收到这些错误 使用未解析的标识符“show”和传递给的参数不带参数的调用
在这个问题上需要帮助:- ***.com/questions/52676650/…【参考方案7】:
感谢之前的回答。 Xcode 进行了一些更改,以下是通过 XCode 7 代码检查并支持 iOS 7 及更高版本的 SWIFT 2 代码:
if #available(iOS 8.0, *)
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()
else
let settings = UIRemoteNotificationType.Alert.union(UIRemoteNotificationType.Badge).union(UIRemoteNotificationType.Sound)
UIApplication.sharedApplication().registerForRemoteNotificationTypes(settings)
【讨论】:
【参考方案8】:斯威夫特 4
导入UserNotifications框架,在AppDelegate中添加UNUserNotificationCenterDelegate
import UserNotifications
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate
为APNS注册应用程序,(在AppDelegate.swift中的didFinishLaunchingWithOptions方法中包含以下代码)
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options:[.badge, .alert, .sound]) (granted, error) in
// Enable or disable features based on authorization.
application.registerForRemoteNotifications()
这将调用以下委托方法
func application(_ application: UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
//send this device token to server
//Called if unable to register for APNS.
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error)
print(error)
收到通知后,代表将致电:
private func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject])
print("Recived: \(userInfo)")
//Parsing userinfo:
【讨论】:
【参考方案9】:斯威夫特 3:
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options:[.badge, .alert, .sound]) (granted, error) in
// Enable or disable features based on authorization.
UIApplication.shared.registerForRemoteNotifications()
确保在视图控制器的顶部导入 UserNotifications。
import UserNotifications
【讨论】:
【参考方案10】:您可以使用以下代码 sn-p 发送通知:
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
if(UIApplication.sharedApplication().currentUserNotificationSettings() == settings )
//OK
else
//KO
【讨论】:
【参考方案11】:我在 AppDelegate.swift 中使用这个代码片段:
let pushType = UIUserNotificationType.alert.union(.badge).union(.sound)
let pushSettings = UIUserNotificationSettings(types: pushType
, categories: nil)
application.registerUserNotificationSettings(pushSettings)
application.registerForRemoteNotifications()
【讨论】:
【参考方案12】:100% 工作中... 您可以正确读取一个信号文档并进行设置https://documentation.onesignal.com/docs/ios-sdk-setup OneSignal 下面的代码导入 AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
// Override point for customization after application launch.
OneSignal.setLogLevel(.LL_VERBOSE, visualLevel: .LL_NONE)
// OneSignal initialization
let onesignalInitSettings = [kOSSettingsKeyAutoPrompt: false, kOSSettingsKeyInAppLaunchURL: false]
OneSignal.initWithLaunchOptions(launchOptions,
appId: "YOUR_ONE_SIGNAL_ID",
handleNotificationAction: nil,
settings: onesignalInitSettings)
OneSignal.inFocusDisplayType = OSNotificationDisplayType.inAppAlert;
// promptForPushNotifications will show the native iOS notification permission prompt.
// We recommend removing the following code and instead using an In-App Message to prompt for notification permission (See step 8)
OneSignal.promptForPushNotifications(userResponse: accepted in
print("User accepted notifications: \(accepted)")
)
return true
【讨论】:
以上是关于如何在 Swift 中设置推送通知的主要内容,如果未能解决你的问题,请参考以下文章
XCUITest - 如何访问 XCUITest 中的应用设备令牌以触发推送通知,但无需在应用代码中设置任何 UIView?
iOS Swift App 不会收到 Parse Server 发送的推送通知