I can send a message from my WatchKit Interface to its parent application using +openParentApplication:reply:, and I can provide data from the parent application in the reply.
Is there an official Apple mechanism for triggering a message in the other direction, ideally an Objective-C API with similar support for arbitrary user data, or do I have to use a library like MMWormhole?
The openParentApplication:reply: does have that reply parameter for sending a message back to the WatchKit side.
But I think you mean triggering a message from the iPhone app directly. You can look into Darwin notifications for this. It's a C API, but the concepts are similar to NSNotificationCenter where you register to listen for certain notifications, and then post notifications from somewhere else.
Related
We are having trouble using the new iOS Critical Alerts feature with OneSignal. The app we have is built using Apache Flex and the push notification payloads are being compiled/generated through Distriqt ANE and sent through the OneSignal iOS SDK. We have been approved by Apple for Critical Alerts but when attempting to send the payload through OneSignal, it does not work.
The Distriqt team has built in support for Critical Alerts, which is great, but once it is sent through OneSignal, the payload isn't delivered successfully and the critical alert is not generated. To be clear, general push notifications work fine.
OneSignal has documentation on Critical Alerts, though it is over simplified. The payload needed to trigger Critical Alerts on iOS is clear but there is no way to construct a payload like this through the OneSignal iOS SDK.
In the link, we have performed #1 (Update OneSignal App Payload Structure for iOS) but #2 is unclear. What does the payload need to look like? The code provided does not make that clear. Additionally, what is the referenced 'notification category extension' and if that code is identified, what are we needing to do at that point?
We have contacted OneSignal and have been unsuccessful in understanding how to successfully construct this payload. The documentation says 'iOS features OneSignal SDK supports' but from their support we received this:
Unfortunately our SDK is not setup to handle critical alerts.
One user reported he achieved this with our additional data parameter like this:
"data": {"CRITICAL_ALERT":"YES","CRITICAL_PAYLOAD":{"CRITICAL_VOLUME":"1.0","CRITICAL_SOUND":"Alert.wav"}}
Though that doesn't work. Although a relatively new feature, I am hoping someone in the community has been successful at this and can help. Thanks!
TL;DR Building an iOS Notification Service Extension is the solution. The OneSignal documentation mentions this but in far less detail.
When Critical Alerts was introduced by Apple, they changed the sound parameter that is passed through with an APNS payload. Previously, the sound was only ever a string. For example:
{
“aps” : {
“sound” : “critical-alert-sound.wav”
}
}
With Critical Alerts, it is a dictionary. Example:
{
“aps” : {
“sound” : {
“critical”: 1,
“name”: “critical-alert-sound.wav”,
“volume”: 1.0
}
}
}
The string version is still valid and is used for non-critical alerts. Based on inference and testing, when passing the sound parameter to OneSignal, it only supports the initial 'string' version. When OneSignal sends the payload to Apple, it passes it as a string thus even trying to pass a sound dictionary to OneSignal won't work because it gets parsed down before it gets to Apple. By the time Apple communicates back with your device, the dictionary is gone, thus preventing the device from ever recognizing it as a Critical Alert.
This is where the Notification Service Extension comes in. From Apple's documentation:
A UNNotificationServiceExtension object provides the entry point for a Notification Service app extension, which lets you customize the content of a remote notification before it is delivered to the user. A Notification Service app extension doesn't present any UI of its own. Instead, it is launched on demand when a notification of the appropriate type is delivered to the user’s device. You use this extension to modify the notification’s content or download content related to the extension.
In short, you can intercept the notification JSON payload coming from Apple and modify it just before the user sees it.
In order for the information to be passed to the device correctly from OneSignal->Apple->Device, you need to:
1) Set the additional_data_is_root_payload value on your OneSignal account to true. This is done through an Update an App API call on OneSignal. I used Postman for this. To be clear, this is needed to be done one time, it is not something needed to be repeated every time you make an notification API call.
2) In your OneSignal API payload, set the mutable_content parameter to true.
As mentioned above, you can use values in the OneSignal data parameter of the payload. The data payload is an open field that can be used for any additional information you want to pass through the OneSignal->Apple->Device flow and does get delivered to the device/app which you can then parse however you would like. In my example, we use:
"data": {"CRITICAL_ALERT":"YES"}
The data payload is arbitrary, it just needs to match the checks you do in the Notification Service Extension.
We then create our Notification Service Extension in XCode. There are some great step-by-step instructions here on creating an extension. This is done through XCode so if you are building a native app, it's simply done through your XCode project for your application. If you are using a framework like Adobe AIR, it is quite a bit more complicated and I will detail that in a different post. Keep in mind that the Notification Service Extension is basically a separate 'app' bundled with the parent app. It is compiled into a file with extension 'appex' and even though it is a separately bundled binary, it is specifically targeted to your parent app.
Once the extension is created, your XCode project will have a file named NotificationService.swift with a class that has the didReceive method within it. We then added this code:
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
// Modify the notification content here...
if ((request.content.userInfo["CRITICAL_ALERT"] as? String) == "YES"){
bestAttemptContent.sound = UNNotificationSound.defaultCriticalSound(withAudioVolume: 1.0)
}
contentHandler(bestAttemptContent)
}
You can see that we check the data payload (request.content.userInfo) to see if the CRITICAL_ALERT key is set with a value of YES. If so, we add a 'critical sound' to the notification which effectively turns it into a critical alert. In this case, we kept it simple with the defaultCriticalSound function but you can also use criticalSoundNamed if you want to define your own sound. You could also pass the sound you want to use for the alert through the data payload and then parse it and add it in the Notification Service extension if you wanted to create specific sounds for specific notifications.
At this point, we tested this through the OneSignal interface once we had deployed the app to our devices. This can be accessed by logging into your OneSignal account and then going to 'Messages' -> 'New Push' and choosing the devices you would like to send the push to:
Hopefully this is helpful to others using OneSignal for Critical Alerts (and hopefully they update their system soon to no longer need a Notification Service Extension).
I am working on a video/audio call app. Now when my phone is locked and another user is calling me then from the lock screen I will get a notification and if I swipe the notification then the call automatically received. I used UILocalNotification for getting notification.
But I don't want like this. I want to see the UI same as when another user call me when my phone is unlocked that is there will be receive/reject option with my UI. I want to receive call like Viber or skype. How can I do that?
You should be looking into the PushKit framework form Apple.
The PushKit framework provides the classes for your iOS apps to
receive VoIP pushes from remote servers. VoIP pushes provide the
functionality that VoIP apps need to perform on-demand processing of
the push before displaying a notification to the user.
Apple Documentation
There are some tutorials might help you.
Tutorial 1
Tutorial 2
Update
To display the system-calling UI for your app's VoIP services you can use CallKit.
CallKit documentation
Sample code from Apple
Here is a tutorial which explains it well.
http://www.techjini.com/blog/enhance-voip-app-user-experience-using-pushkit-callkit/
https://www.raywenderlich.com/150015/callkit-tutorial-ios
I've set up an app to send motion data from one device to another using websockets (Starscream library). Now I need to send push notifications when a critical event happens (when app is minimized), does it have anything to do with websockets or I just need to use something like Pusher?
As you said, I think you should use Pusher or any other external service (Pushwoosh, Onesignal, among others) to send push notifications to the users. You can't do this with websockets.
I recommend you to use OneSignal (it is free and some big companies like Uber or Zillow are using it)
EDIT:
I think you can't send a push notification from one device to the other one. One device (let's say Kid.app) should notify the server of an event, and then the server will send the push notification to the other (Parent.app).
Check this link, it will be useful for you.
Can we integrate VoIP services through the new framework CallKit without using any server services or push notification?
I am really new to this concept, also checked the speaker box app as a sample app but didn't get much idea how it would be working.
Please, share your feedback if anyone has integrated CallKit.
Thanks
The CallKit framework provides programmatic access to VoIP functionality, as well as call blocking and identification. Apps can use CallKit to receive incoming calls and make outgoing calls using the native phone UI.
Reference for call kit.
Can we integrate VoIP services through new framework call kit without using any server services or push notification?
No we can't use it. You will need third parties like Twilio, Plivo, or ICELink and create your own server. Then provide CallKit the data required, it will handle the call and UI stuff. You can read the apple docs for more ideas.
If a CallKit app only intends to make outgoing calls, then it may be possible to not have a server component. But if the app intends to receive incoming calls while the app may not be running (e.g. when it is suspended), those incoming calls must be signaled via Push Notification, and those push notifications are typically sent by a backing server.
Is it possible to create a Notification Listener in iOS? Something like the NotificationListenerService in Android.
Edit: What I want to do is listen to any notifications coming from any app within the device (missed calls, emails, SMS...)
There are two possible answer for this.
NSNotificationCenter is used to post notifications within the app itself. Say for instance you want several classes all to receive information that something has happened (or something) then you would use this. https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/nsnotificationcenter_Class/Reference/Reference.html
If you mean Remote Notifications i.e. push notifications that you receive from Apple then the AppDelegate receives these in a couple of its methods...
https://developer.apple.com/library/ios/documentation/uikit/reference/UIApplicationDelegate_Protocol/Reference/Reference.html#//apple_ref/doc/uid/TP40006786-CH3-SW16
Edit: It's not possible between apps. See comments.