Using Bonjour for iPhone/desktop application sync

Many Cocoa developers might want to port their application(s) to the iPhone. I’m one of these developers and the first problem I ran into was how to sync my desktop application’s data with it’s iPhone pendant. Some applications like OmniFocus use MobileMe or any WebDav server for synchronisation. Unfortunatly this is not an option for me because I don’t want my users to have a MobileMe account or a Server just to sync with my app.

My solution uses Bonjour to synchronize my app’s data to the iPhone via the network. You can download this demo project which contains a proof of concept version of my solution. The demo project consists of two XCode Projects. One desktop app and it’s iPhone pendant.

The idea is pretty simple: The desktop application needs to share it’s data with the iPhone app via the network. Therefore the iPhone app creates a sync service and publishes it using the Bonjour technology. This way, the desktop application “sees” all iPhones (which are running the sync service) in the local network and offers the user a list from which he can choose the iPhone to sync with.
The application’s data is then transfered onto the iPhone where it is saved as a file. The iPhone app can now work with this data.

As I’m short of time at the moment I could only implement this basic solution yet but I’m sure I will extend it as soon as I’ll find the time.
In a real world scenario the synchronization process might be a bit more complex. In most cases you may want to import your iPone app’s data into your desktop app and vice versa. For this I’d suggest to put the whole sync logic into your desktop app and perform something like this:

  1. Fetch the data from the iPhone
  2. Check it against your desktop app’s data
  3. Resolve conflicts if they exist
  4. Import the data into your desktop app
  5. Put the whole data back to the iPhone

Most Important: Security
Whenever you deal with network services you have to keep security in mind. When you start a network service on your iPhone it might be a potential security risk, since it opens a “door” to your applications data and everyone in the local network may be able to download this data.

So you may want to create some kind of pairing or authentication protocol as well as encryption for your sync service. This means that when the app syncs for the very first time the user must enter some “secret” which identifies the the iPhone whic the user wants to sync with. Of course this mechanism becomes useless when you use an unencrypted protocol so you should think about encryption too.
Besides, you shoud ensure that the sync service is only stated when it is really needed. E.g. stop the service when the user swithes to some view other than the sync view, etc.

Conclusion
Since the iPhone supports Bonjour, it could be used to sync data with any desktop application.
A full featured example project resides on your HD in /Developer/Examples/Foundation/PictureSharing and /Developer/Examples/Foundation/PictureSharingBrowser. This is where I took some code from :) .

Since I’ve never held a real iPhone in my hands I only tried the example Project with the simulator. It would be nice to see if it works on real hardware. So, if you have tried it, please drop me a line.

Tags: ,

13 Responses to “Using Bonjour for iPhone/desktop application sync”

  1. Nice blog, i have added it to my favourites, greetings

  2. mma says:

    I find this blog very interesting, i will be here everyday till now. Greetings

  3. Jon says:

    Thanks, I knew we had messed something up, and have this working fine on the actual device and MacBook.

    Note of caution: Need to change to use this instead. (didn’t work without changing it)
    NSSearchPathForDirectoriesInDomains(NSDocumentDirectory…

    Other than that, it helped figure out an error I made in trying to use the samples.

    Next test is Windows PC…

  4. tobe says:

    hi Michael,
    did you already figured out how to use the sync services framework to synchronize data between Mac and iPhone?

  5. michael says:

    Hi Tobe,

    it’s been a while since I’ve been looking into sync services. At that time it didn’t support that and I don’t know if this has changed.
    If you find out, please let me know :)

  6. tobe says:

    unfortunately the sync services framework still issn’t available in the iPhone SDK.
    By the way, is there a limit of receiving data at 4119 or 4120 bytes, because your OSX app can send more data, but the iPhone app doesn’t receive more?

  7. David says:

    This seems to falter on iPhone 4.0. I can get the two to recognise each other however for some reason nothing actually seems to sync – the only error I get is !”Class ‘syncservicecontroller’ does not implement the ‘NSNetServiceDelegate’ protocol.

    Anyone gt any good ideas?

  8. David says:

    Actually I just want to edit to this – it works as expected on the simulator but not at all on the actual device….anyone got any great ideas here?

  9. I’m also getting a warning about the “NSNetServiceDelegate” not being implemented. Like mentioned above, only shows up when building for iPhone 4.0 (iPhone 3.2 base sdk doesn’t give the warning). What is the workaround for this on iPhone 4.0?

  10. amok says:

    Awesome and wonderuseful post!

    Any idea how do I build the client companion for Windows?

  11. Marc says:

    For all those that who have problems: The data is transfers, but there’s a problem with the appData.txt file, where the received data is stored. You can check if that file exists, if no, you can can directly create a new one and write the data to that file.

  12. jmac says:

    Great Code! It helped me tremendously. The project will work in the simulator but not on the device. To make it work on the device read on…….

    The compiler warnings mentioned above can be corrected by adding

    to the SyncServiceController.h in “Sync Demo” and to MainWindowController.h in “Sync Demo App”

    @interface SyncServiceController : UIViewController {

    @interface MainWindowController : NSWindowController {

    Currently, “Sync Demo (the iPhone application)” tries to create a new directory(folder) to store the file “appData.txt” in the iPhone sandbox. As far as I know, this is possible when using the simulator but the device won’t allow a new directory to created. You’ll have to use a pre-existing directory, for example the “Documents” folder. To do this

    change the if statement in “Sync Demo”, SyncServiceController.m, – (void)connectionReceived:(NSNotification *)aNotification to:

    if([paths count] > 0) {
    NSError *error = [[NSError alloc] init];

    NSString *append = [[paths objectAtIndex:0]
    stringByDeletingLastPathComponent];
    NSString *path = [append stringByAppendingPathComponent:@"Documents/appData.txt"];

    [fm createDirectoryAtPath:[paths objectAtIndex:0] withIntermediateDirectories:YES
    attributes:nil error:&error];
    [fm createFileAtPath:path contents:receivedData attributes:nil];

    }

    and change the if statement in “Sync Demo”, AppDataViewController, -(IBAction) refreshAction:(id)sender to:

    if([paths count] > 0) {

    NSString *append = [[paths objectAtIndex:0] stringByDeletingLastPathComponent];
    NSString *path = [append stringByAppendingPathComponent:@"Documents/appData.txt"];

    if([fm fileExistsAtPath:path]) {
    [appDataField setText:[NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]];
    }

    else
    NSLog(@”File %@ does not exist”, path);
    }

    these changes will make the application store and look for the “appData.txt” file in the devices “Documents” folder.

  13. jmac says:

    nope! won’t work

Leave a Reply