Doesn't get Push Notification with APNS - ios

I have followed this tutorial http://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1
As notification has been sent successfully from the server as described in tutorial. But i am not getting it in my device.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
if(![[NSUserDefaults standardUserDefaults] valueForKey:#"UUID"])
{
if (SYSTEM_VERSION_LESS_THAN(#"6.0"))
{
deviceID = [self GetUUID];
}
else
{
NSUUID* udid= [UIDevice currentDevice].identifierForVendor;
deviceID = [udid UUIDString];
}
[[NSUserDefaults standardUserDefaults] setValue:deviceID forKey:#"UUID"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
else
{
deviceID = [[NSUserDefaults standardUserDefaults] valueForKey:#"UUID"];
}
return YES; }
- (NSString *)GetUUID {
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return (__bridge NSString *)string; }

For push notifications you have to register with the push notification token. iOS returns the push notification token with spaces, you have to remove them:
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *token = [[devToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:#"<>"]];
token = [token stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"token: %#", token);
}

Have you implemented application:didReceiveRemoteNotification: in your application delegate? When you're in app notifications get received there.
Or is it no notification gets sent to you?

What's the size of your payload? The maximum length is 256bytes. If your payload is over that limit, it may say the push has been sent successfully yet Apple rejects it silently.
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html

Related

Store device token in AppDelegate, then use it in ViewController

I am trying to get the device token in my AppDelegate, and then use it in a function in my ViewController later.
I successfully retrieve the device token like so in the AppDelegate:
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
NSString *tokenAsString = [[[deviceToken description]
stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]]
stringByReplacingOccurrencesOfString:#" " withString:#""];
[[NSUserDefaults standardUserDefaults] setObject: token forKey:#"deviceToken"];
[[NSUserDefaults standardUserDefaults]synchronize];
}
Then I am trying to use it in a function in my ViewController, but it is printing as null:
-(void)addDeviceToken{
NSString *deviceToken = [[NSUserDefaults standardUserDefaults] objectForKey:#"deviceToken"];
NSLog(#"%#", deviceToken);
}
Does anyone know how to get the variable to show up here?
Replace token with tokenAsString.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
NSString *tokenAsString = [[[deviceToken description]
stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]]
stringByReplacingOccurrencesOfString:#" " withString:#""];
[[NSUserDefaults standardUserDefaults] setObject: tokenAsString forKey:#"deviceToken"];
[[NSUserDefaults standardUserDefaults]synchronize];}

how to get Device Token in iOS?

I am working on push notifications. I wrote the following code for fetching a device token.
-(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];
NSLog(#"Registering for push notifications...");
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
return YES;
}
-(void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *str = [NSString stringWithFormat:#"Device Token=%#",deviceToken];
NSLog(#"This is device token%#", deviceToken);
}
-(void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err
{
NSString *str = [NSString stringWithFormat: #"Error: %#", err];
NSLog(#"Error %#",err);
}
Try this code :
// Register for Push Notification
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)];
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings // NS_AVAILABLE_IOS(8_0);
{
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken{
NSLog(#"deviceToken: %#", deviceToken);
NSString * token = [NSString stringWithFormat:#"%#", deviceToken];
//Format token as you need:
token = [token stringByReplacingOccurrencesOfString:#" " withString:#""];
token = [token stringByReplacingOccurrencesOfString:#">" withString:#""];
token = [token stringByReplacingOccurrencesOfString:#"<" withString:#""];
}
Note : simulator not return deviceToken, deviceToken only return in device with valid APNS certificate
Enable "Push Notifications" in Xcode, this will fix the issue.
Targets -> Capabilities -> Push Notifications
Note:
Provisioning Profiles Should be in Active State
In iOS 8 and iOS 9 you need to register for notifications like this:
NSLog(#"Registering for push notifications...");
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
Note that if you also want to support iOS 7, then you'll need to call your existing code on the earlier versions of iOS.
Same issue happened with me So You have to use following code to get device token:-
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:#"<>"]];
token = [token stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"content---%#", token);
}
Even then it doesn't work Then please check your provisioning profile,it should be of that app ID by which you have created your ssl certificate for push notification.
Here is the latest code of swift 4.0, so you can use following code to get device token.
import UserNotifications
if #available(iOS 10, *) {
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]){ (granted, error) in
}
UIApplication.shared.registerForRemoteNotifications()
} else {
UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))
UIApplication.shared.registerForRemoteNotifications()
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = deviceToken.map { String(format: "%.2hhx", $0) }.joined()
}
Get device token in Swift 3
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = String(format: "%#", deviceToken as CVarArg)
.trimmingCharacters(in: CharacterSet(charactersIn: "<>"))
.replacingOccurrences(of: " ", with: "")
print(token)
}

How to pass deviceToken from AppDelegate to ViewController? iam getting DeviceToken is nil

I'm getting DeviceToken is nil
Please help me.
Code in AppDelegate is as follows
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *deviceTokenString = [NSString stringWithFormat:#"%#", deviceToken];
NSLog(#"Device token : %#", deviceToken);
[[NSUserDefaults standardUserDefaults] setObject:deviceTokenString forKey:#"DeviceToken"];
[[NSUserDefaults standardUserDefaults] synchronize];
[[NSUserDefaults standardUserDefaults] setObject:#"1" forKey:#"isNotificationsEnabled"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Code of ViewDidLoad
- (IBAction)NextBtn:(id)sender
{
NSString *getDeviceToken = [[NSUserDefaults standardUserDefaults] objectForKey:#"DeviceToken"];
NSLog(#"DeviceToken:%#",getDeviceToken);
getDeviceToken = [getDeviceToken stringByReplacingOccurrencesOfString:#"<" withString:#""];
getDeviceToken = [getDeviceToken stringByReplacingOccurrencesOfString:#">" withString:#""];
[service registerWithCounty:[NSString stringWithFormat:#"%ld", (long)country1.Id] andPhoneNumber:self.phNumber andDeviceId:getDeviceToken];
}
The iPhone Simulator cannot receive push notifications or successfully register for them.
You should rather use a device for testing this functionality.
For registering and using PUSH functionality you require a APNS supported provisioning profile which can be utilised/installed on a device only.
Register for RemoteNotification in following method
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { }
with following 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:
(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
}
Then implement following method
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSString* strToken = [deviceToken description];
strToken = [strToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
strToken = [strToken stringByReplacingOccurrencesOfString:#" " withString:#""];
[[NSUserDefaults standardUserDefaults] setValue:strToken forKey:#"device_token"];
[[NSUserDefaults standardUserDefaults] synchronize];
}

Push Notification works only once

The push notification only works when the app is in background ,But it didn't work when i removed it from background also when it returned to background , i didn't receive any push notifications. I had to delete the app and download it again from testflight to be able to receive push notifications.
here's the code
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
#if !TARGET_IPHONE_SIMULATOR
//Do stuff that you would do if the application was not active
NSLog(#"remote notification: %#",[userInfo description]);
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
NSLog(#"Aps Info : %#",apsInfo);
NSString *alert = [apsInfo objectForKey:#"alert"];
NSLog(#"Received Push Alert: %#", alert);
NSString *sound = [apsInfo objectForKey:#"sound"];
NSLog(#"Received Push Sound: %#", sound);
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
NSString *badge = [apsInfo objectForKey:#"badge"];
NSLog(#"Received Push Badge: %#", badge);
application.applicationIconBadgeNumber = [[apsInfo objectForKey:#"badge"] integerValue];
#endif
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
{
NSInteger pushCode = [userInfo[#"pushCode"] integerValue];
NSLog(#"Silent Push Code Notification: %i", pushCode);
NSDictionary *aps = userInfo[#"aps"];
NSString *typeID = userInfo[#"type_id"];
NSString *alertMessage = aps[#"alert"];
NSLog(#"Type ID %#",typeID);
NSArray * array =[typeID componentsSeparatedByString:#","];
NSLog(#"Item %#,Item2 %#",[array objectAtIndex:0],[array objectAtIndex:1]);
[self typeID:[array objectAtIndex:0] userID:[array objectAtIndex:1] message:alertMessage];
NSLog(#"apss%#,alert%#,%#",aps,alertMessage,userInfo);
}
The problem is in the method:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
{
}
you should "catch" the notifications which arrive in background with this method:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
}
the fetchCompletionHandler method is designed for receiving "silent" push messages, which gets called prior to didReceiveRemoteNotification, if implemented.

How to pass the device token from AppDelegate to UIViewController

Hi in my application I'm fetching the device token and I'm passing to my server to send the notification now I want to send the individual notification for the i need to fetch the device token form my UIViewController Please tell is there any possibilities fetching the device token form the Appdelegate or from the UIViewController
My code for fetching the device token in Appdelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeNone)];
return YES;
}
Device Token.
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
const char* data = [deviceToken bytes];
NSMutableString * token = [NSMutableString string];
for (int i = 0; i < [deviceToken length]; i++) {
[token appendFormat:#"%02.2hhX", data[i]];
}
NSString *urlString = [NSString stringWithFormat:#"url?token=%#",token];
NSURL *url = [[NSURL alloc] initWithString:urlString];
NSLog(#"token %#",urlString);
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSLog(#"request %# ",urlRequest);
NSData *urlData;
NSURLResponse *response;
urlData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:nil];
NSLog(#"data %#",urlData);
}
I have used the to get the device token please tell me how to pass the device token to my UIViewController or how to fetch the device token from my UIViewController.
Use the NSUserDefaults to store the objects(values), you can access it anywhere.
AppDelegate (setValue) :
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
[[NSUserDefaults standardUserDefaults] setObject: token forKey:#"deviceID"];
[[NSUserDefaults standardUserDefaults]synchronize];
}
UIViewController (getValue) :
[[NSUserDefaults standardUserDefaults] objectForKey:#"deviceID"];
In AppDelegate.m class:
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSLog(#"My token is: %#", deviceToken);
NSString *device = [deviceToken description];
device = [device stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
device = [device stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"My device is: %#", device);
[[NSUserDefaults standardUserDefaults] setObject:device forKey:#"MyAppDeviceToken"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
In ViewController class, inside viewDidLoad method:
[super viewDidLoad];
NSString *deviceToken = [[NSUserDefaults standardUserDefaults] objectForKey:#"MyAppDeviceToken"];
NSLog(#"device token in controller: %# ", deviceToken);
This is working perfectly in my device. Happy Coding !! :)
Try this coding in your view did load
NSString* deviceId = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
deviceId = [deviceId stringByReplacingOccurrencesOfString:#"-" withString:#""];
NSLog(#"%#",deviceId);
Declare and define below methods in your delegate file,
#pragma mark - Get / Set Device Token
+ (void)setDeviceToken:(NSString *)token {
if(token) {
[[NSUserDefaults standardUserDefaults] setObject:token forKey:#"DeviceToken"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
+ (NSString *)getDeviceToken {
NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:#"DeviceToken"];
if(token) {
return token;
}
return #"";
}
In -(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken method
call, [AppDelegate setDeviceToken:token]; once you get the token and
Now in project, in any view controller, you can call NSString *token = [AppDelegate getDeviceToken]; to get saved token, here note that, we call it with AppDelegate its name of your delegate file, and we call it with the class name, as we make a class method to set and get a token.
At the time of getting you can check for availability of saved token
NSString *token = [AppDelegate getDeviceToken];
if(token.length) {
// do something
}
You can get appDelegate instance in any view contoller and fetch value from that instance like -
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

Resources