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

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

问题描述

目前在我的 appDelegate 中的 didFinishLaunchingWithOptions 我正在调用以下方法:

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?另外 - 如果我将其移至 Settings 类,这是否适用于未来并且所有 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 中调用 setup:

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屋!

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