Adam Howitt's Blog

Oct 19
2011

Getting Started with iCloud - Entitlement Issues

After battling through what seemed like a simple procedure to setup WalkJogRun for iCloud I figured I'd share the fix that worked for me.

The procedure as I understood it was as follows

  1. Enable iCloud for your fully qualified appId in the provisioning portal
  2. Regenerate and download your development provisioning profile and install it on your device and in Xcode
  3. Click my project in Xcode (4.2) and view the summary page for my target
  4. Scroll to the bottom and check the box to enable entitlements. It prepopulates the entitlement file and sets the two keys to match my app id
  5. Call
    NSString *containerId = @"com.mycompany.myapp";
    NSURL *iCloudURL = [[fileManager URLForUbiquityContainerIdentifier:containerId];
    NSLog(@"%@", [iCloudURL absoluteString]);
  6. Build and run on the device

The requested container identifier is not permitted by the client's com.apple.developer.ubiquity-container-identifiers entitlement

If I didn't see this error message the actual device would start to throw up in debug mode so I had to restart the phone to try again. I found an article that mentioned that you need the Team ID too for this approach so if you open the provisioning profile you'll find the team ID listed
<key>Entitlements</key>
    <dict>
        <key>application-identifier</key>
        <string>XXXXXXXXX.com.mycompany.myapp</string>
        <key>aps-environment</key>
        <string>development</string>
        <key>com.apple.developer.ubiquity-container-identifiers</key>
        <array>
            <string>YYYYYYYYY.*</string>
        </array>
You'll notice that the actual com.apple.developer.ubiquity-container-identifiers key is a wildcard so that any apps you develop can use iCloud as long as you use your Team-ID (the YYYYYYYY part). So the fix to my code is
NSString *containerId = @"YYYYYYY.com.mycompany.myapp";
NSURL *iCloudURL = [[fileManager URLForUbiquityContainerIdentifier:containerId];
NSLog(@"%@", [iCloudURL absoluteString]);

Build and run that and you should have success. However, I don't think I did, initially.

After some frustrating hours of trial and error I noticed the innocuous statement that specifying the containerId as nil will use the first one listed in your entitlements file. Huh. I tried it, built and run. Tada! NSLog shows the local fileURL my app can write to to send stuff to the cloud.

Now here's where it gets a little cloudy. Having seen that success I went back to my snippet code above with the YYYYYYY prefixed container ID and it seemed to work now. I'm not sure if I was missing a step when I first tried that but it's certainly working after the edit to pass nil instead.

Hope this helps!

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)

There are no comments for this entry.

[Add Comment] [Subscribe to Comments]