PushKit не зачитывает учетные данные
Я некоторое время борюсь здесь, и, возможно, это моя ошибка, но я нигде не могу найти ответ на этот вопрос.
Я реализовал PushKit в некотором роде, но ни один из них не был эффективным.
Я добавил правильные фоновые режимы, правильно реализовал обратные вызовы, didUpdatePushCredentials
вызывается нормально...
Тем не менее credentials: PKPushCredentials!
переменная, дает мне указатель на ошибку... Это не нуль... не ноль... не что-нибудь... У него просто нет значения... это выделенный мусор... и для этого причина.. Я получаю EXC_BREAKPOINT..
Я пробовал в 3 разных устройствах... Такое же поведение...
Я уже создал сертификаты для VoIP Push...
Я сделал это по-разному:
- Создавая объект void Push Registry после didRegisterForRemotePushNotification
- Путем создания push-реестра без регистрации для удаленного push-уведомления...
- Создавая реестр с основными, глобальными и пользовательскими очередями.
Всегда одно и то же...
Вот код:
extension AppDelegate : PKPushRegistryDelegate {
func registerForVoipPush() {
self.registry = PKPushRegistry(queue:nil)
if self.registry != nil {
self.registry!.delegate = self
self.registry!.desiredPushTypes = Set<String>(arrayLiteral: PKPushTypeVoIP)
}
//let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories:nil)
//UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
}
func pushRegistry(registry: PKPushRegistry!, didUpdatePushCredentials credentials: PKPushCredentials!, forType type: String!) {
//print out the VoIP token. We will use this to test the nofications.
NSLog("voip token: \(credentials.token)")
if credentials != nil {
let username = NSUserDefaults.standardUserDefaults().objectForKey("username") as? String
if username != nil {
ServerDefinitions.subscribeForPush(username!, token: NSString(data: credentials.token, encoding: NSUTF8StringEncoding) as! String, callback: { (retMsg) -> Void in
print(retMsg)
})
}
}
}
func pushRegistry(registry: PKPushRegistry!, didReceiveIncomingPushWithPayload payload: PKPushPayload!, forType type: String!) {
let payloadDict = payload.dictionaryPayload["aps"] as? Dictionary<String, String>
let message = payloadDict?["alert"]
//present a local notifcation to visually see when we are recieving a VoIP Notification
if UIApplication.sharedApplication().applicationState == UIApplicationState.Background {
let localNotification = UILocalNotification();
localNotification.alertBody = message
localNotification.applicationIconBadgeNumber = 1;
localNotification.soundName = UILocalNotificationDefaultSoundName;
UIApplication.sharedApplication().presentLocalNotificationNow(localNotification);
}
else {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
print("Incoming Call")
})
}
NSLog("incoming voip notfication: \(payload.dictionaryPayload)")
}
func pushRegistry(registry: PKPushRegistry!, didInvalidatePushTokenForType type: String!) {
NSLog("token invalidated")
}
}
РЕДАКТИРОВАТЬ:
Обратите внимание, что приведенный выше код является расширением AppDelegate, созданным только для разделения кода, поэтому он становится более читабельным.
Я также добавил var registry : PKPushRegistry?
на AppDelegate's. Для того, чтобы это сработало, нужно позвонить registerForVoipPush()
где-то в коде. В моем случае я сделал это с кнопки.
ПОМОГИТЕ МНЕ, ПОЖАЛУЙСТА!
2 ответа
Я столкнулся с той же проблемой, и решил ее, добавив классическую реализацию Push перед началом регистрации VoIP... Я предполагаю, что каким-то образом Apple хочет убедиться, что вы сначала попросите пользователя дать базовый push и получите подтверждение пользователя, прежде чем разрешить вам обрабатывать дальше молчаливые вещи...
Включите Push-уведомления для вашего приложения...
Тогда это весь итоговый файл AppDelegate, который очень похож на ваш:
import UIKit
import PushKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
//Enable all notification type.
let notificationSettings = UIUserNotificationSettings(forTypes: [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound] , categories: nil)
//register the notification settings
application.registerUserNotificationSettings(notificationSettings)
NSLog("app launched with state \(application.applicationState.stringValue)")
return true
}
func applicationWillResignActive(application: UIApplication) {
}
func applicationDidEnterBackground(application: UIApplication) {
}
func applicationWillEnterForeground(application: UIApplication) {
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
NSLog("app terminated")
}
}
extension AppDelegate {
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
//register for voip notifications
let voipRegistry = PKPushRegistry(queue: dispatch_get_main_queue())
voipRegistry.desiredPushTypes = Set([PKPushTypeVoIP])
voipRegistry.delegate = self;
NSLog("didRegisterUserNotificationSettings")
}
}
extension AppDelegate: PKPushRegistryDelegate {
func pushRegistry(registry: PKPushRegistry!, didUpdatePushCredentials credentials: PKPushCredentials!, forType type: String!) {
//print out the VoIP token. We will use this to test the nofications.
NSLog("voip token: \(credentials.token)")
}
func pushRegistry(registry: PKPushRegistry!, didReceiveIncomingPushWithPayload payload: PKPushPayload!, forType type: String!) {
let payloadDict = payload.dictionaryPayload["aps"] as? Dictionary<String, String>
let message = payloadDict?["alert"]
//present a local notifcation to visually see when we are recieving a VoIP Notification
if UIApplication.sharedApplication().applicationState == UIApplicationState.Background {
let localNotification = UILocalNotification();
localNotification.alertBody = message
localNotification.applicationIconBadgeNumber = 1;
localNotification.soundName = UILocalNotificationDefaultSoundName;
UIApplication.sharedApplication().presentLocalNotificationNow(localNotification);
}
else {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let alert = UIAlertView(title: "VoIP Notification", message: message, delegate: nil, cancelButtonTitle: "Ok");
alert.show()
})
}
NSLog("incoming voip notfication: \(payload.dictionaryPayload)")
}
func pushRegistry(registry: PKPushRegistry!, didInvalidatePushTokenForType type: String!) {
NSLog("token invalidated")
}
}
extension UIApplicationState {
//help to output a string instead of an enum number
var stringValue : String {
get {
switch(self) {
case .Active:
return "Active"
case .Inactive:
return "Inactive"
case .Background:
return "Background"
}
}
}
}
Для получения дополнительной информации, это вдохновлено этим постом
Как @JBA я забыл активировать push-уведомления. Похоже, что даже вам нужен только пуш VOIP, который вы должны активировать пуш (традиционный)