Backend - Django
Frontend - Objective C (X-code)
I've followed this Apple Document to configure Push Notifications and successfully completed all steps.
For Backend, I am using django-push-notifications with Django==1.7 and it results into no error when message is sent.
For Frontend, I have added following lines to receive the notification,
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:#"<>"]];
token = [token stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"content---%#", token);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"DeviceToken!!!" message:token delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[alert show];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
....
}
But after this, I am not able to receive the notification. Have I completed and configured steps correctly? My X-code version is 6.3 and Apple Device with iOS version on 8.4. Should both be compatible versions to receive the notifications?
Is there any way to log or view the progress at APNs cloud?
Use deviceToken directly like
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
NSLog(#"My token is: %#", deviceToken);
}
Also you need to be sure that you're sending Push-notification.
Try to use this tutorial and their application it will help you to be sure that you're sending Push correctly and you need to fix frontend.
Check whether the device token are getting updated to your server.
Check the mode of push operation. Development or Distribution? Provision your application based on that.
Confirm that APNS service is enabled in your application and you are provisioned your app using that mobile provision.(In member center).
Also check whether the .pem is proper or not?
If everything is proper, the try deleting the existing build, restart the phone and install new build and try.
Related
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®Id=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.
i recently set up push notifications for my app using Parse. I have been able to get the notifications and the data sent but now i want to get the channel to which the notification has been sent. Is there any way to do so in ios?
Have you checked this guide? It's really helpful.
https://www.parse.com/tutorials/ios-push-notifications
Here's a quick summary. Create development and production certificates and then attach them to your developer account for the app that you want to be able to send pushes to. After attaching these certificates redownload them, change them to .p12 files w Keychain Access and then upload them to Parse.com. In Xcode make sure to go into your account via preferences and refresh it so you'll have an updated provisioning profile. I'd do this in the stable version of Xcode and not the beta.
Finally after doing all that you can start coding. In your app delegate attach this code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
...
}
Please note that the following code demonstrates how to add a user to a channel... This is Parse's default code and I actually suggest tweaking it a bit. They set it up so that your channels will be reset to global every time the application is launched. I'm not sure that you even need to invoke the method "registerUserNotificationSetting" at all after attaching the device's token to the backend. Take not this method will generate an API request...
- (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];
// This is Parse's default code
currentInstallation.channels = #[ #"global" ];
// I would change it to something like this
if (currentInstallation.channels.count == 0) {
currentInstallation.channels = #[ #"global" ];
}
[currentInstallation saveInBackground];
}
Finally the last bit of code just deals with what the application does if it receives a notification while in the foreground:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[PFPush handlePush:userInfo];
}
Good luck!
When you send the notification just add the channel name to the notifications data.
For example:
PFPush *push = [[PFPush alloc] init];
[push setChannel:#"my_channel"];
NSDictionary *data = #{#"alert":#"Hi there.",#"channel":#"my_channel"};
[push setData:data];
[push sendPushInBackground];
When you receive the notification you can simple get the channel from the payload/userInfo:
NSString *channel = payload[#"channel"];
I have a really strange problem with my app on iPhone 6 and 6 Plus (iOS 8.2). I've followed and read almost everything (I Think!) that I found on the web to figure this out, but still it doesn't work. I've tested the app on iPhone 4 (iOS 7.1), 4s (iOS 7.1), 5s (iOS 8.1) and iPad Mini (iOS 8.2) and they all can receive the push notifications on from the app. My XCode version is 6.2 and the iPhone 6 devices (iOS 8.2) are detected as ineligible devices on it. So I can't even run the app right from XCode.
I'm using php script to push the notifications. When the app first run on iPhone 6, it showed up a pop up alert asking for the push notification permission. On the device's settings, the app is there on the notifications settings. I've tried revoking the apns certificate and creating a new one, re-generating the .pem files, reseting the device contents and settings, uninstall and install the app. None of these ever worked and I am already pulling my hair out. I even asked the Apple technical support for this but their answer is really just blah. I've tried downloading an app from the app store that has push notifications feature. And somewhat the device can receive push notifications from that app. So, is there anything that I am missing here? Can someone help me in this?
As suggested, here's my code for registering the notifications. I called the method "registerForRemoteNotification" from inside "application:didFinishLaunchingWithOptions:" :
- (void)registerForRemoteNotification
{
if ([[UIApplication sharedApplication] respondsToSelector:#selector(registerUserNotificationSettings:)])
{
NSLog(#"system version >= 8.0");
UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert;
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
}
else {
NSLog(#"system version < 8.0");
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
}
#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
NSLog(#"Registering for remote notification");
[application registerForRemoteNotifications];
}
#endif
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(#"did register remote notification with device token");
NSString *newToken = [deviceToken description];
newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
newToken = [newToken stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"Device token: %#",newToken);
DataManager *sharedData = [DataManager sharedInstance];
sharedData.deviceToken = newToken;
[self requestProfileWithDeviceToken:newToken];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(#"Failed to get device token, error: %#", error);
[self requestProfileWithDeviceToken:#""];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(#"Receive push notification: %#",userInfo);
[self processPushNotification:userInfo];
}
Any help would be very much appreciated. Cheers.
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.
I need to send the APNS device token of my iOS app to my provider by calling a service that expects JSON data in my request. I'm reading Apple's Local and Push Notification Programming Guide and it only says that the application:didRegisterForRemoteNotificationsWithDeviceToken: delegate method passes the device token as NSData and you should pass it to your provider encoded in binary data. But I need it to be converted to string in order to be able to send a JSON request to my provider.
I've also been reading several posts related to this, since it looks it is a common scenario, but I've found some different ways to convert such device token to string to send it, and I'm not sure which of them should be the most appropriate. Which would the most reliable way to deal with this be? I suppose my provider will need to convert this string back to call APNS, and I also need to store this token in the app in order to safely compare it with the new value if a new token is generated and application:didRegisterForRemoteNotificationsWithDeviceToken: is called, to send the token only if it has changed.
Thanks
You are right that you have to convert the device token from NSData to NSString to
be able to send it with a JSON object. But what conversion method you choose is completely
up to you or the requirements of the provider. The most common methods are a
hex string (see for example Best way to serialize an NSData into a hexadeximal string) or a Base64 string (using
base64EncodedStringWithOptions). Both are 100% "reliable".
Also you should always send the device token to the provider and not only when it has changed. The provider has to keep a database of all device tokens with a timestamp of
when it was sent last recently, in order to compare the timestamp with a possible response
from the "feedback service".
In didFinishLaunchingWithOptions method
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
After doing above lines of code ,add the method below
#pragma mark Push Notifications
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *token_string = [[[[deviceToken description] stringByReplacingOccurrencesOfString:#"<"withString:#""]
stringByReplacingOccurrencesOfString:#">" withString:#""]
stringByReplacingOccurrencesOfString: #" " withString: #""];
NSString* strURL = [NSString stringWithFormat:#"http://www.sample.com?device_token=%#&type=IOS",token_string];
strURL=[strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"%#",strURL);
NSData *fileData = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
NSLog(#"content---%#", fileData);
}
After the above listed steps you can use this delegate function to retrieve and handle push notification once it comes.The below added method will fire either the app is running in background or not.The method given below is available from ios7.0
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
const unsigned *tokenBytes = [deviceToken bytes];
NSString *hexToken = [NSString stringWithFormat:#"%08x%08x%08x%08x%08x%08x%08x%08x",
ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
Converting data to bytes means we can count it. Removing spaces and <> is really not a good idea
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)_deviceToken {
NSString *str = [NSString stringWithFormat:#"%#",_deviceToken];
//replace '<' and '>' along with spaces before you send it to the server.
}
this has worked reliably for me on almost all web platforms.