iPhone PushNotification Registering Multiple Times - iphone

I am using PushNotification for my app. It Seems that the device token is generated each time the application is loaded. So in my server I have many duplicate device tokens.
Do I need to check the device token before adding it to database or am i doing some thing wrong with implementation in app?
Below the code Segment that I am using.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// launchOptions has the incoming notification if we're being launched after the user tapped "view"
NSLog( #"didFinishLaunchingWithOptions:%#", launchOptions );
// [self.viewController handleDidReceiveRemoteNotification:userInfo];
// other setup tasks here....
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeAlert)];
// [self updateWithRemoteData]; // freshen your app!
// RESET THE BADGE COUNT
application.applicationIconBadgeNumber = 0;
// ...
// call the original applicationDidFinishLaunching method to handle the basic view setup tasks
[self applicationDidFinishLaunching:application];
return YES;
}
- (void)application:(UIApplication *)app
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
[self sendDeviceTokenToRemote:devToken]; // send the token to your server
}
Could someone help? How can I store unique device tokens in my server?
thanks,
Nikil

In most cases, this APNs token assigned to each device is unique and constant. You can view it as another kind of UDID. So once a device is registered in your server's database, you don't have to register it again.
(This is the tricky part) However, according to Apple's documentation, APNs token could change, let's say, if the device has been updated to a higher version of OS or has some of its hardware be replaced with a new one. However, this doesn't happen that often.
As for converting and storing this APNs token in your app and in your server, check this post, iPhone pushNotification DeviceToken - How to "decrypt"
Hope it helps.

Applications should re-register for push notifications at each startup as a best-practice recommended by Apple. (see the Apple Local and Push Notifications Programming Guide)
How you store the device id in your server-side domain is up to you. One example would be to have a column representing the last time a device registered. You would add a row if it is a new device id, or update a row with a new timestamp if the device id already exists.

Related

What should the iOS application do when push is disabled by the user?

I know there is a possibility to check whether or not the user has disabled the push settings, as described in objective c - Detect when user change the app's notifications settings.
According to the article above, the push notification is sent even if the user has disabled push notifications for the application. As I understand it I should always register for push notifications in applicationDidFinishLaunching:.
Most example looks like this, i.e. the user settings are ignored.
- (void)applicationDidFinishLaunching:(UIApplication *)app {
// other setup tasks here....
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
}
If the application should take these settings into consideration, how does a correct implementation look like?
The reason why I ask this question is because we have a lot of customers complaining that they are getting push notifications although they have disabled push notifications. This seems to apply to iOS 6.
Should I as a developer take care of the case when the user has disabled push notifications? I have read the documentation over and over again. In particular the documentation for application:didReceiveRemoteNotification:. It does not states if it is called when the user has disabled push notifications.
make sure you implement these methods to know whether the device registered or not
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)_deviceToken {
if ([application enabledRemoteNotificationTypes] < 4) {
NSLog(#"Notifications are disabled for this application");
return;
}
// The device is registered for notifications
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
NSLog(#"FAILED TO REGISTER FOR PUSH NOTIFICATIONS");
NSLog(#"%#", error.userInfo);
}
it is ok to register for push notifications everytime your app is launched. but you have to make sure you implement the methods above to know if the user has enabled or disabled notifications for the app.

iPhone push notifications information

Is it possible to transfer any information in the push notification beside "badge" "sound" and "text"?
For example, in the app "whatsapp" when a push notification appears and pressed, the app is opened but not going to the conversation. My guess is that it can't know what conversation to go to. But then I saw that in facebook messenger app it actually goes in the conversation. how does the messenger app know that what conversation to go to?
Also, if it is possible to transfer information, why is it that apps like whatsapp don't use it and also ask you for your name so it will be displayed in the push?
Yes, indeed. But your message size (in bytes) must not pass a certain threshold Apple has imposed. You can then pull that info in the - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions using something like this:
NSDictionary* dictionary = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
Where dictionary contains your push notification info.
There are apps that have permission to run in the background and other apps that have not. May be facebook messenger app have this permission and can receive push notifications and do whatever is needed to go to the correct conversation or user. I don't know if this is true but it could be a possible reason.
in this method we can display pushnotifications alerts and their action according to our app
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(#"did receive remore notification %#",userInfo);
if(isForground)
{
}
}
You should take a look at this documentation section Examples of JSON Payloads
At the bottom you can see custom payload examples like:
{
"aps" : {
"alert" : "You got your emails.",
"badge" : 9,
"sound" : "bingbong.aiff"
},
"acme1" : "bar",
"acme2" : 42
}
Where acme1 and acme2 are custom data that you can pass to the push notification and get it inside you app after launched.
The data is available through UIApplicationDelegate callbacks as described here Handling Local and Remote Notifications
You can add more arguments in your payload. In our app we add something like
groupID, or type.
See this stack overflow for adding more payload arguments
APNS JSON PAYLOAD - more arguments
Make sure the message size doesnt exceed 256 bytes.It is the threshold limit for the payload

iOS 5.0 detect when the App is re-activated from a URL in Safari.app

In our workflow the user:
Starts a transaction in the App
Is redirected to Safari.app to confirm the transaction
Is redirected back to the app via link: myapp://finish-transaction where the transaction is checked again
The UI is updated based on the result
While my app get's re-activated when I click the link in Safari, I found it weird that none of these methods get called, upon reactivation.
application:openURL:sourceApplication:annotation
application:didFinishLaunchingWithOptions:
applicationDidBecomeActive:
applicationWillEnterForeground:
viewDidAppear: or viewWillAppear: in the current UIViewController
application:handleOpenURL:
I have the urlscheme myapp registered as an editor for the identifier com.mycompany.myapp in the Info.plist.
So how do I find out if the App was re-activated under iOS 5.0?
Try the following?
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
// Handle open here
}
So now this is embarrassing. I had multiple versions of the App installed in the simulator. So when coming back from the Webpage the wrong App would launch... And I would wait in vain for some love from the App which was still inactive...

Apple Push Notification is not delivered

I know it's a little bit flooded with Apple's Push Notification Service (APNs) issues all over StackOverflow so I actually did a lot of researches before coming up my question.
Basically, I have followed the apns-php's CertificateCreation, some tutorial like on mobiforge, and some from Matthijs Hollemans. Still, I can't get any notification posted onto my iPad 2.
Basically these are the steps I have done:
I followed the CertificateCreation tutorial, I came out with server_certificates_bundle_sandbox.pem, entrust_root_certification_authority.pem.
Followed the tutorial specified in mobiforge blog, I successfully created the App ID, provisioning profile and linked them together nicely.
Description: APNTest
Bundle Seed ID: Use Team ID
Bundle Identifier: com.learn.APN
Then I enable the Development Push SSL Certificate (only for now) using the same certificate request I have used just now to get the certs, and I download it and install it into my keychain.
I downloaded my provisioning profile in .mobileprovision file and loaded it into Xcode's Organizer under my iPad 2 device.
Next I create a simple application with only these codes:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
// Override point for customization after application launch.
return YES;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(#"%#", deviceToken);
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(#"Error: %#", error);
}
Then I configure the build parameters:
Targets > Info > Build Identifier: net.learn.APN
Targets > Build Settings > Code Signing Identity > (I chose the provisioning profile I have installed just now, and it automatically selects the identical profiles for my Debug and Release)
I build and run the application on my iPad 2. My application requesting for Push Notification and after I approved it, the Token ID appeared in my console:
2012-01-19 12:43:26.345 TestAPN[578:707] <3cb08612 9392996b 5332d2fc 5adce03d 994f8959 d7a2ac38 de7bed52 c8e0778e>
I used apns-php, changed the device ID (raw 64 hexa-values), then run the sample_push.php. Script ran successfully, but my device is not receiving any notification
Then I try to use the SimplePush.php. A "Message successfully delivered" appeared, but my iPad still doesn't receive any notification from APN
Question is, which steps have I done wrongly? I'm pretty newbie in this area, and it is actually a requirement for my project that the server need to send out messages to our own applications. We are aware of the third party softwares that send APN on behalf of you, but we would like to implement one ourselves.
I also came across the "APN Feedback Service" and I written this (base on the SimplePush) but sadly it's empty. What should I do now?
<?php
// Put your private key's passphrase here:
$passphrase = '';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'server_certificates_bundle_sandbox.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://feedback.sandbox.push.apple.com:2196', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
while (!feof($fp)) {
$data = fgets($fp, 1024);
var_dump(unpack("N1timestamp/n1length/H*devtoken", $data));
}
// Close the connection to the server
fclose($fp);
Note
I am aware of the differences between development/production certs.
iPad is not jailbroken, running iOS 5.0.1
Other App Store apps receives notifications normally
XCode 4.2.1, Lion 10.7.2
I hope I'm not duplicates any of the questions here.. ;)
EDIT
When I run php simplepush.php then php feedback.php, I received a feedback with my device ID. My App is still in the iPad, so does it mean my device ID is wrong?
[root#ip-xx-xx-xx-xx SimplePush]# php feedback.php
Connected to APNS
array(3) {
["timestamp"]=>
int(1326962028)
["length"]=>
int(32)
["devtoken"]=>
string(64) "3cb086129392996b5332d2fc5adce03d994f8959d7a2ac38de7bed52c8e0778e"
}
Thanks
EDIT
After much struggling and redoing all the steps written by Matthijs Hollemans, I finally get it working. So the problem lies within the incorrect PEM file generated... hmm
I had similar problem, for me the key thing I didn't know is that the device token is different for dev and prod (for the same device).
I was using the device token I got when testing in dev to test in prod. This was working fine in dev, but when I switched to prod I kept the same device token in my python script (assuming, wrongfully, that the device token would be the same for the same device) but the actual device token registered in prod was different.
In practice this wouldn't happen as the device token is sent to the server, but when I was testing I was using hard coded device token as I didn't want to involve the server.
Hopefully this will save someone some frustration.

How to detect an arrived sms message in IPhone?

How to detect an arrived SMS in code? and how can I auto check if it contains specific strings? for example I wanna send SMS to the Iphone which contains "specifString" and I want the receiver Iphone auto open my app.
You cannot, get a notification when a person receives a SMS, but you can enter a special url in that SMS that then would launch your application when clicked.
In your Info.plist you have to define some key-value pairs:
And then your app is launched when url like this is clicked:
yourapp://?foo=1&bar=2
as you can see, you can pass parameters to your app.
In your app you get a special event, when your app is launched from an url.
4.1 and earlier:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
// Do something with the url here
}
**4.2 and later **
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
// Do something with the url here
}
More details in documentation: "Implementing Custom URL Schemes"
Edit after WWDC Keynote 06.06.2011
New API iMessaging now supports messaging on iPad and also receipts to know if your message has been delivered.
You can not achieve what you are trying to do. Apple restricts this kind of things, because this amounts to spying on the user who uses your application.