My app crashes with an "Application initializing document picker is missing the iCloud entitlement" when either of the following two lines is executed:
UIDocumentPickerViewController* documentPicker =
[[UIDocumentPickerViewController alloc]
initWithDocumentTypes:@[@"public.data"]
inMode:UIDocumentPickerModeImport];
UIDocumentMenuViewController *documentMenu =
[[UIDocumentMenuViewController alloc]
initWithDocumentTypes:@[@"public.data"]
inMode:UIDocumentPickerModeImport];
The Document Picker Programming Guide states that "Before your app can use the document picker, you must turn on the iCloud Documents capabilities in Xcode."
However, my app is not built with Xcode: it is built using third-party tools (the cross-platform toolkit, Marmalade), so I cannot do this.
It should still be possible to turn on iCloud Documents capabilities for this app manually — the switch in iCloud simply automates the process — but my attempts to do so have not fixed the crash.
What I've tried so far
Xcode displays the steps it carries out when switching on iCloud:
- Add the "iCloud" entitlement to your App ID
- Add the "iCloud containers" entitlement to your App ID
- Add the "iCloud" entitlement to your entitlements file
- Link CloudKit.framework
I also found Apple's Entitlements Troubleshooting TechNote, which describes steps that can be taken to check that the following steps have been carried out correctly.
I have enabled iCloud on my App ID:
I'm not certain whether this is necessary to use the document picker's simple import and export operations, but I also set up an iCloud container with the id iCloud.com.[company].[app]
.
I have generated an updated provisioning profile that includes the iCloud entitlements:
I inspected the downloaded provisioning profile using the command:
security cms -D -i /path/to/iOSTeamProfile.mobileprovision
It includes the following entries:
<key>com.apple.developer.icloud-services</key>
<string>*</string>
<key>com.apple.developer.icloud-container-environment</key>
<array>
<string>Development</string>
<string>Production</string>
</array>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.com.[company].[app]</string>
</array>
<key>com.apple.developer.icloud-container-development-container-identifiers</key>
<array>
<string>iCloud.com.[company].[app]</string>
</array>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array>
<string>iCloud.com.[company].[app]</string>
</array>
Marmalade uses this provisioning profile to generate the entitlements file for the app.
I have inspected the generated entitlements using the following command:
codesign -d --ent :- [App.app]
Which gives the following output:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>[team-id].com.[company].[app]</string>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.icloud-container-development-container-identifiers</key>
<array>
<string>iCloud.com.[company].[app]</string>
</array>
<key>com.apple.developer.icloud-container-environment</key>
<array>
<string>Development</string>
<string>Production</string>
</array>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.com.[company].[app]</string>
</array>
<key>com.apple.developer.icloud-services</key>
<string>*</string>
<key>com.apple.developer.team-identifier</key>
<string>[team-id]</string>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array>
<string>iCloud.com.[company].[app]</string>
</array>
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
<string>[team-id].*</string>
<key>get-task-allow</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>[team-id].com.[company].[app]</string>
</array>
</dict>
</plist>
However, the app still crashes whenever the functions are called.
I also found this old guide to setting up iCloud in Marmalade apps. Most of the steps seem no longer to be necessary/possible, but I followed the suggestion to add the application-identifier
key to my Info.plist.
What else do I need to do to add iCloud Documents capabilities to my app?