Wykonuję aplikację, w której chcę zaimplementować usługę powiadomień push Apple. Postępuję zgodnie z instrukcjami krok po kroku podanymi w tym samouczku .
Ale nadal metody nie są wywoływane. Nie wiem, co jest przyczyną problemu. Czy ktoś może mi pomóc?
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
//NSString * token = [[NSString alloc] initWithData:deviceTokenencoding:NSUTF8StringEncoding];
NSString *str = [NSString stringWithFormat:@"Device Token=%@",deviceToken];
NSLog(@"Device Token:%@",str);
//NSLog(@"Device token is called");
//const void *devTokenBytes = [deviceToken bytes];
//NSLog(@"Device Token");
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSString *str = [NSString stringWithFormat: @"Error: %@", err];
NSLog(@"Error:%@",str);
}
objective-c
apple-push-notifications
Muzammil
źródło
źródło
Odpowiedzi:
Miałem ten sam problem: wywołanie
registerForRemoteNotificationTypes:
nie wywołało aniapplication:didRegisterForRemoteNotificationsWithDeviceToken:
aniapplication:didFailToRegisterForRemoteNotificationsWithError:
Ostatecznie rozwiązałem ten problem za pomocą notatki technicznej Apple TN2265 .
Oto co zrobiłem:
Po pierwsze, dwukrotnie sprawdziłem, czy faktycznie rejestruję się poprawnie w celu korzystania z powiadomień push , w tym zweryfikowałem mój profil obsługi administracyjnej dla klucza „aps-environment” i kodowanie samego pliku .app. Miałem to wszystko poprawnie skonfigurowane.
Następnie musiałem zdebugować komunikaty o stanie powiadomień push w konsoli (musisz zainstalować profil informacyjny PersistentConnectionLogging.mobileconfig na swoim urządzeniu i ponownie go uruchomić. Zobacz TN2265 w sekcji „Obserwowanie komunikatów o stanie push”). Zauważyłem, że proces apns uruchamia licznik czasu i oblicza minimalną datę odpalenia, co skłoniło mnie do podejrzenia, że komunikat potwierdzenia rejestracji Push-Notification, który jest zwykle wyświetlany w tym miejscu, jest tłumiony przez APNS, jak wskazano w TN2265:
Usunąłem więc aplikację z urządzenia, a następnie ręcznie zmieniłem datę iPhone'a w Ustawieniach, zrestartowałem urządzenie i ponownie zainstalowałem aplikację.
Następnym razem, gdy mój kod zadzwonił
registerForRemoteNotificationTypes
, otrzymał oddzwonienie zgodnie z oczekiwaniami.To rozwiązało problem. Mam nadzieję, że to pomoże.
źródło
W iOS 8 niektóre metody są przestarzałe. Wykonaj poniższe czynności, aby uzyskać zgodność z iOS 8
1. Zarejestruj zgłoszenie
if([[UIDevice currentDevice] systemVersion].floatValue >= 8.0) { UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings]; } else { [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge)]; }
2. Dodaj nowe 2 metody
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { //register to receive notifications [application registerForRemoteNotifications]; } //For interactive notification only - (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler { //handle the actions if ([identifier isEqualToString:@"declineAction"]){ } else if ([identifier isEqualToString:@"answerAction"]){ } }
Uwaga: powyższe dwie nowe metody są wymagane w iOS 8 oprócz
didRegisterForRemoteNotificationsWithDeviceToken
i .. WdidReceiveRemoteNotification
przeciwnym razie metoda delegata nie zostanie wywołana.Zobacz: Zdalne powiadamianie iOS 8
źródło
[application registerForRemoteNotifications];
W iOS 8 , oprócz żądania dostępu do powiadomień push w inny sposób, musisz również inaczej się zarejestrować.
Poproś o dostęp:
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) { // iOS 8 UIUserNotificationSettings* settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; } else { // iOS 7 or iOS 6 [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; }
Obsługuj zarejestrowane urządzenie:
// New in iOS 8 - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { [application registerForRemoteNotifications]; } // iOS 7 or iOS 6 - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]]; token = [token stringByReplacingOccurrencesOfString:@" " withString:@""]; // Send token to server }
źródło
application:didRegisterForRemoteNotificationsWithDeviceToken:
Pamiętaj, że symulator nie obsługuje zdalnych powiadomień. Dlatego jeśli uruchomisz swoją aplikację w symulatorze,
didRegisterForRemoteNotificationsWithDeviceToken
nie zostanie wywołana.źródło
Upewnij się, że dzwonisz w swoim kodzie (zaktualizuj zgodnie z obsługiwanymi rodzajami powiadomień)
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
a profil informacyjny jest włączony APNS. Po włączeniu APNS może być konieczne ponowne pobranie profilu obsługi administracyjnej. Jeśli masz problemy i otrzymujesz błędy, być może powinieneś utworzyć Entitlements.plist i dodać klucz „aps-environment” z wartością „development” lub „production” w zależności od rodzaju kompilacji (zwykle ta para klucz-wartość to zawarte w profilu aprowizacji, ale czasami Xcode z nimi miesza).
źródło
Jeśli profile aprowizacji były wcześniej używane do włączania i konfigurowania usługi Apple Push Notification, konieczne będzie ponowne pobranie tych profili.
Usuń profile obsługi administracyjnej z Xcode Organizer i z iPhone'a / iPada. Idź do
Settings -> General -> Profiles -> [Your provisioning] -> Remove
.Zainstaluj nowe pobrane profile udostępniania. Następnie wyczyść i uruchom projekt z XCode. Teraz
didRegisterForRemoteNotificationsWithDeviceToken
należy zadzwonić.źródło
Popełniłem błąd i przeoczyłem szczegół implementacji, który mnie tu doprowadził. Próbowałem dostać się kręci i poprosić użytkownika o powiadomień push później w procesie Onboarding aplikacji, więc miałem
registerForRemoteNotificationTypes
,didRegisterForRemoteNotificationsWithDeviceToken
adidFailToRegisterForRemoteNotificationsWithError
wszystko to w niestandardowych UIView.FIX:
didRegisterForRemoteNotificationsWithDeviceToken
ididFailToRegisterForRemoteNotificationsWithError
muszą znajdować się wUIApplicationDelegate
(YourAppDelegate.m
), aby zostały wyzwolone.wydaje się teraz oczywiste, heh.
źródło
AppDelegate
. Nie mogę uwierzyć, że zmarnowałem kilka ostatnich godzin na tę prostą odpowiedźUpewnij się, że masz włączone połączenie internetowe. Otrzymanie powiadomień o pracy zajęło mi kilka godzin z powodu połączenia internetowego.
źródło
Jeśli dodałeś wypychanie do istniejącego identyfikatora aplikacji, upewnij się, że ponownie wygenerowałeś profile aprowizacji. Jeśli tego nie zrobisz, profil nie będzie wiedział o włączeniu opcji push na identyfikator aplikacji.
źródło
Spróbuj, to działa dla mnie,
Pierwszy krok
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
W powyższej metodzie dodaj poniższy kod
UIApplication *application = [UIApplication sharedApplication]; if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) { UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge |UIUserNotificationTypeSound |UIUserNotificationTypeAlert) categories:nil]; [application registerUserNotificationSettings:settings]; } else { UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound; [application registerForRemoteNotificationTypes:myTypes]; }
Drugi krok
Dodaj poniższy kod Funkcja
#ifdef __IPHONE_8_0 - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { //register to receive notifications [application registerForRemoteNotifications]; } - (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler { //handle the actions if ([identifier isEqualToString:@"declineAction"]){ } else if ([identifier isEqualToString:@"answerAction"]){ } } #endif
Otrzymasz token urządzenia w poniższej funkcji
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
aby uzyskać szczegółową odpowiedź, zapoznaj się z tym
Mam nadzieję, że to pomoże komuś.
źródło
-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions{ //Overridepointforcustomizationafterapplicationlaunch. //Addtheviewcontroller’sviewtothewindowanddisplay. [windowaddSubview:viewController.view]; [windowmakeKeyAndVisible]; NSLog(@”Registering for push notifications...”); [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)]; returnYES; } - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { } NSString *str = [NSString stringWithFormat:@”Device Token=%@”,deviceToken]; NSLog(@”%@”, str); - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { NSString *str = [NSString stringWithFormat: @”Error: %@”, err]; NSLog(@”%@”, str); } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { } for (id key in userInfo) { NSLog(@”key: %@, value: %@”, key, [userInfo objectForKey:key]); }
źródło
Minimalny wymóg uzyskania tokenu urządzenia:
nie ma potrzeby konfigurowania identyfikatora aplikacji, obsługi administracyjnej ani certyfikatu itp., Dlatego nie ma ustawionego podpisywania kodu w celu uzyskania metody delegata didRegisterForRemoteNotificationsWithDeviceToken .
Właśnie utworzyłem nowy projekt iOS w Xcode 7 dla pojedynczego widoku z domyślnymi ustawieniami i podałem losowy identyfikator pakietu, taki jak com.mojafirma.pushtest, który nie jest skonfigurowany w portalu Apple dla deweloperów.
Za pomocą następującego kodu otrzymuję token mojego urządzenia w metodzie didRegisterForRemoteNotificationsWithDeviceToken na moim iPadzie z dostępem do Internetu do WIFI. Moje urządzenie jest podłączone i po prostu uruchamiam aplikację bezpośrednio z xcode i przeglądam wartości w konsoli xcode.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) { UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound); UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes categories:nil]; [application registerUserNotificationSettings:settings]; [application registerForRemoteNotifications]; } else { // Register for Push Notifications, if running iOS version < 8 [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)]; } return YES; } - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"Error: %@", error.description); } - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSLog(@"didRegisterForRemoteNotificationsWithDeviceToken: %@", deviceToken); } - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { NSLog(@"NotificationSettings: %@", notificationSettings); }
źródło
Mam rację w tej sprawie Ostatnio też napotykam ten problem.Zrobiłem wszystko zgodnie z dokumentacją ale metoda delegata nie dzwoniła.W końcu zobaczyłem jeden post mówiący o tym problemie z siecią, potem zmieniłem sieć i działa dobrze. Dlatego uważaj na sieć, ponieważ niewiele sieci może blokować APNS.
źródło
Po zmarnowaniu najbardziej irytujących 3 godzin, oto kroki, aby rozwiązać problem:
Usuń aplikację
Zresetuj urządzenie
Uruchomić ponownie
Po prostu zadziałało
źródło
Zdarzyło mi się to, ponieważ zresetowałem i usunąłem wszystkie dane z telefonu (chciałem użyć telefonu programisty). Uniemożliwiło to APN łączenie się w ogóle po ponownym skonfigurowaniu telefonu.
Próbowałem różnych rzeczy, ale jedyną rzeczą, która to naprawiła, było ustawienie telefonu do pracy z operatorem pod nową kartą SIM.
Ten link zawiera więcej wskazówek, co mogło się dziać: https://developer.apple.com/library/ios/technotes/tn2265/_index.html
Mówi, że APN próbuje łączyć się preferencyjnie przez operatora / wieże, a nie przez Wi-Fi. Być może problemem było również coś, co działo się z routerem blokującym port 5223 w sieci Wi-Fi, ale wątpię w to, ponieważ działał dobrze poprzedniego dnia przed globalnym resetem.
źródło
Dla mnie rozwiązaniem było przejście do ustawień kompilacji i pod sekcją podpisywania kodu, ręczne wybranie tożsamości podpisującej kod i profilu aprowizacji. Najwyraźniej ustawienie automatyczne nie wybrało właściwego ustawienia i dlatego aplikacja nie została poprawnie autoryzowana.
źródło
w przypadku wyłączenia wiadomości push aplikacji,
appdidRegisterForRemoteNotificationsWithDeviceToken nigdy nie zostanie wywołana
źródło
Nie zapomnij też sprawdzić statusu systemu na Apple https://developer.apple.com/system-status/ .
Wypróbowałem wszystkie powyższe rozwiązania, ale ostatecznie błąd wynikał z awarii usługi APNS! Następnego dnia wszystko działało zgodnie z oczekiwaniami.
Masz również literówkę w swojej metodzie wywołania zwrotnego:
- (void)application:(UIApplication *)appdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
Jak zauważył Rupesh, poprawna nazwa metody to:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
Prawdopodobnie dlatego nigdy nie otrzymałeś tokena w swoim przypadku!
źródło
Musisz wywołać metodę registerForNotifications z didFinishLaunchingWithOptions.
func registerForNotifications(){ if #available(iOS 10.0, *) { let center = UNUserNotificationCenter.current() center.delegate = self center.requestAuthorization(options:[.alert,.sound,.badge]) { (granted, error) in if granted{ UIApplication.shared.registerForRemoteNotifications() }else{ print("Notification permission denied.") } } } else { // For iOS 9 and Below let type: UIUserNotificationType = [.alert,.sound,.badge]; let setting = UIUserNotificationSettings(types: type, categories: nil); UIApplication.shared.registerUserNotificationSettings(setting); UIApplication.shared.registerForRemoteNotifications() } } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let token = String(format: "%@", deviceToken as CVarArg).trimmingCharacters(in: CharacterSet(charactersIn: "<>")).replacingOccurrences(of: " ", with: "") print(token) } extension AppDelegate : UNUserNotificationCenterDelegate{ @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (_ options: UNNotificationPresentationOptions) -> Void) { print("Handle push from foreground”) let info = ((notification.request.content.userInfo as NSDictionary).value(forKey: "aps") as! NSDictionary) if let type = info.value(forKey: "type") as? Int{ if type == 0 { // notification received ,Handle your notification here } } } @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { print("Handle push from background or closed") let info = ((response.notification.request.content.userInfo as NSDictionary).value(forKey: "aps") as! NSDictionary) if let type = info.value(forKey: "type") as? Int{ if type == 0 { // notification received ,Handle your notification here } } } }
źródło
Miałem inny problem, w którym moje wywołania zwrotne powiadomień push były przejmowane przez biblioteki innych firm, które dołączyłem, a mianowicie Firebase. Te biblioteki zmieniają metody wywołań zwrotnych powiadomień push, aby uzyskać wywołania zwrotne.
Mam nadzieję, że to komuś pomoże.
źródło