Должен ли `registerUserNotificationSettings:` вызываться во время цикла запуска приложения?

ios iphone permissions push-notification uikit

968 просмотра

1 ответ

5677 Репутация автора

В документах дляregisterUserNotificationSettings: государства:

Если ваше приложение отображает оповещения, воспроизводит звуки или значок на значке, вы должны вызывать этот метод во время цикла запуска, чтобы запросить разрешение на оповещение пользователя этими способами.

Я был разочарован, прочитав это, так как приложение выглядит грубым, когда запрашивает разрешение на отправку push-уведомлений, прежде чем в этом есть необходимость. Например, в приложении, которое я разрабатываю, пользователь должен создать учетную запись в нашем онлайн-сервисе, прежде чем отправлять push-уведомления. И может случиться так, что пользователь никогда не регистрируется, просто использует приложение локально, поэтому нет никаких причин спрашивать. Но если я могу только спросить при запуске приложения, это означает, что пользователю придется создать учетную запись, закрыть приложение, а затем снова запустить его, прежде чем мы сможем спросить. Кажется странным

Это действительно необходимо? Я попытался поместить вызов registerUserNotificationSettings:в более релевантную часть приложения, но затем приложение никогда не запрашивало разрешение на отправку push-уведомлений. Это просто политика для push-уведомлений iOS, или есть какой-то способ повысить гибкость в отношении того, когда запрашивать разрешение на отправку push-уведомлений?

Автор: theory Источник Размещён: 18.07.2016 12:39

Ответы (1)


4 плюса

5677 Репутация автора

Решение

Первоначальный вызов -registerForNotificationsне должен вызываться во время цикла запуска приложения. Однако после этого первого вызова он всегда должен вызываться во время цикла запуска приложения.

Здесь было две проблемы: одна моя и одна из сторонней службы, которую я использовал для push-уведомлений. Моя проблема заключалась в том, что я увольнял контроллер представления, который вызывал -registerForNotificationsпосле его возвращения; Я не понимал, что это работает асинхронно. Поэтому я добавил -application:didRegisterUserNotificationSettingsв свое приложение делегата. Этот метод вызывается после того, как пользователь ответил на приглашение -registerForNotifications, и я отправил ему уведомление. Перед вызовом -registerForNotificationsя настроил прослушиватель для этого уведомления и отклонил контроллер представления только после получения уведомления. Как бы то ни было, есть делегат или блок для указания вместо этого, но это не так.

И я подозреваю , что причина здесь не потому , что IOS действительно хочет , чтобы вы звоните -registerForNotificationsв application:didFinishLaunchingWithOptions:, так что это естественно для асинхронной обратного вызова просто еще один метод в приложении делегата. [Удалено немного о необходимости перезапустить приложение, чтобы фактически получать push-уведомления. Добавление:] Другая проблема заключалась в том, что сторонний сервис, который я использовал для push-уведомлений, который все еще находится в альфа-режиме, часто не отправлял push-уведомления. Как только это было исправлено, они начали работать, как только я одобрил push-уведомления, независимо от того, пришло ли приглашение во время запуска приложения или позже. [/ Added]

Итак, вот полная картина:

  • В application:didFinishLaunchingWithOptions:вызове метода делегата приложения, -registerForNotificationsесли пользователь по умолчанию был установлен:

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        if NSUserDefaults.standardUserDefaults().boolForKey("registedNotificationSettings") {
            self.registerForNotifications()
        }
        return true
    }
    
  • В -application:didRegisterUserNotificationSettings:методе делегата приложения настройте удаленные уведомления, сохраните значение по умолчанию для пользователя и опубликуйте уведомление:

    func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
        if notificationSettings.types != .None {
            application.registerForRemoteNotifications()
        }
        let defaults = NSUserDefaults.standardUserDefaults()
        if !defaults.boolForKey( "registedNotificationSettings") {
            defaults.setBool(true, forKey: "registedNotificationSettings")
            defaults.synchronize()
        }
        NSNotificationCenter.defaultCenter().postNotification(
            NSNotification(name: "RegistedNotificationSettings", object: notificationSettings)
        )
    }
    
  • В моем контроллере представления при нажатии кнопки прослушайте это уведомление, затем запросите разрешение на отправку push-уведомлений:

    @IBAction func okayButtonTapped(sender: AnyObject) {
        NSNotificationCenter.defaultCenter().addObserver(
            self,
            selector: #selector(didRegisterNotificationSettings(_:)),
            name: "RegistedNotificationSettings",
            object: nil
        )
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        appDelegate.registerForNotifications()
    }
    
  • Тогда, конечно, нам понадобится метод уведомления, который отклоняет контроллер представления, когда разрешение было предоставлено, и должен делать что-то еще, когда он не имеет:

    func didRegisterNotificationSettings(notification: NSNotification) {
        let status = notification.object as! UIUserNotificationSettings
        if status.types != .None {
            // Yay!
            self.done()
            return
        }
    
        // Tell them a little more about it.
        NSLog("User declined push notifications")
        self.done()
    }
    

При такой конфигурации все работает [Удалена неверная информация о -registerForNotificationsвремени вызова] и не запрашивает пользователя при запуске приложения.

Автор: theory Размещён: 15.08.2016 08:37
Вопросы из категории :
32x32