iCloud with Cloud Build

Hello!

I was wondering if anyone had managed to “turn on” iCloud for Cloud builds.
I’ve had a good old search around, and have of course looked into the various frameworks to modify the project file, but unfortunately iCloud is a bit more complex as it then requires an entitlement file, which seems generated on the fly from Xcode when enabling iCloud.

Thanks,

Guillaume.

I have not done it, but what I would suggest is to create the necessary files locally. Make a proper native plugin and add it in the post process to the XCode project!

I have the same problem, i don’t really understand how to setup iCloud with Unity Cloud Build. Here are the step with Xcode :

Enable iCloud and Select CloudKit
CloudKit is one of three app services provided by iCloud. The other iCloud app services—key-value storage and iCloud documents—also appear in the iCloud settings in Xcode. To use CloudKit, you first enable iCloud and then select the CloudKit service.

Set the Bundle ID in App Distribution Quick Start.

To enable iCloud and select CloudKit

  • In the Capabilities pane, select the switch in the iCloud row.

Xcode provisions your app to use iCloud. (Key-value storage is enabled by default.)

  • Select the CloudKit checkbox.

Xcode creates a default CloudKit container based on the bundle ID and adds the CloudKit framework to your project.

Your app can now store data and documents in iCloud.

1 Like

This looks not too difficult (maybe changing boolean values of this specific capabilities tab), you can modify the Unity-iPhone.xcodeproj which stores all those settings with the XCode manipulation API in an post process build step. You can checkout the Native Library Demo which uses post process builds to add a native library to a XCode build in a post process build.

Sorry but i’m still stuck with this, inside PBXProject.cs i don’t see anything about “Capabilities” options. I don’t really understand what it does overall.

Is there any other example or documentation that explain how the Xcode manipulation API work ?

Hello!

David, I still need to look at the native library demo, but the issue here is not to add a library to the Xcode project.
I’m sure it’s relatively straight forward once you know what you’re doing, but adding the capabilities / entitlements / whatever they’re called for iCloud seemed actually pretty painful when I looked at it as ticking the box in the project UI seems to change the project file in significant ways - nothing you guys can do about it I know!
Are you guys planning on documenting the XCode manipulation API?

Thanks!

G.

I’ve been looking into automating some of our manual work with Unity-to-XCode builds and I’ve also got this same problem.

The mystery here is figuring out what that large ON/OFF is called in the PBXProj file and seeing that there is no Quick Help for this item in XCode and reading through what it does in the “Steps”-section it makes sense that this ON/OFF thing is not a single setting, but a shortcut tool to add/remove all the mentioned stuff in the “Steps” section.

I came across this while trying to automate the GameCenter capability, but for iCloud the “Steps” indicate that you’ll

  1. need to find and parse or create the entitlements file and then edit and save it during your PostProcess. Not sure if XCodeApi has a tool for this already.

  2. Use XCodeApi to link CloudKit.framework by using PBXProject.AddFrameworkToProject method. There is some example code in Unity xcode api - Unity Engine - Unity Discussions but hope other more specific examples can also be found.

After a couple of hours I finally got this working,
It may not have been worth it since enabling iCloud manually probably would have saved more time but oh well…
anyway here’s my build script

Here’s the most important piece of the code:

//find project
                string projectPath = "/Volumes/Jesper Ext/unity/ZeGame/ZeGame_ios/xcode/Unity-iPhone.xcodeproj/project.pbxproj";
                PBXProject project = new PBXProject();
                project.ReadFromFile(projectPath);
                string targetGuid = project.TargetGuidByName("Unity-iPhone");

                //add cloudkit framework (this is still easy)
                project.AddFrameworkToProject(targetGuid,"CloudKit.framework",false);

                //copy the entitlements file, you should generate this once
                //using xcode, then put it somewhere on your disk so
                //you can copy it to this location later
                File.Copy("/Volumes/Jesper Ext/unity/ZeGame/ZeGame_ios/ZeGame.entitlements","/Volumes/Jesper Ext/unity/ZeGame/ZeGame_ios/xcode/Unity-iPhone/ZeGame.entitlements");



                //now this is where it gets messy, because the PBXProject
                //class doesn't support enabling iCloud so you'll
                //have to change the string manually
                //I suggest you build your xcode project once (without
                //playing it automatically, so you'll have to remove
                // BuildOptions.AutoRunPlayer; from the buildoptions
                //then duplicate your xcode project folder and enable
                //iCloud in one of them. You can then use a site like
                //https://www.diffnow.com/ to find the difference
                //between the two projects.
                //not all differences have to be included but these are
                //the ones I found that are necessary.

                string projectString = project.WriteToString();

                //add entitlements file
                projectString = projectString.Replace("/* Begin PBXFileReference section */",
                    "/* Begin PBXFileReference section */\n\t\t244C317F1B8BE5CF00F39B20 /* ZeGame.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = ZeGame.entitlements; path = \"Unity-iPhone/ZeGame.entitlements\"; sourceTree = \"<group>\"; };");

                //add entitlements file (again)
                projectString = projectString.Replace("/* CustomTemplate */ = {\n            isa = PBXGroup;\n            children = (",
                    "/* CustomTemplate */ = {\n            isa = PBXGroup;\n            children = (\n                244C317F1B8BE5CF00F39B20 /* ZeGame.entitlements */,");

                //add some kind of entitlements command
                projectString = projectString.Replace("CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;",
                    "CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = \"Unity-iPhone/ZeGame.entitlements\";");

                //add development team you'll have to replace ****
                //with your own development string, which you can find
                //in your project.pbxproj file after enabling icloud
                projectString = projectString.Replace("TargetAttributes = {",
                    "TargetAttributes = {\n                    1D6058900D05DD3D006BFB54 = {\n                        DevelopmentTeam = ******;\n                    };");

                //save the file
                File.WriteAllText(projectPath, projectString);

I hope this will help anyone out there, maybe I didn’t waste those couple of hours after all that way.

9 Likes

Thanks a lot! This will be very helpful :slight_smile:

1 Like

If anyone is still interested in doing this I created a unity package which is based on the code from @Jespertheend2

It uses relative directories and doesn’t have any other build code so it should be easy enough to setup. Just install the package and edit the two variables at the top of ‘CloudPostBuild.cs’

http://www.emstudios.co.uk/gdocs/CloudBuildSetup.zip

3 Likes

I tried this but I’m getting this error when building with Xcode 8

9664: [xcode] Check dependencies
9665: [xcode] Unity-iPhone has conflicting provisioning settings. Unity-iPhone is automatically signed, but provisioning profile GAMEPROFILE has been manually specified. Set the provisioning profile value to “Automatic” in the build settings editor, or switch to manual signing in the project editor.
9666: [xcode] Code signing is required for product type ‘Application’ in SDK ‘iOS 10.0’
9667: [xcode] ** ARCHIVE FAILED **

Anyone got any ideas for a solution?

Not sure if that has anything to do with iCloud support. Were you able to get a codesigned build without iCloud?
Otherwise it is probably because of the changes in unity since they now automatically select a team. But I’m not sure what got changed exactly.

Yeah, it has been working until I added this icloud build script.

Hmm alright. Are you able to get iCloud working without the build script? I mean by enabling iCloud manually in xcode before archiving.

The build script sets up the team automatically - you can remove that by changing ‘TeamGUID’ in CloudPostBuild.cs to an empty string (e.g. const string TeamGUID = "" )

The other part of the code just enables the iCloud button and entitlements file setup that you would normally have to do manually in xCode.

Got it to build with Xcode 7.3 but then the app wouldn’t install “Could not be installed at this moment” Guessing the profile got messed up somehow. Retrying with Xcode8 and a higher postprocessbuild tag since it might be conflicting with some plugins post build.

9707: [xcode] Provisioning profile “Fluffy Jump iCloud” doesn’t include the com.apple.developer.icloud-container-identifiers entitlement.
9708: [xcode] Code signing is required for product type ‘Application’ in SDK ‘iOS 10.0’
9709: [xcode] ** ARCHIVE FAILED **

Now I got this instead. This is fun…

I got it building and installing again. The iCloud.com.dev.game adress was incorrect.

Hey guys. So I build my xcode project and found the mmk.entitlements file.

I cross checked with the app.entitlements from @tonemcbride and I found out they are the same?

If the values are the same, why should I copy from my own xcode project? Should I be changing values on my own mmk.entitlements?

Thanks.