Apple Notification Device Token change - ios

I'm facing an issue after updating my app. I'm getting a device token in this format
C43461D5-E9CB-4C10-81F8-020327A07A62
and the notifications aren't working.
Before, I had a notification in this format:
2add70865401171c7ca1d3b3957b719eaf721fef8f8d7a52bc91ef8a872cc004
I did allow notifications for the app and I've not changed anything in the backend. Can anyone guide me why it's not working?
Code in didFinishLaunchingWithOptions:
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)];
}
Getting the device token:
NSString *deviceTokenID = [[NSUserDefaults standardUserDefaults] objectForKey:DEVICE_TOKEN_PUSH_NOTI];
if ([deviceTokenID isEqualToString:#""] || deviceTokenID == nil) {
NSString *tempApplicationUUID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
[dics setObject:tempApplicationUUID forKey:#"cust_device_id"];
} else {
[dics setObject:[[NSUserDefaults standardUserDefaults] objectForKey:DEVICE_TOKEN_PUSH_NOTI] forKey:#"cust_device_id"];
}
I got the below error:
Code=3000 "no valid 'aps-environment' entitlement string found for
application" UserInfo={NSLocalizedDescription=no valid
'aps-environment' entitlement string found for application}, no valid
'aps-environment' entitlement string found for application

plz go to
Click on .xcodeproj -> Capabilities -> Enable Push Notification
hope it's work

Click on .xcodeproj -> Capabilities -> Enable Push Notification

NSString *tempApplicationUUID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
The UUIDString is the Unique device ID but for the Apple Push Notification you required the device token get back from APNS so for that Use the below method you get 64 digit deviceToken and get notification.
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *devToken = [[[[deviceToken description]
stringByReplacingOccurrencesOfString:#"<"withString:#""]
stringByReplacingOccurrencesOfString:#">" withString:#""]
stringByReplacingOccurrencesOfString: #" " withString: #""];
NSString *str = [NSString
stringWithFormat:#"Device Token=%#",devToken];
[[NSUserDefaults standardUserDefaults]setObject:devToken forKey:#"DeviceToken"];
}

Related

iOS- Push notification issue

Currently one of my php developer provided me push notification API for iOS devices
The problem is : If i run that api with respective parameter in any Browser(Chrome/Safari/Firefox and etc..) i am getting notification on foreground of iOS device. But not in iOS app(Xcode) itself
In my app i used code like:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Register for Push Notitications, if running on iOS 8
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0){
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}
#pragma mark
#pragma mark -- Push Notification Delegate Methods
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings: (UIUserNotificationSettings *)notificationSettings{
//register to receive notifications
[application registerForRemoteNotifications];
}
-(void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken{
// Prepare the Device Token for Registration (remove spaces and < >)
devToken = [[[[deviceToken description]
stringByReplacingOccurrencesOfString:#"<"withString:#""]
stringByReplacingOccurrencesOfString:#">" withString:#""]
stringByReplacingOccurrencesOfString: #" " withString: #""];
NSLog(#"My token is: %#", devToken);
// My token is: cd2887c4093569b3eed142320f21a81e521e486cf5c40467390901d3a191398b
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:deviceToken forKey:#"deviceToken"];
}
-(void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error{
NSLog(#"Failed to get token, error: %#", error);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
NSLog(#"%s..userInfo=%#",__FUNCTION__,userInfo);
}
I am getting response:(in didReceiveRemoteNotification)
{
aps = {
alert = "You're login successfully";
sound = default;
};
}
This message is not showing on Status bar(top of the screen). Is there any issue in iOS side (or) PHP side
If the issue is in iOS side--> How can i do this
Here is my Testing Push notification API:
https://shopgt.com/mobile1/iphone/register.php?device_type=2&email=sukhpal#anaad.net&regId=4d1d9067cc1382ecb8b0532831cce7fc8eb6fc388a6139060cd84712407a0ae5
Can you please help me out regarding this issue
You need to customize the view for showing Banner of Push Notification while the app in Foreground. You can use JCNotificationBannerPresenter. Follow the sample code using below link.
https://github.com/jcoleman/JCNotificationBannerPresenter
#import "JCNotificationCenter.h"
#import "JCNotificationBannerPresenterSmokeStyle.h"
- (void) application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)notification {
NSString* title = #"Push Notification";
NSDictionary* aps = [notification objectForKey:#"aps"];
NSString* alert = [aps objectForKey:#"alert"];
[JCNotificationCenter
enqueueNotificationWithTitle:title
message:alert
tapHandler:^{
NSLog(#"Received tap on notification banner!");
}];
}
Hope it Helps you..!
There is no issue, this is default behaviour.
The banner that appears at the top of the screen when you are on the Home screen does not appear when you are inside the app.
You need to get the app to do something with the notification yourself, inside didReceiveRemoteNotification. This could be showing an alert, adding a badge to the tab bar, etc. but banners only show when you are outside of the app.

Push Notification working well in ios 8 but not in ios 7

I am trying to implement push notification in app.
I have done that for ios 8. on iPad OS is ios8. I got push notification on iPad.
on iPhone OS is iOS7. whenever I compile app on iPhone I got error
/* Failed to get token, error: Error Domain=NSCocoaErrorDomain Code=3000 "no valid 'aps-environment' entitlement string found for application" UserInfo=0x16d246c0 {NSLocalizedDescription=no valid 'aps-environment' entitlement string found for application}*/
My app delegate methods are
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
// Let the device know we want to receive push notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
return YES;
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSLog(#"My token is: %#", deviceToken);
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(#"Failed to get token, error: %#", error);
}
Appreciate for help
The message indicates you are using a different signing certificate for iPad/iOS 7 than for iPhone/iOS 8, one without the permission for push notifications set. It has nothing to do with your code.
Sounds like your app is picking up the wrong provisioning profile for whatever reason. Does it start working if you explicitly specify the provisioning profile?

APNS device token is getting generated incorrect

I have integrated apple push notification and facing a strange problem in my application. when I directly install the application via Xcode through usb connection then the device token is being generate stored in database correctly and push notification is working fine. but when I create IPA and install the app via created ipa in the same device then the device token is getting generated wrong and push notification is not working. Below is my code:
if ([[UIApplication sharedApplication] respondsToSelector:#selector(registerUserNotificationSettings:)]) {
[[UIApplication sharedApplication] registerUserNotificationSettings: [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
} else {
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
}
application.applicationIconBadgeNumber = 0;
#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings
*)notificationSettings {
[application registerForRemoteNotifications];
}
#endif
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData
*)deviceToken {
const unsigned *tokenData = deviceToken.bytes;
NSString *deviceTokenString = [NSString stringWithFormat:#"%08x%08x%08x%08x%08x%08x%08x%08x", ntohl(tokenData[0]),ntohl(tokenData[1]),ntohl(tokenData[2]),ntohl(tokenData[3]),ntohl(tokenData[4]),ntohl(tokenData[5]),ntohl(tokenData[6]),ntohl(tokenData[7])];
[[NSUserDefaults standardUserDefaults]setObject:deviceTokenString forKey:#"devicetoken"];
NSLog(#"Device Token = %#", deviceTokenString);
}
//Failed to Register for Remote Notifications
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(#"Error in registration. Error: %#", error);
}
The device Token depends on the certificate you signed your application with. If you install directly it is the dev-certificate, while when signing for AdHoc it is a distribution certificate. For push you need a corresponding distribution or development certificate packed on your server.

Get Device Token in iOS 8

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

How to detect if user tap on "Don't Allow" on Apple's push notification confirmation alert

I want to fire some event if user taps on "Don't Allow" button on the apple's push notification alert message. Is there any notification getting fired or any other way to detect this action from the user?
I'm sure someone will need a solid and simple answer to this (like I once did) -- so here you go. Directly after calling [[UIApplication sharedApplication] registerForRemoteNotifications]; you can use NSNotificationCenter beautifully like so:
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification * _Nonnull note) {
if ([[UIApplication sharedApplication] isRegisteredForRemoteNotifications]) {
//user tapped "Allow"
}
else{
//user tapped "Don't Allow"
}
}];
NOTE: My device is currently running iOS 9.2, my Xcode is version 7.2, and my Deployment Target is 8.0.
I do't thing so that we can detect what UIAlertView button user pressed as there is no any kind of callback methods or delegate etc provided in iOS.
Only if you pressed Don't Allow this will disable the push notification service for that particular iOS App and if YES then enable.
And After that through the code we can check and ensure about it using.
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone)
// NONE
iOS8 comes with rregisterUserNotificationSettings: delegate method. Using this method we can do some patches.Please review them and Let us know your comments.Please these is only work with iOS8.
=> Add/Register Notification.
if ([[UIApplication sharedApplication] respondsToSelector:#selector(registerUserNotificationSettings:)])
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
}
=> Here Below method is called After Alert Notification Fire. Using Any of the Button Action(Don't allow or Allow) we force fully register Notification. and Dow with some patch Here.
#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
//register to receive notifications
[application registerForRemoteNotifications];
}
=>We do some trick here
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
NSLog(#"devToken: %#",devToken);
#if !TARGET_IPHONE_SIMULATOR
NSString* deviceToken = [[[[[devToken description]
stringByReplacingOccurrencesOfString: #"<" withString: #""]
stringByReplacingOccurrencesOfString: #">" withString: #""]
stringByReplacingOccurrencesOfString: #" " withString: #""] retain];
NSLog(#"deviceToken : %#",deviceToken);
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
if((![[standardDefaults valueForKey:#"DeviceToken"] isEqualToString:deviceToken]) || [standardDefaults valueForKey:#"DeviceToken"]==nil){
[self sendProviderDeviceToken:deviceToken];
}else{
//Do Some Stuff Here
}
}

Resources