问题 如何控制何时在iOS中提示用户推送通知权限


我使用Swift和Xcode 6构建了一个iPhone应用程序,并使用Parse框架来处理服务。

在关于如何设置推送通知的Parse教程之后,指示建议我将推送通知放在App Delegate文件中。

这是我添加到App Delegate文件的代码...

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var pushNotificationsController: PushNotificationController?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

         // Register for Push Notifications
        self.pushNotificationsController = PushNotificationController()

        if application.respondsToSelector("registerUserNotificationSettings:") {
            println("registerUserNotificationSettings.RegisterForRemoteNotificatios")
            let userNotificationTypes: UIUserNotificationType = (.Alert | .Badge | .Sound)
            let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: userNotificationTypes, categories: nil)
            application.registerUserNotificationSettings(settings)
            application.registerForRemoteNotifications()
        }

        return true;
    }

    func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
        println("didRegisterForRemoteNotificationsWithDeviceToken")
        let installation = PFInstallation.currentInstallation()
        installation.setDeviceTokenFromData(deviceToken)
        installation.saveInBackground()
    }
}

所以会发生的情况是,第一次启动应用程序时,系统会提示用户授予这些权限。

我想要做的只是在某个动作发生后(即,在应用程序功能的演练期间)提示这些权限,所以我可以提供更多关于为什么我们希望它们允许推送通知的上下文。

是否只是在相关的ViewController中复制下面的代码,我希望提示用户?

// In 'MainViewController.swift' file

func promptUserToRegisterPushNotifications() {
        // Register for Push Notifications
        self.pushNotificationsController = PushNotificationController()

        if application.respondsToSelector("registerUserNotificationSettings:") {
            println("registerUserNotificationSettings.RegisterForRemoteNotificatios")
            let userNotificationTypes: UIUserNotificationType = (.Alert | .Badge | .Sound)
            let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: userNotificationTypes, categories: nil)
            application.registerUserNotificationSettings(settings)
            application.registerForRemoteNotifications()
        }
}

func application(application: UIApplication,    didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
        println("didRegisterForRemoteNotificationsWithDeviceToken")
        let installation = PFInstallation.currentInstallation()
        installation.setDeviceTokenFromData(deviceToken)
        installation.saveInBackground()
}

谢谢!


1365
2018-06-13 09:26


起源

是的,您可以简单地移动该代码以在适当的时间执行:) - SomeGuy
谢谢SomeGuy!我会在我回到项目后立即尝试并报告我是否需要更多帮助。谢谢! - Simon
你如何获得应用程序:UIApplication到另一个viewController? - denislexic
嘿,如果有帮助,你会介意接受我的答案吗? :) - LinusGeffarth
@denislexic,我所做的是在viewController中声明了一个全局变量,例如 let application: UIApplication = UIApplication.sharedApplication()。这似乎对我有用。 :) - Simon


答案:


答案很简单。如果您希望在其他时间提示用户,例如按下按钮,则只需将有关请求的代码移动到该功能(或调用) promptUserToRegisterPushNotifications() 来自其他地方)。

抓住了 application AppDelegate外部的变量,只需执行以下操作:

let application = UIApplication.shared

希望有所帮助:)


5
2018-06-13 09:32



谢谢Linus。 :)我现在离开我的电脑试试这个,这就是我的假设,所以谢谢你的澄清。 :)将尝试并报告反馈!谢谢! - Simon
嗨,Linus,不管你信不信,我现在才开始实施这个解决方案。所以我按照你的建议做了并且移动了 promptUserToRegisterPushNotifications () 一个不同的视图控制器的方法,但现在我得到了上面的Denislexic带来的问题...我如何引用 application : UIApplication 将设置保存到我的MainViewController.swift文件中? - Simon
没问题;)啊,你为什么不把整个 promptUserToRegisterPushNotifications() 进入MainVC的方法? - LinusGeffarth
我做到了,但在方法中有一个 if application.respondsToSelector("registerUserNotificationSettings:") 我的MainVC对此一无所知 application。我不确定我是否需要声明一个实例 application 在MainVC?如果是这样,怎么样? - Simon
很酷,所以我找到了'应用'问题的解决方案。我只是在我的MainViewController中声明了一个 application 像变量一样 let application: UIApplication = UIApplication.sharedApplication()。这解决了我的问题。 :)谢谢Linus! - Simon


这是针对Swift 2.我在MainViewController.swift中放置了promptUserToRegisterPushNotifications(),但我在AppDelegate中保留了didRegisterForRemoteNotificationsWithDeviceToken,因为当我将它放在同一个MainViewController.swift上时它不起作用。

// In 'MainViewController.swift' file
func promptUserToRegisterPushNotifications() {
    // Register for Push Notifications

    let application: UIApplication = UIApplication.sharedApplication()

    if application.respondsToSelector(#selector(UIApplication.registerUserNotificationSettings(_:))) {
        print("registerUserNotificationSettings.RegisterForRemoteNotificatios")

        let notificationSettings = UIUserNotificationSettings(
            forTypes: [.Badge, .Sound, .Alert], categories: nil)
        application.registerUserNotificationSettings(notificationSettings) // Register for Remote Push Notifications
        application.registerForRemoteNotifications()
    }
}


// In AppDelegate
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
    let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
    var tokenString = ""

    for i in 0..<deviceToken.length {
        tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
    }

    NSUserDefaults.standardUserDefaults().setObject(tokenString, forKey: "deviceToken")

    print("Device Token:", tokenString)

}

3
2018-05-26 09:58





这是我在代码中编写的方法,一旦调用启动就可以正常工作(didFinishLaunch)

class func registerNotification() {
    if #available(iOS 10.0, *) {
        // push notifications
        UNUserNotificationCenter.current().requestAuthorization(options: [.sound, .alert, .badge]) {
            (granted, error) in
            if (granted) {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }

        let center  = UNUserNotificationCenter.current()
        center.delegate = AppManager.appDel()
        center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
            if error == nil {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    } else {
        UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))
        UIApplication.shared.registerForRemoteNotifications()
    }
}

1
2017-07-25 07:07