How can I test Apple Push Notification Service without an iPhone? - ios

Is it possible test the Apple Push Notification Services without an iPhone application? (Creating an emulator on windows?)
If isn't, how could I test that? Is there a free sample application compiled to do that?
I created the Server provider, but I need test the functionallity.

This answer is outdated. As of 2020 / Xcode 11.4 it's now possible to test push notifications in the simulator
See this full explanation in an answer below
Sorry to say, but you'll need to find some hardware to test this functionality.
Push notifications are not available in the simulator. They require a provisioning profile from iTunes Connect, and thus are required to be installed on a device. That also means you'll probably have to be accepted into the apple iPhone developer program and pay your $99.
On the bright side, with the iPhone OS 3.0 update, you can test this functionality on any device, including the first gen iPhones.

You can't test real push notifications. However, you can test your app's response to a simulated push notification by creating one programmatically and manually triggering your AppDelegate's - application:application didReceiveRemoteNotification:notification method.
To trigger this from a different class (like a UIViewController):
[[[UIApplication sharedApplication] delegate]
application:[UIApplication sharedApplication]
didReceiveRemoteNotification:testNotification];
The testNotification should have the same format as a real notification, namely an NSDictionary that contains property list objects plus NSNull.
Here's an example of how to provide the testNotification above:
NSMutableDictionary *notification = [[NSMutableDictionary alloc] init];
[notification setValue:#"Test" forKey:#"alert"];
[notification setValue:#"default" forKey:#"sound"];
NSMutableDictionary *testNotification = [[NSMutableDictionary alloc] init];
[testNotification setValue:notification forKey:#"aps"];
This should create a reasonable notification NSDictionary to work with.

Testing push notifications using the Xcode 11.4 iOS Simulator
As of Xcode 11.4, it is now possible to simulate push notifications by dragging and dropping an .apns file onto the iOS simulator. The Xcode 11.4 release notes have the following to say about the new feature:
Simulator supports simulating remote push notifications, including
background content fetch notifications. In Simulator, drag and drop an
APNs file onto the target simulator. The file must be a JSON file with
a valid Apple Push Notification Service payload, including the “aps”
key. It must also contain a top-level “Simulator Target Bundle” with a
string value matching the target application‘s bundle identifier.
simctl also supports sending simulated push notifications. If the file
contains “Simulator Target Bundle” the bundle identifier is not
required, otherwise you must provide it as an argument (8164566):
xcrun simctl push <device> com.example.my-app ExamplePush.apns
Example
Here is an example for such an .apns file, targeted towards the system settings app:
{
"Simulator Target Bundle": "com.apple.Preferences",
"aps": {
"alert": "This is a simulated notification!",
"badge": 3,
"sound": "default"
}
}
Dragging and dropping this onto the target simulator will present the notification and set the badge:
Now, to use this for debugging purposes, you only have to change the Simulator Target Bundle to your own app's identifier and adjust the payload to your debugging needs!

Nowadays, we can test push notifications with this library.
It's pretty easy to send push via terminal:
echo -n '{"message":"message"}' | nc -4u -w1 localhost 9930
echo -n '{"aps":{"alert" : "message","badge" : 99,"sound" : "default"}, "myField" : 54758}' | nc -4u -w1 localhost 9930

Apple has supporting push notification for simulators.
iOS 13.4 and above or Xcode 11.4 and above.
as usually create Xcode project and implement a user notification and authorization permission.
run your application in simulator iOS 13.4 and above.
put your application in background.
Create an APNS payload file named "payload.apns"
{
"aps": {
"alert": {
"title": "Test Push",
"body": "Success! Push notification in simulator! 🎉",
"sound": "default"
},
"badge": 10
},
"Simulator Target Bundle": "com.company.app"
}
Drag and drop to your iOS simulator.
right now your push notification will appear on simulator.
And also you can simulate push notification by terminal
get your simulator identifier by opening Window->Devices and Simulators and choose your targeted simulator and right click and copy your identifier.
Now build a terminal command like
xcrun simctl push <simulator-identifier> <path-to-payload-file>
ex:
xcrun simctl push 27A23727-45A9-4C12-BE29-8C0E6D1E5360 payload.apns
run this command and simulate push notification in simulator

The simulator does not do Push Notifications.
And to push from a server, you have to have device(s) to push to as well as your app on that device.
The token contains the app identity as well as the device ID.

With macOS 13 and Xcode 14, when on Mac computers with Apple silicon or T2 processors, it’s now possible to receive real push notifications as didRegisterForRemoteNotificationsWithDeviceToken will return a real token.
See Xcode 14 release notes:
Simulator now supports remote notifications in iOS 16 when running in macOS 13 on Mac computers with Apple silicon or T2 processors. Simulator supports the Apple Push Notification Service Sandbox environment. Your server can send a remote notification to your app running in that simulator by connecting to the APNS Sandbox (api.sandbox.push.apple.com). Each simulator generates registration tokens unique to the combination of that simulator and the Mac hardware it’s running on.
https://developer.apple.com/documentation/xcode-release-notes/xcode-14-release-notes

Xcode 11.4 Beta starts supporting push notification in Simulator
Simulator supports simulating remote push notifications, including background content fetch notifications. In Simulator, drag and drop an APNs file onto the target simulator. The file must be a JSON file with a valid Apple Push Notification Service payload, including the “aps” key. It must also contain a top-level “Simulator Target Bundle” with a string value matching the target application‘s bundle identifier.
simctl also supports sending simulated push notifications. If the file contains “Simulator Target Bundle” the bundle identifier is not required, otherwise you must provide it as an argument (8164566):
$ xcrun simctl push <device> com.example.my-app ExamplePush.apns
Release Notes: https://developer.apple.com/documentation/xcode_release_notes/xcode_11_4_beta_release_notes

you have to use
NSString *notificationString = #"{\"aps\":{\"alert\":\"Test alert\",\"sound\":\"default\"}}";
NSData *notificationData = [notificationString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *testNotification = [NSJSONSerialization JSONObjectWithData:notificationData options:0 error:&error];
[[[UIApplication sharedApplication] delegate] application:[UIApplication sharedApplication] didReceiveRemoteNotification:testNotification fetchCompletionHandler:nil];

Apart from #fredpi's answer, you can also use the Poes command-line tool. It allows us to quickly test remote push notifications on the iOS simulator without the hassle of creating a JSON payload file.
Poes --help
OVERVIEW: A Swift command-line tool to easily send push notifications to the iOS simulator
USAGE: Poes <options>
OPTIONS:
--body, -b The body of the Push Notification
--bundle-identifier The bundle identifier to push to
--mutable, -m Adds the mutable-content key to the payload
--title, -t The title of the Push Notification
--verbose Show extra logging for debugging purposes
--help Display available options
The following command could be enough to send out a simple push notification with a default title and body:
$ Poes --bundle-identifier com.wetransfer.app --verbose
Generated payload:
{
"aps" : {
"alert" : {
"title" : "Default title",
"body" : "Default body"
},
"mutable-content" : false
}
}
Sending push notification...
Push notification sent successfully

Yes, you can check push notification on the simulator, but you have to use a library in your app named SimulatorRemoteNotifications. By which, by using just 4-5 steps, you can test push notification on the simulator.
They also provide PODs too:
pod 'SimulatorRemoteNotifications', '~> 0.0.3'

It looks like now we have very powerful lib https://github.com/ctreffs/SwiftSimctl
At least it's much more power than lib SimulatorRemoteNotifications which were mentioned here. And which was obsoleted also.

For a more complete answer since Xcode 11.4 and as of Xcode 12.4:
Simulator supports simulating remote push notifications, including background content fetch notifications. In Simulator, drag and drop an APNs file onto the target simulator. The file must be a JSON file with a valid Apple Push Notification Service payload, including the “aps” key. It must also contain a top-level “Simulator Target Bundle” with a string value that matches the target application’s bundle identifier. simctl also supports sending simulated push notifications.
Notification Service Extensions do not work in simulated push notifications. The mutable-content key is not honored. (55822721)
Reference: Xcode 11.4 Release Notes

Most answers suggest using a third-party Cocoapods/SPM dependency. But these dependencies can easily become unsupported for quite a while after a new iOS or Xcode release.
Here is just a lightweight solution that will work in any case and in any weather:
Start any HTTP server on localhost before running the tests (e.g.: ruby/python)
Send a POST request to this localhost from the test when you need to trigger a push notification (e.g. via URLSession)
Get a request on localhost and execute an xcrun simctl push command
For more details feel free to check out this blog post. Hope this helps.

Related

Push notifications from firebase in iOS simulator

I have an app that uses cordova-plugin-firebasex for the push notifications. But they don't appear in notification center while app is in the background. I'm using iOS simulator in XCode.
Can I test Firebase notifications in simulator while app is in the background? Or I need real device for this?
Simulators are not supporting push notifications. You can see this output text from Firebase SDK in yuor console output
Like
6.27.0 - [Firebase/Messaging][I-FCM012002] Error in application:didFailToRegisterForRemoteNotificationsWithError: remote notifications are not supported in the simulator
You can actually test the notifications locally using the XCode Simulator Control Utility:
xcrun simctl push booted payload.json
with the following payload stored in the JSON file in your local directory:
{
"aps": {
"alert": {
"title": "Local notification test",
"body": "This is the body of your local notification."
}
},
"Simulator Target Bundle": "com.example.example"
}
Where the com.example.example is your bundle identifier.
For more information have a look at the utility's documentation:
xcrun simctl push --help

Push notifications in simulator - Not working Xcode 11.4beta

Recently Apple has added push notifications in simulators as well. My existing app notifications are not being received in simulators.
How to simulate push notification in simulator?
Simulator supports simulating remote push notifications, including background content fetch notifications.
Reference: https://developer.apple.com/documentation/xcode_release_notes/xcode_11_4_beta_release_notes
Yes, you are right. With Xcode 11.4:
Simulator supports simulating remote push notifications, including background content fetch notifications. (xcode 11.4 release notes)
You just need to drag&drop a valid APNs file onto your simulator.
However, if someone is asking why the instance method didReceive(_:withContentHandler:) of UNNotificationServiceExtension is not called, it's because the property "mutable-content" is not taking into account.
Notification Service Extensions do not work in simulated push notifications. The mutable-content key is not honored. (55822721) (xcode 11.4 release notes)
In total, this means that a smooth development use case, namely testing easily rich push notifications on local machine with simulator will not work!
To test remote push simply drag an APNS file onto the target simulator. This method requires the payload to contain the "Simulator Target Bundle" key. Otherwise, you will get this error message:
Invalid push notification: The file does not contain a valid JSON payload or the Simulator Target Bundle key is missing.
So add "Simulator Target Bundle" to your payload file:
{
"aps" : {
"alert" : {
"title" : “Namaste”,
"body" : “This is iOS development notification test“
},
},
"Simulator Target Bundle": "com.sarunw.example-xcode-11-4"
}
The following simctl command in terminal will send notifications, and since the bundle identifier is included in the command, it does not need "Simulator Target Bundle" to be in the file:
xcrun simctl push <device> <bundle-identifier> <path-to-apns-file>
(<device> can be "booted" if you only have one device running in Simulator. Otherwise use xcrun simctl list to see a list of them, and copy the UUID of the one you want to send to.)
Simulator supports simulating remote push notifications, including background content fetch notifications...
Apple didn't added push notifications to simulator, they added support for simulating push notifications. So this means that you cannot receive any push notifications, you can just simulate them.
You can read more about this in Xcode Beta Release Notes under the Simulator section.

Can't connect to Push Extension Service

i added Push Extension Service (target) to my project iOS 10 Rich Notifications Integration
It can't connect to process (and it doesn't work - can't change payload). Xcode only once connected to process by "Debug - Attach to process by PID or Name".
Now, it waits for "Waiting for attach" status.
Xcode 9.4.1
Running device IPhone 7 Plus 11.4
Okay, i understood - Push Extension Service is activated when you got Notification with "mutable-content":1

Push Notification is not working on iOS 10

After the installing the new update of iOS 10, push notifications are not working, while the same implementation of code is working for iOS 9. Is there any new thing for iOS 10 for push notification. As, I am not able figure it out. Also, is it necessary to turn on push notification under capabilities.
Need some changes for iOS 10 with xCode 8 GM You need to implement UserNotification.framework and their delegate methods to get work of push notifications and in capabilities needs to enable Push Notifications.
You have to import new UserNotification.framework. Please follow this link : Push notification issue with iOS 10
Enabling the push notifications capabilities were not required as part of Xcode 7. This is now required in Xcode 8. By enabling push notifications capabilities in Xcode 8, it'll add the following changes:
project.pbxproj
com.apple.Push = {
enabled = 1;
};
*.entitlements (for development)
<key>aps-environment</key>
<string>*development*</string>
*.entitlements (for enterprise and production)
<key>aps-environment</key>
<string>*production*</string>
On iOS 10 is necessary add the Push Notifications entitlement, so if you "Fix Issue" the problem will be resolved automatically.
Problem

Debug Notification Extensions

I'm building a set of Notification Extensions (Service/Content).
I'm unable to connect to Xcode debugger or even log out to the device log or console.
Is there any way to see any kind of output?
Change the target to run the extension
then select run and choose your app from the 'Choose an app to run:' window.
I have tried as per brendan's Answer but is not working for me at all!
I am getting below error in console
Program ended with exit code: 0
Then after searching on google i have checked this answer. however this also not worked for me for while!
Then i have tried same steps again as given in answer, After stopping my current running app. then follow same steps.For clarity i am writing this steps as below:
After running the app that contains the extension,
1) Set your breakpoint in the extension
2) Select Debug / Attach to Process by PID or name
3) Enter the name of the extension target
4) Trigger the push notification
Before step 2 make sure to stop your current running app.
This worked for me to stop at breakpoints in the extension and see the extension log:
Choose the notification extension scheme, not the main app scheme
Run the app and select the main app from the list Choose an app to run
Stop the app in Xcode and terminate it manually on the device; not terminating it manually results in Message from debugger: Terminated due to signal 9 after step 6.
[Update: Terminating the app manually on the device doesn't seem to be necessary, try either way if it doesn't work.]
Select Menu Debug > Attach to Process by PID or Name
Enter the correct extension name, not the main app name
Send the push notification
Notification service extension (NSE) is not actually a part of your app but an extension that said it has a different process id (PID) from your app. You can have XCode listen to every process on your phone by going to the “Debug” tab, scroll down to “Attach to Process” and look to see if your NSE is listed under “Likely Targets”. If it's not there than try to sand another push notification to your device and attach to it when it appears.
Now in debug navigator you can see the NES process and you can successfully debug it.
In my case all methods above had some mistakes. Main point, that you need to send push one time, then connect through debugger, then send push to debug. So, full list:
Launch app (not extension).
Stop app from XCode.
Send one push.
Connect via "Attach to Process by PID or Name..." to your extension process.
Send another push.
If you have tried all the above solutions and still scratching your head and wondering why break point point is not being called. Then try checking the deployment target of your extension it should be less or equal to your device OS.
For me, the deployment target was higher than the device OS.
In my case (Xcode 11.1) debug starts after this steps:
run notification extension target with main app
switch app to background
lock the phone !
send push to device
I followed solutions mentioned here but nothing helped. I found out that problem is when payload of notification does not contain flag to enable content to be mutated. Notification without this flag are not handled by NotificationExtension at all. After I added "mutable-content": 1 to the payload and followed answers here I was able to alter content of push notification and to debug code in NotificationExtension.
{
"aps": {
"mutable-content": 1,
"alert": {
"title": "Push Title",
"body": "Push payload body"
}
},
"data": "what ever you need to be in userInfo"
}
Not sure if this will be helpful, but we have multiple builds of the same app (alpha, beta, etc). Kept getting a "don't have permissions to attach" error when trying to debug. Opening up the processes list, I noticed that there were 2 processes named notification-extension so xcode must have been defaulting to the one of the other build. By manually selecting the right one, or deleting the other builds from my phone things started working again.
The only way that worked for me was to see logs. I use xcode 10.1. The logs were available from Window -> Devices and Simulators -> Choose your device -> click on 'Open Console'.
This way i could see logs from extensions as well.

Resources