I am facing issue while generating the device token with the real device.
I am debugging device and device token is not generating.
Sometimes it works and sometimes not.
Please let me know what could be issue.
Thanks
Did you put below in didFinishLaunchingWithOptions of AppDelegate.m?
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
NSLog(#"ios8 app");
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
NSLog(#"lower ios8 app");
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
}
As of now, I, too, am having trouble getting device tokens.
My projects stopped generating device tokens when it was "erased" and "installed" around 10 hours ago.
Also in the Korean iOS Developers forum, some people have been reporting problems with APNS tokens not generating in the past 10 hours.
There may be something wrong with some of the sandbox APNS servers.
Last checked time
2016-04-27 22:43 PM +0900 GMT : No device token, Push Notification Not Arriving.
Add this method,
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError)
{
print("application:didFailToRegisterForRemoteNotificationsWithError: %#", error)
}
You will get answer, why token is not generated.
#GopalDevra could you be more clear? Anyway, I have this code for Parse, maybe it's not your case, but you can get the idea.
You can use didRegisterForRemoteNotificationsWithDeviceToken in AppDelegate.m like:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// Store the deviceToken in the current installation and save it to Parse.
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
currentInstallation.channels = #[ #"global" ];
[currentInstallation saveInBackground];
}
Edited
Have you put this in didFinishLaunchingWithOptions?
// - Push notifications
// -- Register for Push Notitications
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
//-- Set Notification
if ([application respondsToSelector:#selector(isRegisteredForRemoteNotifications)])
{
// iOS 8 Notifications
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[application registerForRemoteNotifications];
}
else
{
// iOS < 8 Notifications
[application registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
}
//--- your custom code
Related
I am not getting push notifications coming through onto my device. I have all my certificates in place and i do get test pushes coming through. my code to send push works fine i can see that on parse. it also says pushes sent but no pushes come through to device due to code below.
My code below in appdelegate didFinishLaunching method gives the alert to allow push notes but none come through
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[application registerUserNotificationSettings:notificationSettings];
} else {
[application registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
[application registerForRemoteNotifications];
}
If i move this line [application registerForRemoteNotifications] anywhere else my app crashes. this line is the only issue if i move it anywhere and i have tried it every where it causes crash (app does not open at all).
help me fix crash and get push notifications coming through?
Could you please try this one:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
make sure that you have remote notification on in background mode capabilities and have uploaded .p12 without any password in parse.
Hope it helps you.
You need to add a PFInstallation to your device. From Parse's iOS guide, under "Push Notifications" -
Every Parse application installed on a device registered for push notifications has an associated PFInstallation object. The PFInstallation object is where you store all the data needed to target push notifications
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// Store the deviceToken in the current Installation and save it to Parse
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation saveInBackground]; }
Here is the code I am using currently in my own iOS app using Parse as a BaaS. Your code fails to implement a PFInstallation which is stored in a Parse table.
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let installation = PFInstallation.currentInstallation()
installation.setDeviceTokenFromData(deviceToken)
installation.addUniqueObject("ExampleChannel", forKey: "channels")
installation.saveInBackground()
}
Hope I was able to help you out, best of luck.
i am not getting into the method
didRegisterForRemoteNotificationsWithDeviceToken
Actually i want to get device token and i have tried to follow this question Get Device Token in iOS 8 but still facing the same problem
.Help me to come out of this problem
Try this.
In your method.
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
use this code
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeNewsstandContentAvailability| UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
And then Put log or breakpoints that your
didRegisterForRemoteNotificationsWithDeviceToken
get called or not.
And if your app is properly registered for remote-notification settings and yet you are not getting device token then
check
didFailToRegisterForRemoteNotificationsWithError
method that will tell you which error you have.
NOTE : device-token will return only when you run on device. OS Simulator doesn't support push notifications
And then also if you are not able to get this method called, then check out this tutorial
http://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1
And follow the steps for creating provisioning profile and certificates. I tried with my existing certificate. After you run your app with valid profile as explained in this tutorial series, you will able to get that method called.
There are different way to get device token in iOS 8.
if ([[UIApplication sharedApplication] respondsToSelector:#selector(registerUserNotificationSettings:)]) {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
}
The problem was that there is some kind of restriction in my company network so when i used a wifi device which was not on company network my code worked fine.
I have coded my app to receive Parse notifications in iOS8 and recently discovered these wouldn't work in iOS& so had to change my code to as follows in AppDelegate.m:
viewDidLoad:
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
NSLog(#"Requesting permission for push notifications...iOS8"); // iOS 8
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
} else {
NSLog(#"Registering device for push notifications..."); // iOS 7 and earlier
[UIApplication.sharedApplication registerForRemoteNotificationTypes:
UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound];
}
and:
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// Store the deviceToken in the current Installation and save it to Parse.
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation saveInBackground];
}
I tested on both version of iOS and it seems to be working fine. However if I change the deployment target in Xcode to iOS8 or above I get these compiler warnings:
AppDelegate.m:62:10: 'UIRemoteNotificationTypeAlert' is deprecated: first deprecated in iOS 8.0 - Use UIUserNotificationType for user notifications and registerForRemoteNotifications for receiving remote notifications instead.
AppDelegate.m:62:42: 'UIRemoteNotificationTypeBadge' is deprecated: first deprecated in iOS 8.0 - Use UIUserNotificationType for user notifications and registerForRemoteNotifications for receiving remote notifications instead.
AppDelegate.m:63:10: 'UIRemoteNotificationTypeSound' is deprecated: first deprecated in iOS 8.0 - Use UIUserNotificationType for user notifications and registerForRemoteNotifications for receiving remote notifications instead.
/AppDelegate.m:61:42: 'registerForRemoteNotificationTypes:' is deprecated: first deprecated in iOS 8.0 - Please use registerForRemoteNotifications and registerUserNotificationSettings: instead
Is it normal to see these warnings and is it just because I'm working in a higher deployment target? Or do I have to change the code somewhere? Seems odd that I would have to see these warnings. Any pointers would be really appreciated. Thanks!
If you changed the deployment target to iOS 8, so no need for checking for iOS 8 or not (Before iOS 8 as your app will work in iOS 8 devices only), thats why it gives you these warnings. So just register like this:
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
Yes, That method is deprecated in iOS8 but you can check condition on iOS7 and iOS8 by these lines of code to manage deprecation:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
}
and addition to that add these line of code below it.
if ([launchOptions valueForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"]) {
[self application:application didReceiveRemoteNotification:launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]];
}
and to register device on parse.com please check once your applicationKey and ClientKey is correct other than that your code block for register device is correct, but it won't affect that deprecations of iOS at all.
I followed this tutorial and set everything just like it says to receive push notifications on iOS.
I set the didFinishLaunchingWithOptions in Xcode with this:
if ([application respondsToSelector:#selector(isRegisteredForRemoteNotifications)]) {
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound) categories:nil]];
[application registerForRemoteNotifications];
} else {
[application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
}
I got registered(I am able to get the deviceToken) and i can get the message from the push notification when is sent, the problem is that i can't get to play any notification sound, my pusher.php is like this:
$body['aps'] = array(
'alert' => $message,
'sound' => "default"
);
I am using iOS 8.1.3
I got the same problems, Seems like the Code below is obsolete:
if ([application respondsToSelector:#selector(isRegisteredForRemoteNotifications)])
{
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound |
UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge) categories:nil]];
[application registerForRemoteNotifications];
}
else
{
[application registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
}
if (application) {
application.applicationIconBadgeNumber = 0;
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]){
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|
UIUserNotificationTypeBadge|
UIUserNotificationTypeSound categories:nil]];
}
}
return YES;}
As I'am only getting Local notifications within the App. Even after putting correct certificate to this.
So far Iv not found any help with this, so ended up emailing Apple Developer Technical Support about this.
I need device token to implement push notification in my app.
How can I get device token since didRegisterForRemoteNotificationsWithDeviceToken method is not working on iOS 8.
I tried this code in app delegate but it is not giving me device token.
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
Read the code in UIApplication.h.
You will know how to do that.
First:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
add Code like this
#ifdef __IPHONE_8_0
//Right, that is the point
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
|UIRemoteNotificationTypeSound
|UIRemoteNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
#else
//register to receive notifications
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
#endif
if you not using both Xcode 5 and Xcode 6 ,try this code
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
|UIRemoteNotificationTypeSound
|UIRemoteNotificationTypeAlert) categories:nil];
[application registerUserNotificationSettings:settings];
} else {
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
}
(Thanks for #zeiteisen #dmur 's remind)
Second:
Add this Function
#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
And your can get the deviceToken in
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
if it still not work , use this function and NSLog the error
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
Appending a small validation to #Madao's response in case you are having crashes on older iOS versions:
#ifdef __IPHONE_8_0
if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
#endif
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeNewsstandContentAvailability;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
What the __IPHONE_8_0 macro does is just allowing you to compile in older versions of xCode/iOS, you don't get compilation errors or warnings, but running the code on devices with iOS 7 or lower will cause a crash.
To get Device token in iOS8 +
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//This code will work in iOS 8.0 xcode 6.0 or later
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeNewsstandContentAvailability| UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
return YES;
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSString* deviceToken = [[[[deviceToken description]
stringByReplacingOccurrencesOfString: #"<" withString: #""]
stringByReplacingOccurrencesOfString: #">" withString: #""]
stringByReplacingOccurrencesOfString: #" " withString: #""] ;
NSLog(#"Device_Token -----> %#\n",deviceToken);
}
2020 solution
Six steps,
1. library
2. add to AppDelegate
// APNs:
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print(">> getting an APNs token works >>\(deviceToken)<<")
let tokenAsText = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
}
func application(_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error) {
print(">> error getting APNs token >>\(error)<<")
}
3. in your app
For example, after user logon
import UserNotifications
and
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
askNotifications()
}
func askNotifications() {
let n = UNUserNotificationCenter.current()
n.requestAuthorization(options: [.alert, .sound, .badge]) {
granted, error in
print("result \(granted) \(String(describing: error))")
guard granted else {
print("not granted!")
return
}
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
4. capabilities tab
do three items
beware of old articles: there is no longer an "on switch" there.
5. tethered phone, no simulator
it will not work in simulator. must be a phone
tethered phone is fine, console will work fine
6. and finally ... WIFI DANCE
With 100% repeatability, as of 2020 you MUST do the following:
completely erase app from tethered phone
build to the phone and run from Xcode
(it definitely won't work)
force quit the app
completely erase app from tethered phone
turn off both wifi/cell
build to the phone and run from Xcode
(obviously it won't work)
force quit the app
then in exactly this order:
completely erase app from tethered phone
turn on connectivity (either wifi or cell is fine - no problem)
build to the phone and run from Xcode
It now works. (And will work from here onwards.)
The WIFI DANCE is just one of those weird Apple things. They have not fixed it yet (Xcode 11.3). In fact it has become "100% repeatable": you have to do the WIFI DANCE.
Aside from the rest of the condescending answers to this question, the most likely reason that this issue might occur for an informed developer who has implemented all the required delegate methods is that they are using a wild card provisioning profile (why wouldn't you? It makes it so easy to create and test development apps!)
In this case, you'll probably see the error Error Domain=NSCocoaErrorDomain Code=3000 "no valid 'aps-environment' entitlement string found for application"
In order to test notifications, you actually have to go back to 2000 and late, log into developer.apple.com, and set up your application-specific provisioning profile with push notifications enabled.
Create an App ID corresponding to your app's bundle identifier. Be sure to check off "push notifications" (currently 2nd option from the bottom).
Create a provisioning profile for that App ID.
Go through the rest of the horrible provisioning steps we'd all love to forget.
?
Profit!
On your developer account make sure you have your push notifications setup properly in your app ID and then you need to regenerate and download your provisioning profile. My problem was that I had downloaded the provisioning profile but xcode was running the incorrect one. To fix this go to your Target Build Settings, scroll down to Code Signing, under the provisioning profile section make sure that you are using the correct provisioning profile that matches the name of the one you generated (there should be a dropdown with options if you have installed more than one).
Here is the solution.
in applicationDidFinishLaunchingWithOptions:
{
UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
}
- (void)application:(UIApplication*)application didRegisterUserNotificationSettings:(nonnull UIUserNotificationSettings *)notificationSettings
{
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(nonnull NSError *)error
{
NSLog(#" Error while registering for remote notifications: %#", error);
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(nonnull NSData *)deviceToken
{
NSLog(#"Device Token is : %#", deviceToken);
}
#madoa answer is absolutely correct. Just note that it is not working in the simulator.
In this case
-(void)application:(UIApplication *)application
didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
is called with a error REMOTE_NOTIFICATION_SIMULATOR_NOT_SUPPORTED_NSERROR