ICloud integration with Cut the Rope as an example

    Hello habra resident. Today I would like to tell you about my experience of integrating iCloud into Cut the Rope.

    This post was inspired by a review by one user who came to the technical support email address:
    “I do not need any help, I just wanted to ask you something ... How did you
    run iCloud Cut the Rope even if it is not a universal application? I
    alternate with iPhone and iPad without problems, and it is extraordinary.
    Unfortunately, no other developer does this, it is only with universal
    applications, so I wonder ... you are a magician you or others are not
    willing to do anything? You are number one for me, thank you for your
    beautiful game and support it for long. Hello. "

    I don’t know how extraordinary that the iPad and iPhone versions of the application use the same game progress, but today I will tell you how to achieve this. Moreover, it is very simple. I will also talk about some of the problems and their solutions that we encountered during integration.

    What is iCloud?
    iCloud is a free cloud storage service with push technology support. Created by Apple. In iOS appeared, starting with the fifth version. And on Mac OS starting with version 10.7 (Lion).

    Design Challenges
    We wanted the user to use iCloud as transparent as possible. Therefore, by default, we disabled this function and made a special item in the menu to enable it:

    It’s also done so that each member of the family can independently go through all the boxes on their iOS device using the same Apple ID.

    Since the data update is asynchronous, we decided to add the following notification about the availability of saving in iCloud:


    This notification makes it easy and simple to use the progress existing in iCloud. It is shown only once, after the first synchronization. Moreover, synchronization occurs regardless of the settings in the menu. The setting only affects whether we apply the resulting progress to a local one.

    The progress on the levels, it was decided to compose only the best results from each device. Thus, you can go one half of the box on one device and the other on the second and get full progress on the box on both devices through several synchronizations.

    The game Cut the Rope has the ability to reset game progress. And we thought about whether to reset the progress saved in iCloud with it. We decided that it was not worth it. We thought that iCloud will always store the last and best result for each level, so that the user can restore it at any time, despite any external factors. If a player wants to lose progress and complete the whole game from scratch, he can turn off synchronization with iCloud.

    Integration
    There are two ways to integrate iCloud into an iOS application:

    iCloud document storage (saving files to an iCloud user account) and
    iCloud key-value data storage (storing key-value data ).

    I will talk about the second option, because in our game, game progress is saved in this way - a couple of level-result.
    1. First of all, you need to enable iCloud support in the application on developer.apple.com and re-generate the corresponding profiles.
    2. Include entitlements in the project. In xcode version 4.2, this is done as follows:
      In the Project navigator, double-click on the project, select the desired target and on the Summary tab in the Entitlements section enable the checkbox opposite the “Enable Entitlements” line.
    3. In the iCloud Key-Value Store field, specify the container identifier used in the application. This identifier may be the same for different applications. It is in this way that the possibility of using one progress for two different applications is realized. As a result, for our applications, the identifier will look like “com.zeptolab.ctr”, for full versions (iPhone and iPad). And "com.zeptolab.ctrlite", for free versions. In our case, we had to split the progress files, because the free versions have a different number and order of levels.
      This is how the correct settings in our project look:

    4. In the application code, add listening to messages about data changes, for example:
      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notification:) name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification object:[NSUbiquitousKeyValueStore defaultStore]];
      And do not forget to unsubscribe from these messages when they are no longer needed:
      
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification
      object:[NSUbiquitousKeyValueStore defaultStore]];
    5. Accordingly, in the method to
      -(void)notification:(NSNotification *)notification
      handle the situation of obtaining new data.
    6. Work with NSUbiquitousKeyValueStore on the example of a dictionary. Access to the dictionary is as follows: And so it can be synchronized:

      
NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore];
      NSDictionary* storedDict = [store dictionaryForKey:GAME_PROGRESS];

      NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore];
      [store setDictionary:dict forKey:GAME_PROGRESS];
      [store synchronize];

    Note
    The NSUbiquitousKeyValueStore interface is very similar to NSUserDefaults. But the second cannot be completely replaced by the first. The application must always be locally saved up-to-date game progress.

    Support for older firmware :
    Since iCloud appeared only starting with iOS 5, this functionality will have to be disabled for compatibility with earlier versions.
    This is done as follows:
    • We put a weak link on Foundation.framework, otherwise when running on old firmware we will
      encounter the following error: "dyld: Symbol not found: _OBJC_CLASS _ $ _ NSUbiquitousKeyValueStore".
    • And we add a check in the code for the availability of iCloud functionality, for example like this: And isolate the rest of the code with it.
      +(BOOL)isCloudAvailable

      {
      id class = NSClassFromString(@"NSUbiquitousKeyValueStore");
      return class != nil;

      }


    Thanks for attention. Hope someone finds this article interesting.

    Useful Links
    iCloud Programming Guide
    NSUbiquitousKeyValueStore Class Reference


    Also popular now: