My app is already on the app store and with push notifications active and working (using production certificate). Now I need to add badges (before their were only alerts) in the application (already implemented on the server side). So for testing I would need a development SSL certificate. So following are my queries:
Do I have to install the development SSL certificate on my server so that I can test on iPhone using development cert?
Will it not conflict with the already installed production SSL cert on the server.
Do I have to add badges in both didReceiveRemoteNotification: and didFinishLaunchingWithOptions: delegates using below code:
code section:
NSString* alertValue = [[userInfo valueForKey:#"aps"] valueForKey:#"badge"];
NSLog(#"my message-- %#",alertValue);
int badgeValue= [alertValue intValue];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:badgeValue];
Any suggestions?
Just to add some additional color to the Certificate/Server/SSL questions and answers that have been proposed:
Prod/Sandbox APNS Picked Based on Codesign Settings
For the sake of being thorough, lets start with a quick review of the APNS environment:
Applications that are Code Signed with an iOS Development certificate connect to and wait for Push Notifications to be delivered from the Sandbox APNS Environment
Applications that are Code Signed with an iOS Distribution certificate (AppStore or Distribution > Ad-Hoc) connect to and wait for Push Notification to be delivered from the Production APNS Environment.
This setting is automatically determined by Xcode during the build process and is only configurable by selecting the type of certificate used in the CodeSign step.
Question 1: Do I have to install the Development SSL Certificate on my Server to Test Development Certificate Signed Apps Push Notifications?
Yes, once and app is Code Signed, its APNS setting is sealed into the binary using the rules in the previous section. It is then up to the Developer's server code to know that the APNS token that device will generate goes with the Sandbox APNS environment and that the server should route that request for a push notification to gateway.sandbox.push.apple.com instead.
Some developers choose to setup a single server that is capable of making these distinctions while others choose to setup side-by-side instances of their servers one set to send to Production and another set to send to the Sandbox.
Either way, the decision resides with the individual developer and what their server-side code is capable of doing and the relative complexity of setting up a second server. Either way, users might get upset if you accidentally disabled Production push notifications while testing out upcoming features then forgot to reenable them later, so definitely be careful when poking around production code!
Question #2: Will the Development and Production SSL Certificate Conflict?
From the raw SSL standpoint no they won't conflict -- you should be able to download and open/examine both of those certificates on a machine other than the server and see that the contents of the certificates are in fact different. Importing them into the same server environment (again from an SSL perspective) is perfectly allowable. To ensure they are different, when requesting the certificates make absolutely sure you create two different certificateSigningRequests and you'll inherently wind up with different data.
From the Developer's Server-side Push Code standpoint -- It depends. See the conversation in Question 1 regarding server-side code capabilities. If the server-code was designed with this in mind then in theory the answer is also 'No they will not conflict', but that is a determination the individual developer needs to make about their own server-side code capabilities.
Yes, you should install the development SSL certificate on server. You also have to use sandbox push-notification service (gateway.sandbox.push.apple.com) with this certificate.
I guess they won't conflict. You should just use production SSL for AppStore app, and development SSL for test app.
It's better not to increment or decrement or set badge value in code. Your server should return badge value in notifications body. For example, You can't handle push when your app is not running, thus you cant change badge value in code. But if your push contains badge value, it will be set and displayed correctly any way.
Here is the notification body example. Pass badge value for key "badge":
{"aps":{"alert":"This is message.","badge":7}}
By the way, didReceiveRemoteNotification: method always called when you app receives push. Even if the app is down, it will be called when you launch the app from push.
I just wanted to add something to the existing answers. While the development cert won't conflict with the production cert installed on the same server, you might get conflicts with the device tokens stored in your DB. When you use a development cert, you get development device tokens from Apple, which are not the same as the production device tokens you'll get for your production cert. If you keep both development and production device tokens in the same database (which you probably will if you use the same server for both development and production), you will have trouble if you send notifications with development device token using the production cert or vica versa.
That's why it is recommended by Apple to use separate servers for development and production.
This quote is taken from Troubleshooting Push Notifications, which is a very useful document :
The most common problem is an invalid device token. If the token came
from the sandbox environment, such as when you are testing a
development build in house, you can't send it to the production push
service. Each push environment will issue a different token for the
same device or computer. If you do send a device token to the wrong
environment, the push service will see that as an invalid token and
discard the notification.
Note: It is recommended that you run a separate instance of your
provider for each push environment to avoid the problem of sending
device tokens to the wrong environment.
Related
I am trying to determine what I need to do with respect to the combination of APNS endpoint (e.g., development or production), Xcode, and Apple Push certificates in order to test push notifications while in development. I feel like I've tried every possible combination, but I must be missing something ...
Background
When using Apple's HTTP/2 APNS endpoints from my "dispatch" server, my app/device does not receive pushes, and I receive a BadDeviceToken response from Apple.
Using the exact same .p12 certificate and deviceToken with the Pusher macOS testing app (which uses legacy APNS endpoints), the pushes successfully deliver.
To complicate this further ...
When using Apple's HTTP/2 APNS endpoints from my "dispatch" server for PassKit pushes, my pass/device does receive pushes.
So ...
Point #3 tells me that my "dispatch" server must be configured properly, because pushes to the Apple Wallet pass cause a response (e.g., I can see follow-on requests to my server's endpoints from the Wallet / the pass).
That said, Apple Wallet is a "Production" app. I suspect that, because my app (from Point #1) is non-production/development, something is different.
.
Question
Has anyone been able to successfully receive -- in Xcode -- push notifications sent to Apple's api.development.push.apple.com endpoint? Can you outline the steps you performed (which certificate from developers.apple.com, etc.)? Thank you!
You should be able to send development push from server:
You need to connect to api.development.push.apple.com:443 instead of api.push.apple.com:443. You can use production certificate for both.
Sending push to production server can not work with development builds - only with a build that is exported with AppStore configuration, but you can't debug those (at least not with Xcode)
If you need to check whether the production endpoint works, you can use testflight
Set development certificate from apple developer portal.
Use either production/test server for communicating with APNS.
Edit your target scheme as follows :
This will ensure that when push notification arrives, control will itself fall in the code. It might seem confusing. But here it is how it works :
- Install app on device and stop the Run process from Xcode.
- Place a breakpoint on didReceiveRemoteNotification.
- Send a push notification to device.
- Xcode will itself start the app and control will go to the above function.
I'm trying to test Push Notifications on an app which has been developed by other team. We have the app installed in our device and validated (the app is no yet in the App Store).
Connection parameters with APNS server are ok.
We launch our script to execute the Push Notification but we don't receive any notification in our device/app.
Question:
There are any log or trace in APNS of our demands?
Have APNS any history of the Notifications sended and its status ?
Note : We use Adobe Campaign to generate Push Notifications services.
We've tested the flux with an alpha version of the app and worked but now with a RC candidate doesn't work.
Thanks in advance
I recommend to check all these possibilities:
Notification is not sent from server
Try to log apns response to see if this is the issue
Check if apple certificates used are expired
Check if you're sending notification using development or production certificates with the right gateway. As Apple say:
The binary interface of the production environment is available through gateway.push.apple.com, port 2195; the binary interface of the development environment is available through gateway.sandbox.push.apple.com, port 2195.
Notification is sent from server but is not received by device
Check in settings if push notification are enabled for your app
Check if some code is hiding the notification when the app is in foregroud or is working in background
Check if you have installed the right environment application (if you send notification for production you won't receive nothing in a development build of the app)
Check the device token used to send notification
Did your app communicate to your server that it is a staging app and that the script should send APN via the Apple staging server?
Did you also deploy staging certs/keys to your server?
Did you log the response you got from the APN server when your server communicated with it?
Use APN Tester app save my day, thanks "sanandiya viper".
The problem was app's developers don't tell us p12 certificate is production one and we installed it as developer certificate. APN Tester bring us the choice to test booth options.
Thanks for all your answer. Problem solved.
I’m providing this question and answer because I’ve not seen the problem I ran into with the fairly common ‘APNS not working problem’ and perhaps my experience could help others.
One of my apps that I have in the store uses push notifications. Version 1 of the app was working just fine. No problems.
I created version 1.1, tested it on the sandbox APNS (worked fine) and submitted it. Sometime after 1.1 was approved I noticed push notifications weren’t working. My device was not receiving any push notifications, nor was any other user. That naturally led me to believe I’d screwed up something with the certificates or something like that when I created v 1.1. I checked all the normal things - sandbox vs production, certificates, provisioning profiles, etc. No dice.
--My server setup
I’m doing the interaction with the APNS servers myself and whenever I send an APNS message to Apple I got a positive response. My server code opens a connection to the APNS gateway, sends an APNS message for every device that needs one, then closes the connection.
(this next bit is key to the problem)
In the user record in my DB, I keep track if the user installed the dev version of the app or the production version of the app. I keep this as a flag in the user record. I do this for ease of use.
For simplicity sake, I have one script that processes the development users and sends their APNS messages to the sandbox server and separate code that sends the production user’s APNS messages to the production APNS gateway.
All of that was working fine. I’ll save you all the recertification steps and other grief that I did.
As far as I could tell everything was working fine and everything was set up correctly. So I followed the advice of Ms. Rand: “Contradictions do not exist. Whenever you think that you are facing a contradiction, check your premises. You will find that one of them is wrong.”
After too many hours trying to figure out what was going on I finally determined the problem.
I had turned a development user (my wife’s iPhone) into a production user as I thought she had downloaded the production release of the app
For this user, my server was using the deviceID generated from the development app and sending that to the production APNS server
Whenever I would send that device ID to the production server as one of the APNS messages, even though I would get a positive response from the servers, none of the APNS messages to any other devices would work.
Once I flipped her user record back to be a development device, everything began working again.
I verified multiple times that this was the problem.
So, it appears that using a deviceID that’s intended for sandbox APNS interaction and sending it to the production APNS really screws things up.
Hope this helps somebody in the future.
I've got an iOS app using push notifications via Parse.com, and I'd like to do some testing where notifications are only sent to test devices. If I simply switch over to a development certificate, I presume the notifications won't go to production devices.
However, I'm slightly concerned about doing something wrong and accidentally trying to send hundreds of thousands of push notifications to production devices via the development certificate.
I know the production devices would not receive the notifications, but would there be any wider issue to something like this happening - i.e. my app getting flagged as spam or something like that?
If you try to send notifications to production device tokens using development certificate (and connecting to APNS sandbox server), you'll get an error of invalid device token for each notification and the connection will be closed after each message you send. Most of the messages won't even reach Apple, since they close the connection once they find an invalid message, and all the messages sent after that message are discarded.
A bigger problem would be if you store sandbox (=development) device tokens in the same DB as the production tokens. If you don't distinguish between the two types of tokens, when you switch back to production push notifications, you run the risk of trying to send notifications to sandbox tokens using the production push certificate, which would give you errors and close your connection to APNS, thus disrupting the push to the production tokens. Therefore I strongly suggest that you use a different DB to store the sandbox device tokens.
We are trying to send a notification to ~500,000 iOS devices. We have currently set the batch size to 200 and are noticing that Apple refuses our connection after 300k messages or so. We suspect that Apple interprets our connection/tear-downs to be a DOS attack. What is a good batch size for us to use? Also, any tips on sending notifications for such a large number of devices?
Your push notification server must maintain a persistent connection to Apple's socket stream push server without disconnecting too often.
I recommend writing your push server using Node.js, it was designed for this stuff.
However there are a few things that can also cause Apple to disconnect your push server.
With Push Notification, there are two types of certificates - development and production.
An app signed with a development certificate will generate a development push token whereas a an app signed with a production certificate will generate a different production push token even on the same device.
Your server must make sure it does not send a development token to a production socket stream connection to Apple's push server.
Mixing the token and environment will cause Apple's push server to disconnect your push server.
How you separate your push token is something that you need to build into your server.
Hope that helps.