Tutorial: Using iCloud Key-Value Storage

Tutorial: Using iCloud Key-Value Storage

Today, we are pleased to introduce the iCloud plugin, available as of Daily Build 2015.2795. This plugin is currently in “beta” while we finish polishing the documentation and give it further rounds of testing.

In this tutorial, we’ll explore Key-Value Storage or KVS (we will address “Documents in iCloud” and “CloudKit” in other tutorials).

Overview

KVS allows you to store “key-value” pairs in Apple’s iCloud using a very simple set of API calls. With KVS you can store strings, numbers, and tables of data using a simple iCloud.set() call.

Before you dive in, there are some KVS limits to be aware of:

  • You can use 1 megabyte of storage at most.
  • You can have up to 1024 total keys.
  • Keys can be up to 64 bytes long and include unicode characters. Unicode characters take up more space than alpha-numeric characters. You can use up to 63 alpha-numeric characters.

Depending on your requirements, you can use one key with a lot of tabled data, or you can use many keys with separate bits of data. Keep in mind that when you sync one key with a lot of data, you’re changing a lot at once. Also remember that data is generally synced over both WiFi and Cellular, so syncing keys with large amounts of data can be time consuming, even when only one small part of that data changed.

Provisioning your app

Before you can deploy your iCloud-capable app to the store, your provisioning profile must have iCloud enabled. This is done in the Member Center of the Apple Developer portal under Certificates, Identifiers & Profiles. Once there, click IdentifiersApp IDs. Click on the desired app (it can not use a wildcard App ID) and scroll down to the iCloud row. There, check the box to enable iCloud. Next, click the radio button to enable CloudKit, then click on the Edit button.

Screen Shot 2015-12-16 at 7.01.58 PM

On the next screen, check the box for your app’s bundle ID:

Screen Shot 2015-12-16 at 7.00.01 PM

Click Continue and then Done. At this point, you will need to regenerate your provisioning profile (see the Creating Provisioning Profiles section here).

Updating build.settings

To include the iCloud plugin, you must add it to your build.settings file:

In addition, you must edit the block for iphone and/or tvos:

Corona Enterprise

For Enterprise builds, you have to include the Corona_plugin_iCloud.framework which is located in the Enterprise plugins download tab on the Daily Builds page.

In addition, there are some Xcode settings required for enabling iCloud, located on the project’s Capabilities screen. Here, ensure that iCloud is enabled and that Key-value storage is checked.

Screen Shot 2015-12-16 at 7.27.05 PM

Saving values to iCloud

In any scene or Lua file where you need to access iCloud services, you must require the plugin:

Then, when you’re ready to save some data, simply call iCloud.set() with a key and value, for example:

This will set a key named playMusic with the value of "on".

Accepted values

KVS allows you to store the following data types:

  • numbers
  • strings
  • tables

While you cannot store booleans this way, they can be part of table data. Alternatively, you can simply use numbers like 1 or 0 to indicate true or false, or just store the strings "true" or "false", but you will need to convert them back to boolean values before you use them as Lua booleans.

Note that if you choose to store a table, it must contain only key-value pairs. Tables with numeric keys (arrays) can not be stored directly as tables. In other words, the following array will produce an error if you attempt to store it to KVS:

If you have an array to store, one option is to use json.encode() on the table and save it as string data, then use json.decode() on the string to convert it back into a table after you retrieve it from iCloud.

Retrieving data

To get data back from KVS, simply call the iCloud.get() method:

If the value can’t be found, nil will be returned. It’s that simple!

Deleting data

If you no longer need some data, you can recover used storage by deleting the key from iCloud using the iCloud.delete() method:

Synchronizing data

An important purpose of iCloud is to allow users with multiple devices to share data between them. In other words, if you finish a level in a game on your iPad, you should be able to pick up your iPhone and play the next level. If you load certain saved settings (data) from KVS when the app starts, the app should have the latest data — but what if the app is open at the same time on both devices and changes to the data occur?

One option is to enable a listener function via iCloud.setKVSListener() that will execute when values change, effectively keeping your app up-to-date. Consider this block of code:

See the iCloudKVSEvent documentation for the various values returned as part of the event table.

Conclusion

This tutorial is just the first in respect to storing and sharing data in Apple’s iCloud. To learn more, please refer to the iCloud documentation.


Rob Miracle
rob@coronalabs.com

Rob Miracle creates mobile apps for his own enjoyment and the amusement of others. He serves the Corona Community in the forums, on the blog, and at local events.

13 Comments
  • Corona SDK add Mac OS Support; tvOS In Betagamedev.fm | gamedev.fm
    Posted at 06:34h, 19 December

    […] To get started with the iCloud plugin, see the documentation and our first tutorial. […]

  • Sem
    Posted at 07:55h, 26 December

    Is this only for iOS apps?

    • Rob Miracle
      Posted at 09:29h, 26 December

      Currently for iOS and tvOS. At some point we will make it available for OS X builds as well. Engineering is looking into an Android equivalent and then we will look at a wrapper to make a cross platform version.

  • René
    Posted at 01:58h, 28 December

    Very cool. Thank you Rob.
    The limitations: 1 megabyte of storage, 1024 total keys etc. are these limitations per app?

    • Rob Miracle
      Posted at 18:40h, 28 December

      Yes, 1MB/1024 Keys per app. It is possible for multiple apps to share a single storage. In this case, quota is 1MB/1024 keys for the whole suite sharing.

  • Jeremiah
    Posted at 09:04h, 30 December

    What happens when the user has iCloud disabled? Do these methods throw errors or do they just silently fail? e.g. return null / do nothing.

    • Rob Miracle
      Posted at 16:31h, 01 January

      They should return nil if they fail and you’re expecting a returned value. If it’s something where no return is expected, nothing is returned.

      Rob

  • Umut Demirel
    Posted at 05:42h, 31 March

    Is there any way to clear the data from the icloud settings on the actual device? I can’t find my app name on Settings->iCloud->Storage->ManageStorage section. Is iCloud.delete( ) function the only way to clear it?

    • Vlad Shcherban
      Posted at 12:12h, 31 March

      Settings->iCloud->Storage->ManageStorage would display only Documents in iCloud (may be CloudKit). User has no way to reset iCloud KVS storage, and deleting them from within app is the only way in Apple ecosystem.

  • Tim
    Posted at 08:32h, 03 May

    Using iCloud and KVS everything seems fine. Can write, sync, read. But as soon as I re-install, everything is gone. Which can only mean it never wrote to iCloud at all, only a local save file.

    Very simple code.
    Just set up provisioning in Developer Portal.

    Then use the plugin per the tutorial

    Finally use
    iCloud.set( “value”, myValue)
    and
    iCloud.get( “value”)

    Any ideas?

  • Cesar
    Posted at 12:20h, 03 July

    Hi all.
    First of all, thanks for this excellent tutorial and for your hard work.

    I’m starting with iCloud due my app need backup a mysql database and a prefs.json file. I was thinking in zip both files and upload to iCloud Documents. But I’m not way to do it. Also I don’t know if I can use KVS to store less than 1 MB file (zip file format). I think json can be a solution to convert a zip file into a plain text file to set a value using KVS. I don’t know if I need to use documents.

    Really I don’t know how to do it.

    Also, CloudKit appear to allow a database to share data along deferents users, but, how to upload my sqlite database there? I think I must fully transform the sqlite db to a CloudKit version.

    Dear, do you plan to publish Documents and CloudKit tutorial too?

    Any ideas about if I can use KVS to store a zip file?

    Thanks a lot,

    Regards,