Tag Archives: NSUbiquitousKeyValueStore

How to test the size of an NSDictionary (in bytes)

The NSDictionary class doesn’t have a length property that can tell us how much memory is being used for storing the whole lot. Usually we don’t really care how big our variables grow – but if you’re storing that dictionary somewhere with potentially limited space (such as iCloud Key/Value storage), it may well be of interest.

You can however turn the dictionary into data and test its size like this:

NSMutableDictionary *dictionary = [[NSMutableDictionary alloc]init];
for (int i = 0; i <= 1000; i++) {
        
    NSString *key = [[NSString alloc]initWithFormat:@"Key%i", i];
    [dictionary setObject:@47 forKey:key];
}
NSData * data = [NSPropertyListSerialization dataFromPropertyList:dictionary format:NSPropertyListBinaryFormat_v1_0 errorDescription:NULL];

NSLog(@"Size in bytes: %lu - Entries: %lu", (unsigned long)[data length], (unsigned long)dictionary.count);

Here we setup a loop that generates a dictionary and adds 1001 entries with an NSNumber literal of 47. This will give us the following information:

Size in bytes: 12954 – Entries: 1001

Note that the above only works if your dictionary has “serialisable” data such as NSNumber, NSDate, NSArray, NSDictionary, NSString or NSData (anything that can be written to a .plist file basically) – but it will not work with custom objects.





How to detect changes in iCloud Key/Value Data

Now that we can read from and write to iCloud, how will we know when another device may have written new data?

We’ll do this by adding an observer and listening to a special message iCloud transmits every time new data is available. The message has the catchy title NSUbiquitousKeyValueStoreDidChangeExternallyNotification.

Here’s how we can setup such an observer. This calls a method (newCloudData) in which you can react to the changes:

// setup an observer
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(newCloudData) name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification object:nil];




How to use iCloud to store Key/Value Data

iCloud-IconUsing iCloud as Key/Value storage is almost identical to NSUserDefaults, except it populates to iCloud in the background and can be read from any device on the same account. What I find much harder than the code is how to make this work in Xcode.

Here’s what we need:

  • an App ID that has iCloud enabled
  • a Provisioning Profile for this App ID
  • an entitlements file, created by Xcode
  • code to save data
  • code to retrieve data

The Code

Let’s start with the easy bit. To store and retrieve key/value data in iCloud we use the

This content is for members only.

NSUbiquitousKeyValueStore class, just like we’d use the NSUserDefaults class for local storage. Usage is identical:

NSUbiquitousKeyValueStore *cloudStore = [NSUbiquitousKeyValueStore defaultStore];

Once setup, we can store values like this:

[cloudStore setString:@"I'm live in iCloud! Woot!" forKey:@"testString"];
// optional
[cloudStore synchronize];

and retrieve data like that:

NSString *result = [cloudStore stringForKey:@"testString"];

Continue reading