View All Posts
read
Want to keep up to date with the latest posts and videos? Subscribe to the newsletter
HELP SUPPORT MY WORK: If you're feeling flush then please stop by Patreon Or you can make a one off donation via ko-fi
#APP DEVELOPMENT #DATA SYNC #ICLOUD #IOS #NSUBIQUITOUSKEYVALUESTORE #PERSISTING SETTINGS #SUDOKU GRAB #USER DATA

The new version of Sudoku Grab is going to be a universal app (iPhone and iPad) so it’s become even more important that user data sync across all the devices an user owns.

The types of data that we need to sync are: settings (colours, fonts etc..) and puzzle data. In this post I’m going to talk about settings and persisting settings in the cloud.

The mechanism that Apple recommends for doing this is the NSUbiquitousKeyValueStore and there is some pretty decent documentation on how to get it up and running in the Storing Preferences in iCloud document.

There’s a couple of thing to be aware of - the Key-Value data store is intended for small amounts of data:

The total space available in your app’s iCloud key-value storage is 1 MB per user. The maximum number of keys you can specify is 1024, and the size limit for each value associated with a key is 1 MB. For example, if you store a single large value of exactly 1 MB for a single key, that fully consumes your quota for a given user of your app. If you store 1 KB of data for each key, you can use 1,000 key-value pairs.

And:

The maximum length for a key string is 64 bytes using UTF8 encoding. The data size of your cumulative key strings does not count against your 1 MB total quota for iCloud key-value storage; rather, your key strings (which at maximum consume 64 KB) count against a user’s total iCloud allotment.

If you think you are going to be storing more than that amount of data then the key-value store is not for you and it’s probably worth asking yourself if you are really storing user defaults or some other kind of data.

Setting up for iCloud key-value store

The first thing to do is to enable your app for cloud synching. There seem to be too places where this needs to be done and I’m not sure if the xcode step also does the dev portal step - so I’d recommend doing both…

When you create your app Id you’ll need to switch on the iCloud App Services option - if you are updating an existing app then enabled the iCloud App Services and then I’d suggest regenerating your provisioning profile.

'Setup App ID for iCloud'

Now create/open your app select your target and modify the Capabilities section enabling iCloud and make sure you tick the “Use key-value store” checkbox. 'Setup project for iCloud'

Getting values from iCloud

You’re now ready to go! To use your iCloud settings you’ll need to get hold of the default NSUbiquitousKeyValueStore (this code is take from the Preferences and Settings Programming Guide).

NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore];
[[NSNotificationCenter defaultCenter] addObserver:self
          selector:@selector(updateKVStoreItems:)
          name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification
          object:store];
[store synchronize];

This code gets hold of the default store and registers us to get updates when something changes in the store (e.g. another device modifies the values). We then synchronize the store with the cloud.

You should run this code as soon as possible when your app launches so that you get any changes immediately - you respond to these changes in the updateKVStoreItems notification:

- (void)updateKVStoreItems:(NSNotification*)notification {
   // Get the list of keys that changed.
   NSDictionary* userInfo = [notification userInfo];
   NSNumber* reasonForChange = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey];
 
   // If a reason could not be determined, do not update anything.
   if (!reasonForChange)
      return;
 
   // Update only for changes from the server.
   NSInteger reason = [reasonForChange integerValue];
   if ((reason == NSUbiquitousKeyValueStoreServerChange) ||
         (reason == NSUbiquitousKeyValueStoreInitialSyncChange)) {
      // If something is changing externally, get the changes
      NSArray* changedKeys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey];
      // do whatever you need to do when settings change
   }
}

There are three possible reasons for receiving a change notification:

  • NSUbiquitousKeyValueStoreServerChange - another device updated the values in iCloud.
  • NSUbiquitousKeyValueStoreInitialSyncChange - slightly more complicated, only happens under these circumstances:
    1. You start the app and call synchronize
    2. Before iOS has chance to pull down the latest values from iCloud you make some changes.
    3. iOS gets the changes from iCloud
  • NSUbiquitousKeyValueStoreQuotaViolationChange - you’re using it wrong and trying to store too much data.
  • NSUbiquitousKeyValueStoreAccountChange - the user has changed to a difference iCloud account. What you should probably do is clear down the user defaults to their default settings and then copy accross any new values from the cloud.

Storing values in iCloud

You can treat the NSUbiquitousKeyValueStore just as you would NSUserDefaults:

[[NSUbiquitousKeyValueStore defaultStore] setString:@"Mr Blobby" forKey:@"name"];
[[NSUbiquitousKeyValueStore defaultStore] synchronize];

As with NSUserDefaults it’s not neccessary to call synchronize every time you make a change (but calling synchronize will cause any changes to be sent to iCloud immediately).

Off line or No iCloud account

From my expeiments on my test devices if you are offline or if you have no iCloud account then values are still persisted - so it seems like these edge cases are not something to worry about.

Demo Project

I’ve put a very simple demo project up on github. Make sure you modifiy the app id to one that you have created on your own account and modified the code signing and provisioning profile settings.

#APP DEVELOPMENT #DATA SYNC #ICLOUD #IOS #NSUBIQUITOUSKEYVALUESTORE #PERSISTING SETTINGS #SUDOKU GRAB #USER DATA

Related Posts

Version 2 of SudokuGrab released - We've updated SudokuGrab with some major enhancements including iCloud syncing for your puzzles and support for iPads. There are a few bugs we're aware of and we're actively working to fix them in the coming weeks, with a new version already submitted to the app store.
Updating Sudoku Grab - Currently, I am revitalizing Sudoku Grab, my first app ever, published in 2009. The plan involves updating the code, upgrading to ARC, simplifying the menu system, accommodating iOS7, and supporting 4-inch display sizes. Future updates may include iCloud syncing features for universal access to puzzles. This endeavor also gives me an excuse to switch to an iPhone5s!
How does it all work? - In this blog, I explain the process behind my Sudoku Grab app, a solution that uses basic image processing techniques to recognize Sudoku puzzles. This is done by locating the puzzle in an image, turning it back into a square form, segmenting it to find potential numbers, and lastly, recognizing those numbers. This involves simple thresholding techniques, blob extraction algorithm, perspective transform, and a Neural Network for Optical Character Recognition (OCR) to recognize digits from the photograph. I conclude by mentioning the potential for multiple enhancements to this process.
Sudoku Grab Removed From Sale in Japan - Just got an email from Apple, claiming that my app 'Sudoku Grab' infringes on intellectual property rights of Nikoli.Co.Ltd. So, as a precaution, I've taken Sudoku Grab off the shelves in Japan.
Augmented Reality In The Browser - This blog showcases the progress of my idea to create an augmented reality Sudoku solver using technology that enables us to solve puzzles in our browser rather than with dedicated apps. I have developed an AR Sudoku solver with a simple image processing pipeline. It identifies and extracts Sudoku puzzles from pictures, recognizes each cell's numbers, solves the puzzle, and renders the solution on top of the original image. This process is accomplished by converting the image to greyscale, conducting thresholding, OCR-processing, and puzzle-solving. I've also done parallel image location and extraction. It's a technical journey that's achieved some high-quality, low-drift results, visible in the video included. The full codebase is accessible on Github. Enjoy the joy of leveraging technology to efficiently solve Sudoku puzzles!

Related Videos

Sudoku Grab for the iPhone - Unleash the power of technology to effortlessly solve Sudoku puzzles with this incredible iPhone App available on the App Store! Click to learn more and get started.
AR Sudoku Solver in Your Browser: TensorFlow & Image Processing Magic - Discover how to recreate a Sudoku app using browser APIs and ecosystem advancements, and explore the image processing pipeline technique for extracting Sudoku puzzles and solving them.
Augmented Reality iPhone Sudoku Grab - Experience real-time augmented reality capture with the new version of Sudoku Grab! Learn to build your own app with detailed guidance provided in the linked article.
Vision framework and CoreML - Discover the seamless integration of Apple's Vision framework with Core ML for object identification in this astounding demonstration, and lock onto the project at GitHub.
Pong on the apple watch - Get a glimpse of a quick demo on playing Pong on the Apple Watch, skillfully hacked together at the iOSDevUK event! Don't miss out!
HELP SUPPORT MY WORK: If you're feeling flush then please stop by Patreon Or you can make a one off donation via ko-fi
Want to keep up to date with the latest posts and videos? Subscribe to the newsletter
Blog Logo

Chris Greening


Published

> Image

atomic14

A collection of slightly mad projects, instructive/educational videos, and generally interesting stuff. Building projects around the Arduino and ESP32 platforms - we'll be exploring AI, Computer Vision, Audio, 3D Printing - it may get a bit eclectic...

View All Posts