I currently sell a Mac-only productivity tool that uses visual and audio notifications to remind the user of certain events taking place.
I've started planning the iPhone and iPad versions of that Mac program and would like to be able to provide notification services from the Mac to the iPhone, e.g. instead of the Mac playing an audio cue, the iPhone could vibrate, etc.
I have so far done very little iPhone development and I'm not really sure how the various push notification services work. Is this easy enough to do? or is a "challenge".
A few more potentially relevant pieces of information:
there will be a Dropbox-based sync between the iPhone and the Mac versions, so there is also the possibility of "sharing" a file that would prompt some action
it might be acceptable as a first step to not have "background" notifications and require that the iPhone client is running
What authentication issues should I expect to deal with?
You'll need to implement APNs (Apple Push Notification Service) in both your app and your server.
To clarify a few things:
You'll need a server doing those transferring messages job between the user's Mac/PC and their iDevices.
Your server will decide when to push what kind of notification to which user's device.
After that, your server sends a message to Apple's APNs server, which will push that message on your behalf.
It's absolutely OK that your app can be in the background or even closed when the APNs message arrives at the user's device. The user will be guided by the OS to open your app.
If the user has explicitly disabled your app's APNs function in her/his device, or, if the user cancels the APNs alert when it arrives, your app won't be launched if it originally stays in the background or if it hasn't been open yet.
The user will be asked to enable (as you put it, authenticate) your app's APNs function by the OS in her or his device when your app is launched for the first time.
It's not a challenging task for an experienced iOS developer or an experienced PHP developer, since Apple's documents and APIs are pretty straightforward. However, configuration on the server side can be a little tricky.
I believe Stack Overflow already has tons of information on how to enable APNs in iOS apps. All you need to do is be specific in your question and do the search work beforehand.
Hope that helps.
Related
Here is the use case:
the user launches the app and grants permission, the app connects to the server
at some point in the future, the server sends a request to the app
the app
regardless of whether it is running or not in the foreground or background, wakes up to run this code
Here are some options I have explored which I am unsure about:
server sent events
websockets
push notifications
Is there a reliable and safe way to do this on android, whether it's Kotlin or Flutter? Can you provide examples or documentation?
Thanks!
Turns out that the best way to do it is with push notifications!
Websockets and server sent events are better suited for other use cases. Persistent connections to a server are resource consuming, and both Android and iOS have mechanisms in place to terminate apps running in the background to save memory etc. So we would probably lose the connection and not be able to receive anything from the server if we minimized the app or locked our phone screen.
Push notifications are basically built for this exact use case because, even though they work differently on Android and iOS, they are built to receive messages from a server regardless of whether the app is in the foreground, background, or not even currently running.
I used Firebase Cloud Messaging to build my app since it's primarily an Android app. It worked like a charm.
I know this question may be a little bit common and over asked but I cannot find any precise information... so :
Is it possible to have some kind of thread running when the app is in background so I can perform basic sync with my webservice ?
App is in background : I mean the user clicked the Home button, or switched to another app
basic sync : photo upload and download with AFNetworking. I know it has method to continue an HTTPRequest while app is in background, but this is not my point.
My goal would be to make some kind of sync manager, reading a list of photos to update created while the user was on the app, and perform those changes.
I know that the manager could be killed by the OS, but since my server uses atomic transfers it is not a problem. I just need a way to relaunch it... Push ?
I think apps like Google Latitude or Mail and those kind of apps uses what I am looking for but I cannot find any relevant details on it. And using iOS5 is not a problem but waiting for iOS6 would not be a solution.
Thank you for your replies !
PS : well I almost forgot. the app is designed for an enterprise program, so maybe rules are different ? I don't think there is any check for in-house deployment so it might lead to new possibilities...
Apple's Mail client has a background daemon which keeps it running but you can't have that with your own applications. Once an app enters a background state, it must halt it's operations. You can request for a little more time when backgrounded to finish off any transfers or writes to disk (see the Executing a Finite-Length Task in the Background section on Apple's Multitasking Guide)
Google Latitude has events generated based on location. This is a special type of backgrounding introduced by Apple for certain types of applications (see Implementing Long-Running Background Tasks section on Apple's Multitasking Guide) but this can't be used for HTTP syncing. It can only be used for audio, location, voip, newstand content, bluetooth and external hardware attachments.
Push doesn't seem like a solution because it only generates an alert. It doesn't trigger any action until the user triggers the opening of the notification.
You'll want to read Tech Note 2277 Networking and Multitasking.
Basically you have a couple of options:
If you can convince Apple that your app is a VoIP app then you can register a VoIP socket and the OS will resume your background app whenever there is activity on that socket.
Your main option though is to register a background task for any outstanding activity that you have to do when your app is put in the background. You typically get 10 minutes to finish up that work.
Mail is a special app with privileges you don't get.
Apps like Latitude typically register themselves for location updates, specifically to be woken up when there are major geo-position changes. Apps that record GPS tracks do similar things.
Found it !
Using Suhail Patel 's link on Apple's Multitasking Guide I added the voip tag to UIBackgroundModes in Info.plist and use setKeepAliveTimeout:handler: method of UIApplication to relaunch it if needed once the app is going to sleep.
I hope this will help a lot of you !
Of course this app won't be allowed to be on the App Store but for in house development this is in my opinion the best way to do so.
Thanks everyone for showing me the right direction !
I am new to iPhone apps developing. Just need my app to do some cyclic job (like a cron). Doing this that way prevent from overconsuming battery.
As I realized I could use /System/Library/LaunchDaemons, but I am not sure if I could use it without jailbreaking iPhone?
As you cannot write outside your designated application area on a non-jailbroken phone, you will not be able to access that path. Neither does Apple seem to encourage or support this kind of service as even keeping an active app in the background is impossible except for a few corner cases (location-aware, voip, ...) [on non-jailbroken devices on course].
You might consider (depending on the case) using Push notifications, specifically remote push notifications. These are issued from your server to apple servers which in turn notify the target phone whenever it is online. The user then has the option to dive into your app again which can display/handle the data. This is a method to resolve many cases where one might resort to polling, e.g. instant message scenarios. Of course this requires that it fits your application profile and that you have a server under your control that can handle the required task and that the app merely displays some information.
How does Apple do polling of a phone's location remotely? Is there any API that allows an app developer to do the same with the SDK?
My guess is that they are private, undocumented and probably un-callable api's.
I couldn't imagine the huge security implications of having an external party/app be about to poll a phone location without the users consent.
An iOS device already maintains a connection to one of Apple's push servers if push is enabled, and the server has to know the device on the end of the connection (to determine the push notifications to deliver to it). The easiest way to build on this is to have the server say "tell me where you are!" as a push notification.
The device also hits Apple's servers for other reasons (App Store updates, captive login page detection), but it's less likely that the server can identify the device in these cases.
That said, you can do this with the user's consent:
Make your app a background "voip" app (<key>UIBackgroundModes</key><array><string>voip</string></array> I think)
At app launch, check that you can retrieve the current location (I'm not sure what happens if you do this while your app is backgrounded).
Maintain a "voip" connection to your server.
When the server asks the device for its location, ask Core Location for the location again and send it to the server. (I think you also need either "location" in UIBackgroundModes or you need to keep the connection active, possibly in both directions; the former may be easier.)
You won't be able to stop the "location services" icon from appearing in the status bar. The usual multitasking caveats also apply (your app can be killed if the phone runs out of memory; "voip" causes your app to be relaunched sometime later though).
I'm pretty sure if you do the "voip trick" your app will be refused from the store. It is only allowed if your app is actually a VOIP app, not just using it as a technique to circumvent background processing restrictions.
I constructed provider code with using C# and it was able to send notification messages to iphone devices successfully. But since yesterday, it hasn't worked. Also it seems to connect APNS successfully and send notification message. Unfortunately, no notification message is received by iphone device. I controlled internet connection and device token of iphone device. What else can I do? Thanks in advance...
I dont have enough rep to comment on the question so typing out answer - Please add more details and I will edit my answer.
Is this in a developer / testing environment and are you using an ad hoc profile to install the application on the iphone devices?
Did you check if the device token has changed and that you are using the new/ correct token in the C# code?
Do provide more details of your problem.
Crazywood, I don't have a solid answer for you but I can tell you I'm in the same boat as you.
There are times when all my notifications go through and times when none of them seem to.
One guess is that not all notifications are sent. According to the docs, in production remote notifications are not guaranteed to be received by the client. My guess is that this is also the case for the sandbox.
-------- EDIT ------
I went through the trouble shooting list (http://developer.apple.com/library/ios/#technotes/tn2010/tn2265.html) and came across this:
The device may have lost its persistent connection to the push service and can't reconnect. Try quitting the app and relaunching it to see if registration completes the next time. (On iOS 4 and later on devices that support multitasking, you will need to force quit the app from the recents list.) If the registration does not complete, iOS has been unable to re-establish the persistent connection. You can troubleshoot this as described in the previous two sections.
I restarted the app and it made no difference. Then I rebooted my phone. That seemed to do the trick.