Saturday, June 11, 2011

iCloud App Sample and entitlement code-sign error

iOS 5 beta has iCloud support now, but getting the entitlement code-sign to work has some steps that are missing from Apple Documentation.

You should use the new Xcode 4.2 for iOS 5 SDK and with iOS5 on an iDevice.

1) You need to create a new App ID in the iOS Provisional Portal, if you use an existing ID, it must not be a wildcard one. For example, you create a new APP ID called com.yourcompany.icloudtest and the App Name is called icloudtest
When you create the New App ID, you will be asked whether to Generate New or select an existing one for the Prefix (existing prefix can have the benefit of sharing the same keychain access or may be iCloud Document folder). Suppose we generate a new prefix in this case. And the new generated prefix is 99Z9Z98987

2) After created the New App ID, you should first enable iCloud for that New App ID and then create the a New Provisional Profile for that New App icloudtest.

3) Suppose the new Development Profile called "iCloudTest" is created and downloaded to the Mac.

4) Launch Xcode and created an empty Universal Application called "icloudtest" and the Bundle Identifier should be com.yourcompany.icloudtest



5) Import the Development Profile "iCloudTest.mobileprovision" to Xcode and to iPhone/iPad which should be iOS 5 beta

6) Click the Build Settings of the Project and Select the code sign identity to the "iCloudTest" Provisional Profile

7) Click the Summary Settings of the Project and scroll down to entitlements and click the Custom Entitlements, Xcode will create a file called icloudtest.entitlements


8) Click the icloudtest.entitlements in the Project Explorer and add these key rows (Right Click -> Add Row) in the entitlements file
com.apple.developer.ubiquity-kvstore-identifier is String Type
com.apple.developer.ubiquity-container-identifiers is Array Type



9) Enter the Team-ID.com.yourcompany.icloudtest into the Value column. The important part is where to get the Team-ID ?

10) Don't confuse with the Team-ID with the App ID that the development portal generated for you. If you look at the "iCloudTest.mobileprovision" file downloaded as in step 5 above. You will see something like this

Yes, ZZZZ826ZZ2 is the Team-ID where 99Z9Z989Z7 is the App ID in this case

iCloudTest.mobileprovision Select all

<key>Entitlements</key>
<dict>
<key>application-identifier</key>
<string>99Z9Z989Z7.com.yourcompany.icloudtest</string>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array>
<string>ZZZZ826ZZ2.*</string>
</array>
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
<string>ZZZZ826ZZ2.*</string>
<key>get-task-allow</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>99Z9Z989Z7.*</string>
</array>
</dict>



The Team-ID can also be found at Your Account area of Member Center
After login the iOS Dev Center, click
Member Center (in top navigation bar)-> Your Account -> Program Membership -> Individual ID



11) Enter the Team-ID + Bundle Identifier in the icloudtest.entitlements as below



icloudtest.entitlements Select all

<!--?xml version="1.0" encoding="UTF-8"?-->

<plist version="1.0">
<dict>
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
<string>ZZZZ826ZZ2.com.yourcompany.icloudtest</string>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array>
<string>ZZZZ826ZZ2.com.yourcompany.icloudtest</string>
</array>
</dict>
</plist>


12) Add these code in the icloudtestAppDelegate.m to test this iCloud App

icloudtestAppDelegate.m Select all

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

NSFileManager *fileManager = [NSFileManager defaultManager];
// Team-ID + Bundle Identifier
NSURL *iCloudURL = [fileManager URLForUbiquityContainerIdentifier:@"ZZZZ826ZZ2.com.yourcompany.icloudtest"];
NSLog(@"%@", [iCloudURL absoluteString]);

NSUbiquitousKeyValueStore *cloudStore = [NSUbiquitousKeyValueStore defaultStore];
[cloudStore setString:[iCloudURL absoluteString] forKey:@"iCloudURL"];
[cloudStore synchronize]; // Important as it stores the values you set before on iCloud

UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,round(self.window.bounds.size.height/4.0),self.window.bounds.size.width,round(self.window.bounds.size.height/8.0))];
myLabel.font = [UIFont fontWithName:@"Marker Felt" size:round(self.window.bounds.size.width/20.0)];
myLabel.numberOfLines = 4;
myLabel.text =[ @"iCloudURL=" stringByAppendingFormat:@"%@", [cloudStore stringForKey:@"iCloudURL"]];
myLabel.backgroundColor = [UIColor clearColor];
myLabel.textColor = [UIColor whiteColor];
myLabel.textAlignment = UITextAlignmentCenter;
[self.window addSubview:myLabel];

[self.window makeKeyAndVisible];
return YES;
}



13) Run it in iOS device
.
.
.