Get tired in dragging frameworks and dependence in Xcode? Try XUPorter

Project github page: https://github.com/onevcat/XUPorter

Hi, everyone. I’d like to share a tool to you.

Overview

If you are doing mobile game development and targeting for iOS platform, you might be suffering in the post build process of Unity3D, especially when you are using some third part framework or plugin. You always drag a lot of frameworks and files to your Xcode project, and then build to see whether you forget something. You even made a check list and do it again and again every time you want to see how your game runs on iOS devices. Of course you can use post process script to regenerate the Xcode project, but it required a lot of skills and time, which might not be a clever way.

Now here is a tool for you to make your life easier. I am working on a project call XUPorter (means a dependency porter from Unity to Xcode), which can help you to add files and frameworks to your Xcode project after it is generated by Unity 3D automatically and dramatically.

Installation

Add all files of the repo to your Unity project’s Editor Folder: {$ProjectFolder}/Assets/Editor/XUPorter or you can download this unity package and import to your project.

Some demos are contained in /Mods folder, they are just a tutorial to help you getting start. Please feel free to delete or substitute all files in that folder as soon as you know how to use XUPorter. A simplified MiniJSON is now used in XUPorter, but I put it into a namespace, so there is no worry of conflicting, even if you are already using a same JSON wrapper.

XUPorter require Unity 3.5 or higher and Xcode 4 to work properly. I have tested for Xcode 5 DP and it can work well now too.

Usage

After the Unity’s building phase, OnPostProcessBuild in XCodePostProcess.cs will be called and Xcode project file will be modified. All .projmods (which is in JSON) will be treated as Xcode patch setting files (In the demos, all .projmods files are in /Mods folder). XUPorter will find and read all projmods files in /Assets and modify Xcode project file as settings.

In these setting files, specify the fields using a json pattern.

  • group:The group name in Xcode to which files and folders will added by this projmods file
  • libs:The name of libs should be added in Xcode Build Phases, libz.dylib for example. If you want to import a .a lib to Xcode, add it as a file(in “files”)
  • frameworks:The name of framework should be added in Xcode Build Phases, Security.framework for example. If you want to add a third part framework, add it using a relateive path to files section instead of here.
  • headerpaths:Header Search Paths in Build Setting of Xcode
  • files:Files which should be added
  • folders:Folders which should be added. All file and folders(recursively) will be added
  • excludes:Regular expression pattern. Matched files will not be added.
  • linker_flags: Linker flags which should be added, e.g. “-ObjC”

One example, the following file will add all files in /iOS/KKKeychain to the Xcode group KKKeychain and add the Security.framework to Xcode project.

{
    "group": "KKKeychain",
    "libs": [],
    "frameworks": ["Security.framework"],
    "headerpaths": [],
    "files":   [],
    "folders": ["iOS/KKKeychain/"],    
    "excludes": ["^.*.meta$", "^.*.mdown$", "^.*.pdf$"],
    "linker_flags": []
}

LICENSE
This code is distributed under the terms and conditions of the MIT license.
Copyright (c) 2012 Wei Wang @onevcat

Project github page: https://github.com/onevcat/XUPorter

Use it as you like! And of course you are welcome to follow and fork the project. If you have any problems, feel free to open an issue in the project page or modify the code and send me a pull request. I hope it can help you. Cheers :razz: (If you’d like to support me, could you consider to look at my this asset about easy implement of rating system for mobile and if you find it useful you can purchase one. That will encourage me a lot, thank you)

2 Likes

This looks amazing, thank you for sharing.

Yeah almost missed this. Thanks a lot for sharing :slight_smile:

It worked amazing until I update the prime31 plugin. The prime31’s new build system will add wrong frameworks (correct name but incorrect path) if using XUPorter. Not sure whether this is still an issue now.

Hi, thanks for the information. I am not using prime31’s plugin so I can not tell what happened. I searched for prime31’s plugin but cant not find a free version which contains the build system (They are expensive for me as a individual developer). If there is a free plugin contains the build system, I’d like to check it to see what can I do to improve XUPorter.

Hey @onevcat, i can’t figure out how to make XUPorter with my asset bundles!!

I generate my assetbundles as .unity3d files, outsite my Assets folder, something like …/AssetBundles, and everything inside here is a .unity3d file.
And I try to make one .projmods to get all the content inside this Folder as a root folder inside my XCode Project, so my .promods is something like these:

{
    "group": "",
    "libs": [],
    "frameworks": [],
    "headerpaths": [],
    "files":   [],
    "folders": ["../../../../AssetBundles/"],    
    "excludes": [],
	"linker_flags": []
}

This path: …/…/…/…/AssetBundles/ extists and is based on the Mod folder, but inside my unity xcode project, all I get is a empty folder with the name “AssetBundles” but with nothing inside.
What I’m doing wrong?

BTW this plugins looks amazing, a life saver!

Hi @badawe. Right now XUPorter can only deal with files and folders in the XUPorter’s folder (I think it is better to be more self-contained). It does not support relative path containing “…”.

So you need to copy your AssetBundles folder to XUPorter/Mods/iOS (the final path should be something like “/Assets/Editor/XUPorter/Mods/iOS/AssetBundles”). Then change the value of “folders” key in promods file to “iOS/AssetBundles/” and it should work. You do not need to copy the .unity3d files to your xcode project folder, all the resources should show in the “Copy Bundle Resources” in Xcode’s Build Phases section and they can be copied to the bundle when you build your project in Xcode.

Maybe I will commit a patch later to make relative path available.

Hello,

It seems that making XUPorter run after the PostProcessBuildPlayer from prime31 solves the problem. Solved it for me too at least. See the last and second to last posts in this thread.

http://forum.unity3d.com/threads/177953-Prime31-s-new-build-tools-and-linker-errors

Hello.

I’ve placed my framework in “Mods/iOS/MyFW.framework” and have tried several ways to use this framework from an obj-c plug-in I wrote, but my plug-in doesn’t compile because Xcode can’t find “MyFW.h” – because it’s unaware of the above framework.

I’ve added “iOS/MyFW.framework” to the “folders” section of my .projmods file and I don’t see any errors in the Unity console window so MyFW.framework appears to be copied correctly. But I still get the above error.

I’ve also tried adding “MyFW.framework” to the “frameworks” section of my .projmods file, but that appears to have no effect.

Am I doing something wrong or is my expectation invalid – that I should be able to copy and use a third-party framework?

Thx,
ALF

Try to put it into the file section. For example your framework is something like “/Editor/XUPorter/Mods/iOS/x.framework”, so you should write

“files”: [“iOS/x.framework”],

Sorry for that. If I have time I will fix it.

Thanks! Taking a look and see what I can do about it.

I’ve actually tried it both ways – in “directories” and in “files”. Neither worked.

From what I’ve read online, what I’m doing is like a “private framework”. I need to reference the framework from a custom location within the bundle once it has been properly copied into the bundle via XUPorter.

I think XUPorter is copying the framework directory structure, but not sure where it goes and not sure how to get Xcode to recognize it as a framework to be linked?

Thx,
ALF

Which commit are you using to do that? I pushed a fix for the search path recently (this one, I believe). If you are using XUPorter earlier than it, the custom framework will not be found so you will suffer that error. If you can not get it work even in the lateset version, would you mind to send your MyFW.framework to me and maybe I can take a look.

I’ll try that link but I just downloaded it from github yesterday.

I can’t send you the framework itself, but there’s nothing wrong with it. If I manually copy the framework into /Applications/Xcode/…/SDK/Library/Frameworks, Xcode can see it just fine and my program links runs okay.

Also, it’s a framework already being used by our current product which is not Unity-based, so I’m certain it works in a “normal” Xcode project.

According to the link:
“Add framework search path.
You can now add third part framework to Xcode project. Add the .framework file to XUPorter’s iOS/ folder and add it to file section in projmods file.”

Here’s my projmods file:
{
“group”: “Frameworks”,
“libs”: [“libxml2.dylib”],
“frameworks”: [“Security.framework”, “QuartzCore.framework”,
“CFNetwork.framework”, “SystemConfiguration.framework”,
“ExternalAccessory.framework”, “CoreTelephony.framework”,
“CoreMotion.framework”, “CoreLocation.framework”,
“CoreFoundation.framework”, “CoreGraphics.framework”],
“headerpaths”: [ ],
“files”: [“MyFW.framework”],
“folders”: [ ],
“excludes”: [ ],
“linker_flags”: [ ]
}

The FIRST problem this causes is due to the fact MyFW framework as images in it. Unity tries to process them and they each generate this error:
“Could not create texture from Assets/Editor/XUPorter-master/Mods/iOS/MyFW.framework/Versions/Current/Resources/default_landscape@2x~ipad.png: File could not be read”

My build breaks because of these errors so it won’t even generate an Xcode project.

Any way to get around that?

I think this kind of scenario makes a good case for the tool pulling files such from a folder parallel to \Assets rather than down inside Editor\XUPorter*. You could enforce your rule of only copying things from within “XUPorter”, but just move “XUPorter’s” home directory to parallel to “Assets”. Just my $0.02 of course…

Hi there, First of all i’d like to appreciate your work regarding XUPorter but there seems to be an issue. i am unable to use it, as in, I am not ale to find this syntax anywhere in the project. Please help.

{
    "group": "KKKeychain",
    "libs": [],
    "frameworks": ["Security.framework"],
    "headerpaths": [],
    "files":   [],
    "folders": ["iOS/KKKeychain/"],    
    "excludes": ["^.*.meta$", "^.*.mdown$", "^.*.pdf$"],
    "linker_flags": []
}

I mean how do i handle it in x-code or unity. I’d really appreciate if anyone would have help me into this.
Thanks in Advance :slight_smile:

This is awesome, but I’m having some trouble figuring out the pattern for what I’m trying to do. I have an existing .xcodeproj that I need my Unity built proj to use as a dependency. My existing one compiles a few different .a’s, so I need it such that when I build through Unity my existing proj is in there as a dependency. I tried adding it as a file, but I only get the .xcodeproj file itself, though it seems to be empty. I tried adding the source folder, and it has all of the files, but XCode doesn’t recognize that it’s a dependent proj and shows the .xcodeproj file as just a folder in the dir. I’ve also tried adding the .xcodeproj as a folder and that has all of the .xcodeproj bits, but none of the actual files of that proj. Also, xcode thinks it’s simply a folder. I’ve tried adding it as a framework, but that did nothing at all. I tried adding it as a lib, but that had the same result as adding it as a file.

So, does XUPorter not support adding dependent .xcodeproj files?

Changing

[PostProcessBuild]

to

[PostProcessBuild(999)]

in XCodePostProcess.cs worked for me.

This is exactly what I was looking for … sadly I’m always getting an error when this bit of code is run:

Debug.Log( “Adding compiler flags…” );
foreach( string flag in mod.compiler_flags ) {
this.AddOtherCFlags( flag );
}

NullReferenceException: Object reference not set to an instance of an object
UnityEditor.XCodeEditor.XCProject.ApplyMod (UnityEditor.XCodeEditor.XCMod mod) (at Assets/Editor/XUPorter/XCProject.cs:594)
UnityEditor.XCodeEditor.XCProject.ApplyMod (System.String pbxmod) (at Assets/Editor/XUPorter/XCProject.cs:544)
XCodePostProcess.OnPostProcessBuild (BuildTarget target, System.String pathToBuiltProject) (at Assets/Editor/XUPorter/XCodePostProcess.cs:27)
UnityEditor.HostView:OnGUI()

My unity version is 4.3.3f1

Any ideas? :slight_smile:

Thanks!!

seb

Thanks for this! I needed a way to add an external set of resources to the XCode project automatically, and this worked perfectly.

Though, I did run into the problem mentioned by the above poster…

This turned out to be an easy fix, though. The script is looking for a “compiler_flags” field in the JSON file. None of the included examples have it in there, but you can add it in, like so:

"compiler_flags": []

And that should fix the null ref exception.