如何注册用户的ios设备以从Ap​​pDelegate以外的其他地方接收推送消息? [英] How can I register user's ios device for receiving push messages from place other than AppDelegate?

查看:89
本文介绍了如何注册用户的ios设备以从Ap​​pDelegate以外的其他地方接收推送消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前在didFinishLaunchingWithOptionsappDelegate中,我正在调用以下方法:

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设备以从Ap​​pDelegate以外的其他地方接收推送消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆