Регистрация для push-уведомлений в Xcode 8/Swift 3.0?

Я пытаюсь заставить свое приложение работать в Xcode 8.0 и сталкиваюсь с ошибкой. Я знаю, что этот код отлично работал в предыдущих версиях Swift, но я предполагаю, что код для этого изменен в новой версии. Вот код, который я пытаюсь запустить:

let settings = UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge], categories: nil)     
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.shared().registerForRemoteNotifications()

Ошибка, которую я получаю: «Ярлыки аргументов» (forTypes:, category:) «не соответствуют доступным перегрузкам»

Есть ли другая команда, которую я мог бы попытаться заставить это работать?


person Asher Hawthorne    schedule 22.06.2016    source источник
comment
Я написал руководство о том, как это сделать: eladnava.com/   -  person Elad Nava    schedule 07.10.2016


Ответы (11)


Импортируйте фреймворк UserNotifications и добавьте UNUserNotificationCenterDelegate в AppDelegate.swift.

Запросить разрешение пользователя

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


        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
            // Enable or disable features based on authorization.
        }
        application.registerForRemoteNotifications()
        return true
}

Получение токена устройства

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

    let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
    print(deviceTokenString)
}

В случае ошибки

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {

        print("i am not available in simulator \(error)")
}

В случае, если вам нужно знать предоставленные разрешения

UNUserNotificationCenter.current().getNotificationSettings(){ (settings) in

            switch settings.soundSetting{
            case .enabled:

                print("enabled sound setting")

            case .disabled:

                print("setting has been disabled")

            case .notSupported:
                print("something vital went wrong here")
            }
        }
person Anish Parajuli 웃    schedule 22.06.2016
comment
Я получаю сообщение об ошибке в swift 2.3: UNUserNotificationCenter не имеет текущего члена - person Async-; 02.08.2016
comment
Эй, можешь ли ты предоставить сохранение в цели с? - person Ayaz; 20.09.2016
comment
Просто примечание, больше не возвращает токен устройства. По крайней мере, в моем случае он просто возвращает 32 байта. - person Brian F Leighty; 27.09.2016
comment
@BrianFLeighty Спасибо, я отредактировал комментарий ast1 - person Anish Parajuli 웃; 28.09.2016
comment
@Async- Вы не видите current(), потому что он работает только в Swift 3. - person Allen; 29.09.2016
comment
Не забудьте связать UserNotifications.framework со своей целью и импортировать его в свой AppDelegate. ;) - person n3wbie; 05.10.2016
comment
Как я могу зарегистрироваться для получения удаленных уведомлений за пределами AppDelegate? Я не хочу, чтобы всплывающие окна были первым, что происходит, когда пользователь открывает приложение. - person KML; 14.11.2016
comment
@Anish웃 Привет, было бы здорово, если бы ты предложил здесь ответы на мои вопросы! :) stackoverflow.com/questions/40587598/ - person KML; 14.11.2016
comment
@KML просто оберните этот блок операторов let center = UNUserNotificationCenter.current() center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in // Enable or disable features based on authorization. } application.registerForRemoteNotifications() внутри метода в AppDelegate. И вызовите метод-оболочку из любого места, получив ссылку AppDelegate. Сохраняйте эти методы на didFinishLaunchingWithOptions запросе разрешения, как только приложение будет запущено. Так что делайте, как я сказал ранее. - person Anish Parajuli 웃; 14.11.2016
comment
Заранее спасибо и извините за следующий вопрос, который возникает просто из-за недостатка опыта и знаний: Каково назначение deviceToken, для чего он используется? - person LukeSideWalker; 04.02.2017
comment
@LukeSideWalker Маркер устройства представляет собой идентификатор устройства, получающего уведомление. APN использует токены устройств для идентификации каждой уникальной комбинации приложения и устройства. Подробнее: здесь - person Anish Parajuli 웃; 05.02.2017
comment
В закрытии вам нужно будет выполнить задачи, связанные с пользовательским интерфейсом, в основном потоке... DispatchQueue.main.async {... обновить метку...} - person Chris Allinson; 23.02.2017
comment
@ChrisAllinson обратный вызов всегда находится в основном потоке после завершения операции. - person Anish Parajuli 웃; 23.02.2017
comment
Я получил неразрешенный идентификатор: «UNUserNotificationCenter». Знаете почему? Я использую Swift 3.1 - person Pavlos; 23.04.2017
comment
@PavlosNicolaou Импортируйте структуру UserNotifications - person Anish Parajuli 웃; 23.04.2017
comment
@ThatlazyiOSGuy웃 Можете ли вы рассказать мне пошаговую процедуру, если пользователь зарегистрируется на веб-сайте, приложение получит уведомления - person Dilip Tiwari; 19.09.2017
comment
application.registerForRemoteNotifications() идет первым, затем запрашивает разрешение. Первый шаг просто может получить несколько обратных вызовов от системы iOS в AppDelegate didRegisterForRemoteNotificationsWithDeviceToken, если вы включите и выключите переключатель уведомлений несколько раз. - person DawnSong; 12.02.2018
comment
как добавить/инициировать несколько уведомлений? - person ArgaPK; 05.03.2018

import UserNotifications  

Затем перейдите в редактор проекта для вашей цели и на вкладке «Общие» найдите раздел «Связанные платформы и библиотеки».

Нажмите + и выберите UserNotifications.framework:

// iOS 12 support
if #available(iOS 12, *) {  
    UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound, .provisional, .providesAppNotificationSettings, .criticalAlert]){ (granted, error) in }
    application.registerForRemoteNotifications()
}

// iOS 10 support
if #available(iOS 10, *) {  
    UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]){ (granted, error) in }
    application.registerForRemoteNotifications()
}
// iOS 9 support
else if #available(iOS 9, *) {  
    UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))
    UIApplication.shared.registerForRemoteNotifications()
}
// iOS 8 support
else if #available(iOS 8, *) {  
    UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))
    UIApplication.shared.registerForRemoteNotifications()
}
// iOS 7 support
else {  
    application.registerForRemoteNotifications(matching: [.badge, .sound, .alert])
}

Используйте методы делегата уведомлений

// Called when APNs has assigned the device a unique token
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {  
    // Convert token to string
    let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
    print("APNs device token: \(deviceTokenString)")
}

// Called when APNs failed to register the device for push notifications
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {  
    // Print the error to console (you should alert the user that registration failed)
    print("APNs registration failed: \(error)")
}

Для получения push-уведомлений

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    completionHandler(UIBackgroundFetchResult.noData)
}

Настройка push-уведомлений включает функцию в Xcode 8 для вашего приложения. Просто перейдите в редактор проектов для вашей цели и затем нажмите на вкладку Возможности. Найдите Push-уведомления и установите для него значение ВКЛ.

Проверьте ссылку ниже, чтобы узнать больше о методах делегирования уведомлений.

Обработка локальных и удаленных уведомлений UIApplicationDelegateОбработка локальных и удаленных уведомлений

https://developer.apple.com/reference/uikit/uiapplicationdelegate

person Mohamed Jaleel Nazir    schedule 09.03.2017

У меня были проблемы с ответами здесь при преобразовании объекта данных deviceToken в строку для отправки на мой сервер с текущей бета-версией Xcode 8. Особенно тот, который использовал deviceToken.description, как в 8.0b6, который возвращал бы «32 байта», который не очень полезно :)

Это то, что сработало для меня...

Создайте расширение для Data, чтобы реализовать метод hexString:

extension Data {
    func hexString() -> String {
        return self.reduce("") { string, byte in
            string + String(format: "%02X", byte)
        }
    }
}

А затем используйте это, когда вы получите обратный вызов от регистрации для удаленных уведомлений:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let deviceTokenString = deviceToken.hexString()
    // Send to your server here...
}
person tomwilson    schedule 27.08.2016
comment
У меня также была проблема с 32 байтами. Отличное решение, вы можете сделать преобразование в режиме реального времени без создания расширения. Вот так: let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)}) - person Alain Stulz; 31.08.2016
comment
Абсурдно, что нет решения, исходящего от самого API. - person Aviel Gross; 14.09.2016
comment
Да, этот API всегда был довольно странным... удивлен, что они не исправили его при создании новой структуры уведомлений в iOS10. - person tomwilson; 03.11.2016

В iOS10 вместо вашего кода вы должны запросить авторизацию для уведомления со следующим: (не забудьте добавить UserNotifications Framework)

if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().requestAuthorization([.alert, .sound, .badge]) { (granted: Bool, error: NSError?) in
            // Do something here
        }
    }

Кроме того, правильный код для вас (например, используйте в else предыдущего условия):

let setting = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
UIApplication.shared().registerUserNotificationSettings(setting)
UIApplication.shared().registerForRemoteNotifications()

Наконец, убедитесь, что Push Notification активирован в target-> Capabilities -> Push notification. (установите его на On)

person tsnkff    schedule 22.06.2016
comment
см. : Страница 73 документа Apple здесь - person tsnkff; 22.06.2016
comment
Большое спасибо за ответ! Однако, используя код, он говорит об использовании неразрешенного идентификатора «UNUserNotificationCenter». - person Asher Hawthorne; 22.06.2016
comment
И огромное спасибо за документацию, блабабла! Я не видел этого на их сайте, я рад, что он есть. :D - person Asher Hawthorne; 22.06.2016
comment
Подождите, кажется, я понял! Просто пришлось импортировать фреймворк уведомлений. XD - person Asher Hawthorne; 22.06.2016
comment
Ага. Я отредактирую свой ответ, чтобы добавить его для будущих читателей. Также читайте о новых уведомлениях, теперь они стали более мощными и интерактивными. :) - person tsnkff; 22.06.2016
comment
Я так взволнован, я давно хотел добавить push-уведомления в свое приложение (изучаю Xcode в качестве хобби в течение последнего года, но мне еще так много нужно знать), и с новыми уведомлениями я фигура сейчас самое время. Я получил уведомления, работающие с моим разработчиком iPhone, теперь мне просто нужно выяснить, как получить токены для телефонов с рабочей версией и передать их в скрипт php, который я использую. - person Asher Hawthorne; 22.06.2016
comment
Каковы дополнительные преимущества этой новой структуры? То, что я вижу здесь, — это использование подхода «completionHandler вместо делегата», после чего вам сразу предоставляется возможность принять решение: ошибка, предоставлено или не предоставлено… В 6‹ iOS ‹10 вам нужно было сделать ‍application.isRegisteredForRemoteNotifications(), чтобы увидеть предоставлено, и используйте другой метод делегата в случае ошибки. Правильно? Что-нибудь еще? - person Honey; 21.02.2017
comment
Я хочу отображать push-уведомления в активном состоянии для iOS 8.0, я получаю уведомления в фоновом режиме @tsnkff - person Dilip Tiwari; 27.09.2017

Ну, эта работа для меня. Первый в AppDelegate

import UserNotifications

Потом:

   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        registerForRemoteNotification()
        return true
    }

    func registerForRemoteNotification() {
        if #available(iOS 10.0, *) {
            let center  = UNUserNotificationCenter.current()
            center.delegate = self
            center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
                if error == nil{
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }
        else {
            UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.sound, .alert, .badge], categories: nil))
            UIApplication.shared.registerForRemoteNotifications()
        }
    }

Чтобы получить токен устройства:

  func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

       let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})

}
person GoIn Su    schedule 17.10.2016

Обратите внимание, вы должны использовать основной поток для этого действия.

let center = UNUserNotificationCenter.current()
center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
        if granted {
            DispatchQueue.main.async(execute: {
                UIApplication.shared.registerForRemoteNotifications()
            })
        }
    }
person laaksom    schedule 17.10.2017

Во-первых, прослушайте статус уведомления пользователя, т. е. registerForRemoteNotifications(), чтобы получить токен устройства APNs;
во-вторых, запросите авторизацию. При авторизации пользователем deviceToken будет отправлен слушателю, AppDelegate;
третьему, передайте токен устройства на ваш сервер.

extension AppDelegate {
    /// 1. 监听 deviceToken
    UIApplication.shared.registerForRemoteNotifications()

    /// 2. 向操作系统索要推送权限(并获取推送 token)
    static func registerRemoteNotifications() {
        if #available(iOS 10, *) {
            let uc = UNUserNotificationCenter.current()
            uc.delegate = UIApplication.shared.delegate as? AppDelegate
            uc.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
                if let error = error { // 无论是拒绝推送,还是不提供 aps-certificate,此 error 始终为 nil
                    print("UNUserNotificationCenter 注册通知失败, \(error)")
                }
                DispatchQueue.main.async {
                    onAuthorization(granted: granted)
                }
            }
        } else {
            let app = UIApplication.shared
            app.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)) // 获取用户授权
        }
    }

    // 在 app.registerUserNotificationSettings() 之后收到用户接受或拒绝及默拒后,此委托方法被调用
    func application(_ app: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {
        // 已申请推送权限,所作的检测才有效
        // a 征询推送许可时,用户把app切到后台,就等价于默拒了推送
        // b 在系统设置里打开推送,但关掉所有形式的提醒,等价于拒绝推送,得不token,也收不推送
        // c 关掉badge, alert和sound 时,notificationSettings.types.rawValue 等于 0 和 app.isRegisteredForRemoteNotifications 成立,但能得到token,也能收到推送(锁屏和通知中心也能看到推送),这说明types涵盖并不全面
        // 对于模拟器来说,由于不能接收推送,所以 isRegisteredForRemoteNotifications 始终为 false
       onAuthorization(granted: app.isRegisteredForRemoteNotifications)
    }

    static func onAuthorization(granted: Bool) {
        guard granted else { return }
        // do something
    }
}

extension AppDelegate {
    func application(_ app: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        //
    }

    // 模拟器得不到 token,没配置 aps-certificate 的项目也得不到 token,网络原因也可能导致得不到 token
    func application(_ app: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        //
    }
}
person DawnSong    schedule 10.11.2017
comment
как добавить несколько уведомлений? - person ArgaPK; 05.03.2018
comment
@ArgaPK, отправка push-уведомлений - это то, что делает ваша серверная платформа. - person DawnSong; 05.03.2018

Ответ от ast1 очень прост и полезен. Это работает для меня, большое спасибо. Я просто хочу указать это здесь, чтобы люди, которым нужен этот ответ, могли легко его найти. Итак, вот мой код регистрации локального и удаленного (push) уведомления.

    //1. In Appdelegate: didFinishLaunchingWithOptions add these line of codes
    let mynotif = UNUserNotificationCenter.current()
    mynotif.requestAuthorization(options: [.alert, .sound, .badge]) {(granted, error) in }//register and ask user's permission for local notification

    //2. Add these functions at the bottom of your AppDelegate before the last "}"
    func application(_ application: UIApplication, didRegister notificationSettings: UNNotificationSettings) {
        application.registerForRemoteNotifications()//register for push notif after users granted their permission for showing notification
}
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let tokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
    print("Device Token: \(tokenString)")//print device token in debugger console
}
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    print("Failed to register: \(error)")//print error in debugger console
}
person Luthfi Rahman    schedule 19.09.2016

Просто сделайте следующее в didFinishWithLaunching::

if #available(iOS 10.0, *) {

    let center = UNUserNotificationCenter.current()

    center.delegate = self
    center.requestAuthorization(options: []) { _, _ in
        application.registerForRemoteNotifications()
    }
}

Помните об операторе импорта:

import UserNotifications
person Bartłomiej Semańczyk    schedule 10.05.2017
comment
Я считаю, что это должен быть принятый ответ. Кажется правильным вызывать registerForRemoteNotifications() в обработчике завершения requestAuthorization(). Вы даже можете окружить registerForRemoteNotifications() выражением if granted: center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in if granted { UIApplication.shared.registerForRemoteNotifications() } } - person Bocaxica; 28.06.2017

Взгляните на этот закомментированный код:

import Foundation
import UserNotifications
import ObjectMapper

class AppDelegate{

    let center = UNUserNotificationCenter.current()
}

extension AppDelegate {

    struct Keys {
        static let deviceToken = "deviceToken"
    }

    // MARK: - UIApplicationDelegate Methods
    func application(_: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

        if let tokenData: String = String(data: deviceToken, encoding: String.Encoding.utf8) {
            debugPrint("Device Push Token \(tokenData)")
        }

        // Prepare the Device Token for Registration (remove spaces and < >)
        setDeviceToken(deviceToken)
    }

    func application(_: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        debugPrint(error.localizedDescription)
    }

    // MARK: - Private Methods
    /**
     Register remote notification to send notifications
     */
    func registerRemoteNotification() {

        center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in

            // Enable or disable features based on authorization.
            if granted  == true {

                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            } else {
                debugPrint("User denied the permissions")
            }
        }
    }

    /**
     Deregister remote notification
     */
    func deregisterRemoteNotification() {
        UIApplication.shared.unregisterForRemoteNotifications()
    }

    func setDeviceToken(_ token: Data) {
        let token = token.map { String(format: "%02.2hhx", arguments: [$0]) }.joined()
        UserDefaults.setObject(token as AnyObject?, forKey: “deviceToken”)
    }

    class func deviceToken() -> String {
        let deviceToken: String? = UserDefaults.objectForKey(“deviceToken”) as? String

        if isObjectInitialized(deviceToken as AnyObject?) {
            return deviceToken!
        }

        return "123"
    }

    func isObjectInitialized(_ value: AnyObject?) -> Bool {
        guard let _ = value else {
                return false
         }
            return true
    }
}

extension AppDelegate: UNUserNotificationCenterDelegate {

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping(UNNotificationPresentationOptions) -> Swift.Void) {

        ("\(notification.request.content.userInfo) Identifier: \(notification.request.identifier)")

        completionHandler([.alert, .badge, .sound])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping() -> Swift.Void) {

        debugPrint("\(response.notification.request.content.userInfo) Identifier: \(response.notification.request.identifier)")

    }
}

Дайте мне знать, если есть какие-либо проблемы!

person CrazyPro007    schedule 14.05.2018

person    schedule
comment
Каковы дополнительные преимущества этой новой структуры? То, что я вижу здесь, — это использование подхода «completionHandler вместо делегата», после чего вам сразу предоставляется возможность принять решение: ошибка, предоставлено или не предоставлено… В 6‹ iOS ‹10 вам нужно было сделать ‍application.isRegisteredForRemoteNotifications(), чтобы увидеть предоставлено, и используйте другой метод делегата в случае ошибки. Правильно? Что-нибудь еще? - person Honey; 21.02.2017
comment
почему ваш отличается от принятого ответа? У него есть application.registerForRemoteNotifications() после его center.requestAuthorization - person Honey; 21.02.2017
comment
@Медовый; Это добавляется, если вы хотите включить удаленные уведомления. Когда я написал свой ответ, другого ответа не существовало, и @OP не указал, нужна ли им удаленная или локальная поддержка или поддержка iOS 10, поэтому я добавил столько, сколько мог. Примечание. Не следует регистрироваться в RemoteNotifications до тех пор, пока пользователь не предоставит доступ (в противном случае все удаленные уведомления доставляются автоматически [если вы этого не хотите] — без всплывающих окон). Также преимуществом нового API является поддержка вложений. Другими словами, вы можете добавлять в уведомления GIF и другие изображения, видео и т. д. - person Brandon; 21.02.2017
comment
Чтобы добавить вложения, вы делаете: notification.content.attachments = [UNNotificationAttachment(identifier: "png_identifier", url:imageURL , options: nil)] или UNNotificationAttachment(identifier: "audio_identifier", url:imageURL , options: [UNNotificationAttachmentOptionsTypeHintKey:kUTTypeMP3]) и т. д., например. - person Brandon; 21.02.2017
comment
О, хорошо... интересно.... Вы имеете в виду, что полезная нагрузка будет иметь URL из gif? или оно отправляется как Data? - person Honey; 21.02.2017
comment
@Honey уведомление будет отображаться в виде GIF, когда оно будет получено и открыто. Если это видео, миниатюра будет отображаться так же, как и изображение. URL-адрес будет загружен принимающим устройством. Если он локальный, он будет отправлен как данные, и принимающее устройство отобразит его правильно. Я считаю, что видео будут отправляться только в виде URL-адреса, но с предварительным просмотром (как в iMessage). Я еще не пробовал их все; только картинки и гифки. - person Brandon; 21.02.2017
comment
В закрытии вам нужно будет выполнить задачи, связанные с пользовательским интерфейсом, в основном потоке... DispatchQueue.main.async {... сделать что-то здесь...} - person Chris Allinson; 23.02.2017
comment
Я хочу отображать push-уведомления в режиме переднего плана для iOS 8.0, я получаю уведомления в фоновом режиме @ChrisAllinson - person Dilip Tiwari; 27.09.2017
comment
@DilipTiwari в последний раз, когда я проверял, вы можете услышать, что push-уведомление получено, но вам нужно вручную обработать этот случай в методе didReceiveRemoteNotification AppDelegate (и вручную отобразить что-то пользователю) ... еще немного чтения SO: stackoverflow.com/questions/14872088/ - person Chris Allinson; 27.09.2017
comment
error в requestAuthorization(options:completionHandler:) всегда равен нулю, когда я отказываюсь получать уведомления или не предоставляю сертификат aps. Как получить настоящую ошибку? - person DawnSong; 09.11.2017
comment
Ваш ответ не очень ясен. application.registerForRemoteNotifications() идет первым, затем запрашивает разрешение. Первый шаг просто может получить несколько обратных вызовов из системы iOS в didRegisterForRemoteNotificationsWithDeviceToken AppDelegate, если вы включите и выключите переключатель уведомлений несколько раз. - person DawnSong; 12.02.2018
comment
как добавить/инициировать несколько уведомлений? - person ArgaPK; 05.03.2018
comment
@DawnSong Я не верю, что порядок имеет значение для iOS. Однако это может иметь значение для вашего приложения. Если вы не запросите и не получите разрешение, iOS молча уведомит ваше приложение. Поэтому, как правило, лучше запрашивать у пользователя разрешение ПЕРЕД регистрацией (и затем регистрироваться только в том случае, если вы получили разрешение), если вы не хотите получать тихие уведомления. - person Smartcat; 12.04.2018
comment
Преимущество этого решения при использовании не в AppDelegate, чтобы делать то же самое в коде - person Codenator81; 04.10.2018