Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. We're looking for your feedback on the platforms you use and how you use them. Let us know!
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  5. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  6. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  7. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

How can you add items to the Xcode project targets Info.plist using the XcodeAPI?

Discussion in 'Unity Cloud Build' started by Simurr, Jun 3, 2015.

  1. Simurr

    Simurr

    Joined:
    Jan 2, 2012
    Posts:
    9
    Is this possible with the XcodeAPI?

    I need to add an API key and some boolean values to the generated xcode projects Info.plist. I don't see any examples on how to do that.

    Perhaps it's outside the scope of the XcodeAPI? Any suggestions on how to do this using C# in a post build process function?

    sim
     
    hammondt likes this.
  2. David-Berger

    David-Berger

    Unity Technologies

    Joined:
    Jul 16, 2014
    Posts:
    646
    It's not Unity Cloud Build Specific, but as I wanted to make a tutorial already for a while, I'll post it here. This is useful when you want to edit the Info.plist of an Xcode project built by Unity when building for iOS. This can be used for example to change the values of Version (CFBundleShortVersionString) and Build (CFBundleVersion) in an Xcode project from within Unity, as a build post-process.

    Step-by-step guide
    1. Create/Have a Unity project
    2. Create a folder inside Assets called Editor
    3. Download the Xcode Manipulation API files from https://bitbucket.org/Unity-Technologies/xcodeapi/src/ and place them inside a sub-folder inside Assets > Editor such as Assets > Editor > xcodeapi
    4. You can now create a script such as the one below to alter CFBundleVersion in Xcode plist
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.Callbacks;
    4. using System.Collections;
    5. using UnityEditor.iOS.Xcode;
    6. using System.IO;
    7.  
    8. public class ChangeIOSBuildNumber {
    9.  
    10.     [PostProcessBuild]
    11.     public static void ChangeXcodePlist(BuildTarget buildTarget, string pathToBuiltProject) {
    12.  
    13.         if (buildTarget == BuildTarget.iOS) {
    14.        
    15.             // Get plist
    16.             string plistPath = pathToBuiltProject + "/Info.plist";
    17.             PlistDocument plist = new PlistDocument();
    18.             plist.ReadFromString(File.ReadAllText(plistPath));
    19.        
    20.             // Get root
    21.             PlistElementDict rootDict = plist.root;
    22.        
    23.             // Change value of CFBundleVersion in Xcode plist
    24.             var buildKey = "CFBundleVersion";
    25.             rootDict.SetString(buildKey,"2.3.4");
    26.        
    27.             // Write to file
    28.             File.WriteAllText(plistPath, plist.WriteToString());
    29.         }
    30.     }
    31. }
    32.  
    Which sets the CFBundleVersion in your Info.plist in a post process step to "2.3.4" (works also in Unity Cloud Build in all Tiers).

    I hope this makes sense and helps. Please let me know how it goes! :)
     
    Hanh, maho125, eppz and 6 others like this.
  3. Simurr

    Simurr

    Joined:
    Jan 2, 2012
    Posts:
    9
    Thank you! That worked perfectly.

    We are using it for background location and fetch stuff in a native plugin.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.Callbacks;
    4. using System.Collections;
    5. using UnityEditor.iOS.Xcode;
    6. using System.IO;
    7.  
    8. public class MyPluginPostProcessBuild
    9. {
    10.     [PostProcessBuild]
    11.     public static void ChangeXcodePlist(BuildTarget buildTarget, string pathToBuiltProject)
    12.     {
    13.         if ( buildTarget == BuildTarget.iOS )
    14.         {
    15.             // Get plist
    16.             string plistPath = pathToBuiltProject + "/Info.plist";
    17.             PlistDocument plist = new PlistDocument();
    18.             plist.ReadFromString(File.ReadAllText(plistPath));
    19.            
    20.             // Get root
    21.             PlistElementDict rootDict = plist.root;
    22.            
    23.             // background location useage key (new in iOS 8)
    24.             rootDict.SetString("NSLocationAlwaysUsageDescription", "Uses background location");
    25.            
    26.             // background modes
    27.             PlistElementArray bgModes = rootDict.CreateArray("UIBackgroundModes");
    28.             bgModes.AddString("location");
    29.             bgModes.AddString("fetch");
    30.            
    31.             // Write to file
    32.             File.WriteAllText(plistPath, plist.WriteToString());
    33.         }
    34.     }
    35. }
    Need some clarification.
    Do I need to download the XcodeAPI and include it in my project if we are already using Unity 5 (5.0.2p3)? It already seems to be included, though I'm guessing it's not the newest version.

    Would this work with 4.6.5? Would that require including the XcodeAPI like you instructed?

    Am I correct in assuming this would also work with Unity Cloud Build?
     
  4. David-Berger

    David-Berger

    Unity Technologies

    Joined:
    Jul 16, 2014
    Posts:
    646
    Yes, there is also a XCode API for 4.6 and 5. If you use source code of the repro you can alter the framework if necessary and it can be optimised. Yes, it also works with Unity Cloud Build. :cool:
     
    liortal likes this.
  5. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    2,909
    Thanks, i used the sample code shown above and was able to modify the Info.plist to add what i wanted.
    The major issue was only understanding what's the name of the element i need to be added :)

    In my book, a good API is one that can be used straight away without reading through docs, etc.... (naming conventions are good and it's hard to find your way around).

    So, good work guys, Thanks !!!! :)
     
    David-Berger likes this.
  6. joonturbo

    joonturbo

    Joined:
    Jun 24, 2013
    Posts:
    38
    Found the answer a bit confusing until I realized I didn't need to actually download the API in Unity version 5.1.1
     
  7. David-Berger

    David-Berger

    Unity Technologies

    Joined:
    Jul 16, 2014
    Posts:
    646
    Yes, the guide was made for 4.6, in 5.x you don't need to add the XCode API into your project.
     
    Emmanuel_Charon likes this.
  8. joonturbo

    joonturbo

    Joined:
    Jun 24, 2013
    Posts:
    38
    it works great.
    I already made a hack, that I set the version to 1.0.0#1, and then parse it in the post-build-processor.

    Is there a way to make cloudbuild auto-increment everytime it builds?
     
  9. David-Berger

    David-Berger

    Unity Technologies

    Joined:
    Jul 16, 2014
    Posts:
    646
    Sweet!
    You can use the Build Manifest to determine the build number! I added a sample about the Build Manifest here. :)
     
  10. urfx

    urfx

    Joined:
    Dec 12, 2013
    Posts:
    10
    hey David, some useful posts again. many thanks (you answered my iOS question too!)...

    can I ask two things.

    1. is there a similar routine for Android's manifest.xml ?
    2. Alternatively, is there anyway to just include hard coded plist or manifest files for iOS and Android respectively ?...

    I'm extending both to include a custom url scheme e.g. mygamename://
     
  11. David-Berger

    David-Berger

    Unity Technologies

    Joined:
    Jul 16, 2014
    Posts:
    646
    1. But if you need something more fancy, you will have to write some code in a post process script. The xml format is easy to modify, compared to the xcodeproj, so you don’t really need a “manipulation api" if that makes sense?
    2. You can have multiple manifests in your project and Unity merges them I think. That's probably not possible on iOS, but there you have the XCode manipulation API :)
     
  12. urfx

    urfx

    Joined:
    Dec 12, 2013
    Posts:
    10
    thanks

    just to confirm...

    so for android we just add a manifest to the Assets/Plugins/Android folder

    and RTM for Xcode manipulation API ! ;)
     
  13. peterworth

    peterworth

    Joined:
    Mar 4, 2014
    Posts:
    7
    I'm getting lots of errors in PBXProject.cs, like:

    Error CS0234: The type or namespace name `CombinePaths' does not exist in the namespace `UnityEditor.Utils'. Are you missing an assembly reference? (CS0234) (Assembly-CSharp-Editor)

    In Unity 4.6.8p3

    Any ideas?
     
  14. chrs1885

    chrs1885

    Joined:
    Jun 4, 2015
    Posts:
    4
    Hi,

    I'm trying to add URL Schemes to my Info.plist.

    While adding frameworks is working just fine, accessing the root dictionary of my plist doesn't seem to work as expected:

    Code (CSharp):
    1. // Add url schema to plist file
    2. string plistPath = path + "/Info.plist";
    3. PlistDocument plist = new PlistDocument();
    4. plist.ReadFromString(File.ReadAllText(plistPath));
    5.            
    6. // Get root
    7. PlistElementDict rootDict = plist.root;
    When I step debug the code, Mono Develop shows me

    FYI, the plistPath is correct.

    Am I doing anything wrong?
     
  15. David-Berger

    David-Berger

    Unity Technologies

    Joined:
    Jul 16, 2014
    Posts:
    646
    @urfx yes
    @peterworth make sure you update the XCode Manipulation API to the correct version for 4.6
    @chrs1885 What's the plistPath pointing to? I assume path is the path handed over from the post process method?
     
  16. soloneer

    soloneer

    Joined:
    Nov 23, 2010
    Posts:
    62
    Which is the correct version for 4.6?
     
  17. David-Berger

    David-Berger

    Unity Technologies

    Joined:
    Jul 16, 2014
    Posts:
    646
  18. soloneer

    soloneer

    Joined:
    Nov 23, 2010
    Posts:
    62
    That's the version (latest commit) that gives me errors in Unity 4.6. Same ones that @peterworth mentioned: Namespace CombinePaths does not exist in namespace UnityEditor.Utils, etc. That's why I thought when you mentioned right version you meant a commit version, I just assumed the latest was only written for Unity 5.
     
  19. David-Berger

    David-Berger

    Unity Technologies

    Joined:
    Jul 16, 2014
    Posts:
    646
    The latest commit should work properly. Did you add the source directly into Unity? That might be broken and might not work without modification I fear, best is to build the dll separately and include the resulting dll into the project. I'll forward it to the devs, maybe they can fix it for the next release of the public API.

    In the meantime if you need precompiled dlls with a working Unity Cloud Build project check out the examples in the UCB Demos for Unity 4 and Unity 5. It's the Library Demo project which includes the dlls in the Editor folder of the subfolder project.
     
  20. chrs1885

    chrs1885

    Joined:
    Jun 4, 2015
    Posts:
    4
    Yes! :)
     
  21. David-Berger

    David-Berger

    Unity Technologies

    Joined:
    Jul 16, 2014
    Posts:
    646
    @chrs1885 could you print the final plistPath? Something is wrong, I know that adding urlschemes is working properly from other projects. :confused:
     
  22. arTk_ev

    arTk_ev

    Joined:
    Mar 24, 2013
    Posts:
    6
    Try insert "using Utils = PBX.Utils;"
     
    blue-mile likes this.
  23. zero_null

    zero_null

    Joined:
    Mar 11, 2014
    Posts:
    152
    how to get the path of Classes/UI/UnityViewControllerBase.mm
     
  24. yakandco

    yakandco

    Joined:
    Dec 3, 2014
    Posts:
    82
    I totally missed that this had been added.. awesome work guys. So great to have a tidy compile process again and not have to worry about manually editing a plist. The whole API looks so well written, thanks!!

    Are their some docs somewhere or more examples? I'd love to know how to add in a folder reference of assets to the xcode project - something I need to manually do every build, and to also add frame works. Thanks again!! =)
     
  25. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    2,909
  26. yakandco

    yakandco

    Joined:
    Dec 3, 2014
    Posts:
    82
    Thanks! =)
     
  27. mopsicus

    mopsicus

    Joined:
    Feb 15, 2016
    Posts:
    13
    How can I add embedded framework via XCode api?
     
  28. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    2,909
    Is this a framework that you added to your project (e.g: plugin), or something that is build-in and should already exist in Xcode ?
     
  29. mopsicus

    mopsicus

    Joined:
    Feb 15, 2016
    Posts:
    13
    I want to add not build-in framework
     
  30. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    2,909
    And did you try to add it using the XcodeAPI (like the examples linked above) ?
     
  31. mopsicus

    mopsicus

    Joined:
    Feb 15, 2016
    Posts:
    13
  32. fagtr0n

    fagtr0n

    Joined:
    Apr 2, 2014
    Posts:
    2
    Hey, so far this is great example working with making new array elements! Works for me.

    Could it be possible to get an example of how to create a new boolean in the info.plist?
    For example, "Application supports iTunes file sharing" and set it to "YES".

    I try to write the script, and I can't find a way to ".CreateBool", so I guess it some kind of conversion from a Dict/Array, but for me all combinations I try with .AsBoolean result in error.

    Here is my code fail based on the original example:

    Code (CSharp):
    1. PlistElementBoolean iTunesFileSupport = rootDict.CreateArray("Application supports iTunes file sharing");
    2.             iTunesFileSupport.AsBoolean(true);
    What am I doing wrong?
    Help/Tips/Examples appreciated!
     
    Last edited: Jul 18, 2016
  33. VsevolodPiletski

    VsevolodPiletski

    Joined:
    Jul 18, 2016
    Posts:
    1
    I don't know if this post is correct for my question, but i'll write it anyway, just correct me if i'm wrong.

    I'm interested in adding new target to XCode project. Can I do it with code, adn if yes, how can I?
     
    alejobrainz likes this.
  34. alejobrainz

    alejobrainz

    Joined:
    Sep 10, 2005
    Posts:
    247
    We are also very interested in automatically adding targets, especially App Extensions (Sticker Packs, iMessage Extensions and Notification Content Extensions). With the release of iOS 10 App extensions have become a very important part to the user interaction and experience with the apps.

    There is an open thread at:
    http://forum.unity3d.com/threads/ho...sions-to-unity-ios-build.287183/#post-2793951

    But there is no response from UT yet. @David-Berger, do you know if integrating App extensions is feasible via Xcode API and Cloud Build?
     
  35. l3aronsansgland

    l3aronsansgland

    Joined:
    Oct 1, 2016
    Posts:
    1
    I am following all the described steps and I have the following error in Unity:
    PXPorject.cs [...]: The type or namespace 'CombinePaths' does not exist in the namespace 'UnityEditor.Utils'

    Am I missing something?
     
    Noor-Ali likes this.
  36. Noor-Ali

    Noor-Ali

    Joined:
    Feb 26, 2015
    Posts:
    2
    @peterworth

    Somehow, Utils are giving errors. Double click on errors and replace Utils with PBX.Utils
     
  37. jaydipsinh

    jaydipsinh

    Joined:
    Mar 31, 2017
    Posts:
    1
    hi david sir.
    please guide me for make printing functionality in IOS and Android device
     
  38. jason_yak

    jason_yak

    Joined:
    Aug 25, 2016
    Posts:
    186
  39. jason_yak

    jason_yak

    Joined:
    Aug 25, 2016
    Posts:
    186
  40. Cromfeli

    Cromfeli

    Joined:
    Oct 30, 2014
    Posts:
    170
    Is it possible to use the same for OSX?

    https://docs.unity3d.com/ScriptReference/iOS.Xcode.PBXProject.html