Swift 2: никаких обратных вызовов делегатов для push-уведомлений в отличие от objective-c
Я создал 2 проекта (один вид) для тестирования push-уведомлений, я не добавил код, кроме кода установки уведомлений, как показано ниже:
Project1 (Swift 2):
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
UIApplication.sharedApplication().registerForRemoteNotifications()
return true
}
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
print("didRegisterUserNotificationSettings got called")
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let trimmedDeviceToken = deviceToken.description .stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<>"))
.stringByReplacingOccurrencesOfString(" ", withString: "")
print("Device Token \(trimmedDeviceToken)")
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print("Failed to get token, error: \(error)")
}
Project2 (Objective-C):
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIUserNotificationSettings* notificationSettings =
[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert|UIUserNotificationTypeBadge) categories:nil];
[application registerUserNotificationSettings:notificationSettings];
[application registerForRemoteNotifications];
return YES;
}
-(void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
NSLog(@"didRegisterUserNotificationSettings got called");
}
-(void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSString* newToken = [deviceToken description];
newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
newToken = [newToken stringByReplacingOccurrencesOfString:@" " withString:@""];
NSLog(@"Device Token %@", newToken);
}
-(void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(@"Failed to get token, error: %@", error);
}
проект objective-c отлично работает на всех тестируемых устройствах: регистрируется для удаленных уведомлений и получает токен устройства в методе обратного вызова делегата, , но быстрый проект не смог получить какой-либо из обратных вызовов делегата..
прочитайте, что Ive попытался, прежде чем отмечать этот вопрос как дубликат:
1) AppID поддерживает push-уведомление
2) Тип сертификата Push - это производство, а профиль Provisioning - производство AdHoc
3) оба проекта используют один и тот же AppID, push-сертификат и профиль подготовки
4) оба проекта были протестированы на трех разных iPhone (5, 6 и 6Plus), все из которых работают с iOS 9.2, удалили приложение при каждой установке и перезапустили все их много раз
5) построил оба проекта с Xcode 7.2 на двух разных машинах MAC Pro
6) все 3 iPhone используют интернет-соединение без брандмауэра, и все порты открыты (как указано в этой технической заметке), также изменилось подключение к Интернету на 3 устройствах 3G-соединение вместо WIFI.
7) проверено/непроверено Push-уведомления в настройках проекта → возможности для обоих проектов (кстати, эта точка не влияет, как я ее протестировал)
8) попробовал Xcode Run (верхняя кнопка) и экспортировал пакет ipa для обоих проектов
9) попробовал как (приложение), так и ([UIApplication sharedApplication] для objective-c и UIApplication.sharedApplication()) для swift с помощью метода registerForRemoteNotifications
10) попробовал другой новый AppID, нажмите сертификат и профиль подготовки для обоих проектов.
11) удалили оба проекта и создали еще 2 новых проекта с тем же кодом, что и выше
проект objective-c после всех этих попыток работает нормально и получает токен устройства через метод didRegisterForRemoteNotificationsWithDeviceToken, но быстрый не работает.
Я создал 3 файла журнала APN с устройства iPhone 6Plus, используя профиль PersistentConnectionLogging.mobileconfig
от Apple, и загрузил их здесь, (внутри apsd_2016_02_24_11_36_29+0300.log
файл objective-c проект BundleID равен XXXXX.push.notification
, а быстрый BundleID проекта XXXXX.apnsswift
)
Ответы
Ответ 1
выясняется, что причиной этой странной проблемы является быстрый print
метод, который не отображает вывод в журнале устройства, в отличие от NSLog
, быстрое приложение не имеет проблем, просто нужно использовать NSLog
, чтобы показать сообщения в методах обратного вызова делегата Push Notification.
//print("Device Token \(trimmedDeviceToken)")
NSLog("Device Token: %@",trimmedDeviceToken)
Ответ 2
Вы на 100% уверены, что application:didFinishLaunchingWithOptions:
вызывается вообще в версии Swift? Может быть, вы забыли, например, установить имя делегата приложения в версии Swift? Чтобы проверить, добавьте некоторый код регистрации в Swift application:didFinishLaunchingWithOptions:
.
Кроме того, обязательно добавьте @objc
в класс делегата Swift (если это еще не так) и попробуйте (это действительно длинный снимок), добавив ключевое слово dynamic
к методам делегата.
И попробуйте заменить UIApplication.sharedApplication()
на application
(еще один длинный снимок).