INCLUDE_DATA

iPhone OS 4 and Backgound Tasks or “Why We Don’t Have a Calendar API”

This has been on the burner for a while. With all of the iPhone OS 4 / iPad / iSlate hoopla, I figured I better get it out the door before it all becomes a moot point.

One of the most perplexing omissions in the current SDK has been the CalendarStore API. It seemingly goes hand-in-hand with the AddressBook APIs and is every bit as important for contact management on a mobile device.

But alas, here we are on OS 3.1.X without any support for accessing a user’s calendar. Not even the “second-class citizen” readonly kind.

Although I’m sure the iPhone team at Apple has a pretty big todo list, I can’t help but think there is something more to this mystery…

I submit to you, the reader, that the forthcoming Calendar API is intimately linked to a background processes API. Huh?

I know, but let me explain.

When iPhone OS 3 appeared on the scene, Apple bestowed upon us a gift known as Push Notifications. But lets face it, they suck. For one, they only serve a few specific types of applications. And, perhaps even more detrimental, Push Notifications are hard. Hard to implement. Hard to host. Hard to scale.

Now some will disagree regarding degree of difficulty in setting up a Push Notification server, but none can argue that requiring developers to deploy a server just to fake background tasks is ludicrous.

But to my point: If only we had something like Push Notifications, but more flexible with no server requirement. Also, why not let us execute arbitrary snippets of code when our app isn’t running.

Now were getting somewhere. So, lets put it all together.

I have an app, say an alarm clock app (I know easy example). I want to schedule an alarm, so I call the calendar API and schedule an event.

CalAppEvent *newEvent = [CalAppEvent event];
[newEvent setStartDate:someDate];
[newEvent setRecurranceRule:hourly];
CalCalendar* appCalendar = [[CalCalendarStore defaultCalendarStore] sharedAppCalendar];
[newEvent setCalendar:appCalendar];
[[CalCalendarStore defaultCalendarStore] saveEvent:newEvent span:CalSpanFuture error:nil];

But wait, instead of a simple alarm, maybe I want to play a sound file from my app bundle and deliver a context specific message to the user. Maybe I even want to open a network connection.

If only we had an easy way to capture lexical scope and pass off some code to be executed by another process. How about:

[newEvent setAlarmBlock:myBlock];

Now when my event fires, I can run any arbitrary piece of code!

Now you see the possibilities. Is this true background process support? Not quite. But it is close, very close.

It provides nearly all the flexibility we need, while preserving battery life. Not to mention it avoids deploying and maintaining a server. We’ve effectively leveraged existing technologies (albeit 10.6) and since the calendar process is always running, why not exploit it for all of our multitasking needs?

Additionally, this implementation provides users with a familiar, easy to understand UI for managing background apps: the Calendar app. Simply open the special “Background Tasks” calendar to view all upcoming events scheduled tasks all of your apps.

Of course this is all speculation as I can assure you I have no inside information. I am sure that Apple has a much more elegant solution, but I can’t help but think I am on to something…

Thank you for indulging me in my little though experiment.

5 Comments

  1. Jimbob
    Posted January 20, 2010 at 6:31 am | Permalink

    Two things: Blocks can’t be passed to another address space and don’t survive termination of the process. If the process is kept alive, NSTimer can be used for this, anyway. No reason to mess with exposed calendar entries.

  2. Posted January 20, 2010 at 10:53 am | Permalink

    I agree this would be cool. But I’m sure if Apple will enable such functionality it will be a bit more limited. I think they’ll never allow you to send some code to be executed by another process. If your code crashes (because it is just wrong/malformed or because of a fringe case that didn’t show up in debug/review) it’ll crash an Apple process. Apple doesn’t like that, even though that process will be re-spawned.

    But they might very well at some point in the future (soon?!) provide a limited API where you can show a message at a certain time/date.

  3. Corey
    Posted January 20, 2010 at 11:34 am | Permalink

    @Jimbob My guess is probably off here, at least technology wise. I don’t think that Apple would allow multiple apps to run as background processes. That would be a huge battery drain. Thats it woud be nice to have the Calendar App (or some other process) handle all “local push notifications”. Which is similar to how the Push Notifications work now, minus the ability to execute code.

    @mare I actually doubt they would allow executing of arbitrary code as well. But if they wanted a simple solution that gives developers more flexibility without sacrificing (too much) battery life, they do have the pieces in place. There is some chatter about “Calendar Syncing”, I have to assume that the Calendar API is coming in the next major OS release.

  4. Posted January 21, 2010 at 1:26 am | Permalink

    Overloading the user-facing calendar as a system-level scheduler seems unlikely given that launchd does exactly what you’re trying to do. Something along the lines of SMJobBless() in the ServiceManagement framework is more likely to be exposed.

  5. Jimbob
    Posted January 21, 2010 at 11:16 am | Permalink

    Apps running in the background don’t cause battery problems if they’re in suspended animation, just waiting to be woken by a timer. They’ll cause memory problems, though, since the iPhone doesn’t have paging (yet).

    Local push notifications would be very good for a bunch of apps that implement some sort of calendar function. I can imagine both local and network push notifications to be used to wake up apps and let them execute code, but that would likely be abused with all kinds of polling anti-patterns, negating any improvements to battery life.

    The solution depends on what you want to do. If you want faster app switching, the best solution is to implement paging and suspend running apps to disk. If you want background activity (such as location tracking or music scrobbling) apps should be allowed to spawn small background daemons with severely limited memory and no GUI.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*