如何注册用户的ios设备以从AppDelegate以外的其他地方接收推送消息? [英] How can I register user's ios device for receiving push messages from place other than AppDelegate?
问题描述
当前在didFinishLaunchingWithOptions
的appDelegate
中,我正在调用以下方法:
Currently in my appDelegate
in didFinishLaunchingWithOptions
I'm calling the following methods:
let notificationTypes: UIUserNotificationType = [UIUserNotificationType.alert, UIUserNotificationType.badge, UIUserNotificationType.sound]
let pushNotificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: nil)
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()
我在AppDelegate
中也实现了以下方法:
I also have the following methods implemented in AppDelegate
:
didRegisterForRemoteNotificationsWithDeviceToken
didFailToRegisterForRemoteNotificationsWithError
didReceiveRemoteNotification
当用户首次启动我的应用程序时,他会看到弹出窗口,询问他是否允许接收推送消息.
When user starts my app for the first time, he sees the popup that ask him for permission about receiving push messages.
我想推迟显示此弹出窗口,直到用户在设置"菜单中手动选择特定选项为止.
I want to postpone showing this popup until user manually chooses specific option in Settings menu.
在设置"菜单中,我有一个UISwitch
,每次用户更改它时,我都会检查它的状态:
In Settings menu I have a UISwitch
and I'm checking the state of it every time user changes it:
func messagesStateChanged(_ sender: UISwitch){
if(sender.isOn){
defaults.set("true", forKey: "popupMessages")
defaults.synchronize()
} else {
defaults.set("false", forKey: "popupMessages")
defaults.synchronize()
}
}
是否可以将push
处理从应用程序委托移到设置菜单,以便用户在启动应用程序后立即看到弹出窗口,而选择了UISwitch
时会看到弹出窗口?另外-如果将来将其移到设置"类,那么将来是否可以使用所有push
功能?
Is there a way of moving the push
handling from app delegate to the settings menu, so that user sees the popup not immediately after starting the app, but when he selects the UISwitch
? Also - will that work for future and all push
functionality works well if I move it to Settings class?
推荐答案
您可以通过访问应用程序中任何位置的UIApplication.shared
类属性来访问didFinishLaunchingWithOptions
中提供给您的UIApplication
实例. UIKit
.我通常会创建一个用于管理通知的包装器类,该类将允许您在稍后编写单元测试时注入UIApplication
依赖项.
You can access the UIApplication
instance provided to you in didFinishLaunchingWithOptions
by accessing UIApplication.shared
class property from anywhere in your application, where you have access to UIKit
. I usually create a wrapper class that manages notifications, which would allow you to inject UIApplication
dependency when you're writing unit tests later.
在激活开关时应该会发生注册调用:
func messagesStateChanged(_ sender: UISwitch){
if(sender.isOn){
defaults.set("true", forKey: "popupMessages")
defaults.synchronize()
let application = UIApplication.shared
let notificationTypes: UIUserNotificationType = [UIUserNotificationType.alert, UIUserNotificationType.badge, UIUserNotificationType.sound]
let pushNotificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: nil)
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()
} else {
defaults.set("false", forKey: "popupMessages")
defaults.synchronize()
}
}
我使用的简化包装器类(为简单起见,使用单包):
A simplified wrapper class I use (singleton used for simplicity):
class NotificationManager {
static var shared = NotificationManager()
private var application : UIApplication?
func setup(application: UIApplication) {
self.application = application
}
func register () {
guard let application = application else {
print("Attempt to register without calling setup")
return
}
let notificationTypes: UIUserNotificationType = [UIUserNotificationType.alert, UIUserNotificationType.badge, UIUserNotificationType.sound]
let pushNotificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: nil)
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()
}
}
这要求您在didFinishLaunchingMethod
中调用设置程序:
This requires that you call setup in your didFinishLaunchingMethod
:
NotificationManager.shared.setup(application: application)
但是,无论您需要注册通知的地方为何,
But then wherever you need to register for the notifications:
func messagesStateChanged(_ sender: UISwitch){
if(sender.isOn){
...
NotificationManager.shared.register()
}
...
}
这允许您稍后通过注入UIApplication
模拟对象来轻松测试NotificationManager
类,并且该类还很好地封装了所有与通知相关的逻辑.经过一些修改,它可以轻松跟踪是否已注册,跟踪收到的推送令牌,甚至处理iOS 8/9向后兼容性,而无需复制样板代码.
This allows you to easily test NotificationManager
class by injecting an UIApplication
mock object later on and the class also nicely encapsulates all notification related logic. With some modifications it can easily keep track if you already registered, keep track of the push token you received and even handle iOS 8/9 backward compatibility without duplicating boilerplate code.
这篇关于如何注册用户的ios设备以从AppDelegate以外的其他地方接收推送消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!