I have an iOS app that plays music with the MusicKit API. I want to write a companion app for macOS that communicates with the iOS app.
For example, my iPhone is playing music. When a new track starts playing, a notification appears in the macOS app. I can click a button on macOS to skip to the next track on my phone.
What's the best way to communicate between devices like this?
I think there are two important use cases:
For static data like account details and preferences.
For real-time messages.
I could do everything via a remote server but I wonder if there's a better way.
The user needs to have your app installed on iOS and macOS and needs to separately grant permission to receive push notifications.
Keep in mind that Apple does not guarantee the real-time delivery or delivery at all of remote push notifications. Remote push notifications may also be discarded by the APNS if many are sent within a short timeframe. It is not recommended to use the APNS for user-initiated actions such as music track controlling, as the user expects an (immediate) result. A web socket or other permanent connection between your server and its clients should be used instead.
Playing music on one device, stopping on another:
Request permission to send remote push notifications to get the unique APNS token for each device.
Store the device tokens on your server.
Make the iOS client notify the server that the user started playing music.
Make the server send a remote push notification to the macOS client via the APNS.
On the macOS client handle the user interaction with the push notification and report the user action back to the server.
Make the server notify the iOS of the user interaction via a web socket connection, rather than a remote push notification to ensure that the client handles the user action.
Make the iOS client skip the track.
Synching user preferences:
Store preferences on server for every change.
Request preferences from server on every app launch or dynamically when the preferences change by triggering the request through a remote push notification by the server or via a web socket connection, depending on how real-time the synchronization should be.
Related
I'm trying to detect uninstalls of our iOS app.
I read this document which gives some useful information. However, how can I understand from the error codes returned whether the user uninstalled versus disabled push notifications/has no connectivity?
I think you'll want to use the Feedback Service. When a user deletes an app, the service provider should ideally stop sending notifications to that device. But Apple does not notify the service that "this device is not using your app, dont send notifications". Technically, a device which has uninstalled your app will not make it onto this list until the next time a push notification goes to the device. So you need to poll for this info using the Feedback Service.
Periodically, you will need to hit Apple Notification servers asking it to give you IDs that have deleted your app. Once you get them you mark them in your DB as deleted thereby not sending any more notifications. This Feedback Service will tell devices that have been unregistered (app uninstalled). The part I'm not sure about is whether a user who has turned off push notifications in settings will register the same. I believe they will not show up in the feed from the Feedback Service. I am certain, however, that users who are offline and the push notification is not delivered will not be included in the list.
It would be a simple test in your dev region to try the app, disable push notifications for the app, and then see if the device shows up in the feed.
Take a look at Apple's documentation
From Apple Documentation -
Apple Push Notification Service includes a feedback service that APNs
continually updates with a per-application list of devices for which
there were failed-delivery attempts. The devices are identified by
device tokens encoded in binary format. Providers should periodically
query the feedback service to get the list of device tokens for their
applications, each of which is identified by its topic. Then, after
verifying that the application hasn’t recently been re-registered on
the identified devices, a provider should stop sending notifications
to these devices.
Access to the feedback service takes place through a binary interface
similar to that used for sending push notifications. You access the
production feedback service via feedback.push.apple.com, port 2196;
you access the sandbox feedback service via
feedback.sandbox.push.apple.com, port 2196. As with the binary
interface for push notifications, you must use TLS (or SSL) to
establish a secured communications channel. The SSL certificate
required for these connections is the same one that is provisioned for
sending notifications. To establish a trusted provider identity, you
should present this certificate to APNs at connection time using
peer-to-peer authentication.
Make sure you also read up on - Issues with Feedback Service
I am doing MDM implementation in iOS and I have one server for its implementation.I have gone through the documents and understood the process that we have to undergo.But Simply I don’t understand how it will happen.I have one server and one device.I have my PEM file enrolled in the server.
As the process of MDM says server sends push notification through the device and the information that is present in the message in only the identifying token.Then device is connected to the server and sends an idle message confirming that device is ready for the commands.
My question is how device receives the push notification.If app is in back ground state and it gets a notification to connect to the server is there any method to detect it and send the feedback or is it happening automatically or we have to write some code for it. Also how does the plist (that we get in command) make changes in the settings (unlock to lock) .Do we save it somewhere in the device configuration?
I have got a lot of questions about the command format but did not get anything how the command works.May be I am missing basic iOS coding.please just explain me the above format.
how device receives the push notification.If app is in back ground state and it gets a notification to connect to the server
First of all, you will have to implement server side only for iOS MDM. Client side is implemented by Apple and MDM client is baked into iOS.
As part of OS it dosn't have restriction which usual iOS apps has. It has a persistent channel to APNS and as soon as somebody send a push notification to APNS, the device will receive it through this persistent channel and will start doing what it should be doing.
Also how does the plist (that we get in command) make changes in the settings (unlock to lock) >.Do we save it somewhere in the device configuration?
The answer is the same. You don't have to implement anything on the iOS side. It's all done by Apple- MDM client will get the command, parse it, save it to appropriate places and enforce appropriate policies.
I want to send push notification from a iOS device to another iOS device without using backend server. Is it possible for an iOS device to act like a server and send push notification to APNs server?.
Thanks in advance.
Theoretically you can send Apple Push Notifications from a device directly to another device. All you need are the push certificate of the app, the device token of the device you are sending the notification to, and code that establishes a secure TLS connection to the APNS servers.
However, there are several practical problems that make the use of a server almost mandatory :
You need a single place where all the device tokens of all the devices that installed your app will be sent to and persisted in. The best such place would be a server. Without a server, how would device A send its device token to other devices that want to send it push notifications?
Apple require that you keep connections with the APNS server open for as long as possible and use the same connection for sending many notifications. If you open a connection to APNS server on your device, it will probably be short lived (since devices switch networks frequently, and don't stay connected to the internet all the time). Therefore, if you try to send many notifications frequently, and each time use a new connection to APNS, you will probably be banned (since Apple would treat this as DDoS attack).
If you store the push certificate in each device that installs your app (to allow it to send push notifications to other devices directly), aside from the security issue of storing the certificate in many places, you'll have to publish a new version of your app each time the push certificate expires (once a year), and push notifications would stop working for users who don't upgrade to the new version.
Try NWPusher.
It has an iOS framework for sending pushes and has an iOS demo application that sends push notifications from iOS to iOS.
You also need to consider Server costs (other than maintenance and development time if you code your own server).
By sending the push directly from the app device:
- you obtain a much better scalability (since you don't have to centralize everything on your server)
- you don't have to pay for server cost or other service's cost
You can use for iOS:
- https://github.com/noodlewerk/NWPusher Pusher
And for Android:
- Send push notification GCM by java
How can an iOS app be notified that it needs to update its content?
I would like to have an app that listens for update alerts that trigger a download rather than doing a data request to be able to stay in sync with the server.
What is the correct way to have an iOS app that needs to be in sync with a server stay in sync while minimizing network activity?
Im aware of using a cache locally, NSURL Cache or Core data etc. and adhere to the timeout in the http header etc. but I would like to correctly setup a sync mechanism without having an update button that a user needs to press to get updates.
I have thought of implementing a dispatch_source on a socket but wont that keep the network active and drain battery?
Rather than request a token for the version of the data to sync from the server I would rather like the server to notify the device that it needs to update. Is this practical?
How does the OS handle listening to push notifications? Is it on POSIX level?
You really have two options here:
Client Side Polling: call the server and ask every so often. For 99% of apps this is fine as it's not that big a deal for someone to run the old version during the interval between polling.
Real-time Server Push: If for some reason you need to disable the old version as soon as you push a new version, you could do a server side push. You would not want to use APNS for this (user may deny APNS, delivery not guaranteed, etc). You would want to use a cheap push service like PubNub or Pusher for this to guarantee real-time delivery. Or code you own version using the same principles of these services, but really why re-invent the wheel?
There are two common, as far as I am aware, approaches to doing this on iOS;
Regular GetUpdates calls to the server at an interval (Fairly standard across any platform I think)
Apple's Push Notification Server(APNS) if anything changes on the server you can push a notification to the device.
At work we typically implement both options because there are a few issues with APNS;
They are not guaranteed to reach the device, if the device is offline the APNS service will store the Notification for a limited time in the APNS system upon which it is forwarded (if it hasn't expired)
If multiple Notifications are sent while the device is offline only the most recent notification is sent
If the device is offline for a long enough period of time all stored notifications will be discarded
the user has to allow Push Notifications to be sent to their device because it suppliers and identifier that you can use to determine the device
Quick question, I am working on an APNS enabled app and I just want to know if there is a way that when the app is not open (not in background) and the app receives a remote notification;
Can I open the app in the background, unbeknownst to the the user, and do do what needs to be done.
I have looked at the docs but it doesnt explicitly say that this can or cannot be done (from what I read), it says that the user has to open the app manually (either from tapping an alert or the app icon).
I think it is clear what I'm looking to do however i'll put an example aswell.
Example)
The default Mail app alerts the user of new emails with a badge icon, showing the number of new emails, aswell as a sound. The user must then tap the app icon to open the app and download the new emails.
I want to be able to have the badge and sound but open the app in the background (silently) and download the new emails, so that when the user does get around to opening the app the emails will already be there, ready to read.
Thanks for any help.
unfortunately, what you describe is not possible.
the only way you could get something like that is to build a voip app. see the relevant section in this document.
Implementing a VoIP Application
A Voice over Internet Protocol (VoIP) application allows the user to make phone calls using an Internet connection instead of the device’s cellular service. Such an application needs to maintain a persistent network connection to its associated service so that it can receive incoming calls and other relevant data. Rather than keep VoIP applications awake all the time, the system allows them to be suspended and provides facilities for monitoring their sockets for them. When incoming traffic is detected, the system wakes up the VoIP application and returns control of its sockets to it.
anyway, I doubt that your app would get into the App Store, then...