iOS Development – Avoiding Duplicate Object IDs for Data Shared Across Devices Using iCloud

iosobjective c

I have a data intensive iOS app that is not using CoreData nor does it support iCloud synching (yet). All of my objects are created with unique keys. I use a simple long long initialized with the current time. Then as I need a new key I increment the value by 1. This has all worked well for a few years with the app running isolated on a single device.

Now I want to add support for automatic data sync across devices using iCloud. As my app is written, there is the possibility that two objects created on two different devices could end up with the same key. I need to avoid this possibility.

I'm looking for ideas for solving this issue. I have a few requirements that the solution must meet:

1) The key needs to remain a single integral data type. Converting all existing keys to a compound key or to a string or other type would affect the entire code base and likely result in more bugs than it's worth.

2) The solution can't depend on an Internet connection. A user must be able to run the app and add data even with no Internet connection. The data should still resolve properly later when the data syncs through iCloud once a connection is available. I'll accept one exception to this rule. If no other option is available, I may be open to requiring an Internet connection the first time the app's data is initialized.

One idea I have been toying around with in my head is logically splitting the integer key into two parts. The high 4 or 5 bits could be used as some sort of device id while the rest represents the actual key. The fuzzy part is figuring out how to come up with non-conflicting device ids that fit in a few bits. This should be viable since I don't need to deal will millions of devices. I just need to deal with the few devices that would be shared by a given iCloud account.

I'm open to suggestions. Thanks.

Update:

After giving this some more thought, I've decided to take the short term hit and do this the right way. Using a GUID is definitely the best long term option for this. Using this approach eliminates the need to do any of the various options to deal with handing out key ranges or translating keys once an Internet connection is made.

My original requirement prevented the GUID option because neither SQLite nor iOS support a simple, 128-bit integer type. Since I have a large existing code base that is written such that my keys are simple integer types, it will require a major refactoring of both the code and the database schema.

In the end, I've decided that the short term pain of doing this refactoring out weighs the long term issues of dealing with a klunky solution. Taking the hit now gives me a much simpler and less error prone solution that will last the long term.

Best Answer

As Lars Viklund points out in his comment, you might look into UUIDs -- they're 128-bit numbers used for unique IDs and have good stats for uniqueness. If you can't find a function to generate one (though I'm sure Apple has one), Version 4 is pretty easy to implement.

Related Topic