1

I'm seeking advice on how to share assets between 4 targets in my project: A.app, B.app, C.app, D.app


Approach 1 - Best case. I have attempted this unsuccessfully

  1. Create an Assets.bundle target.
  2. In the 'Run Script' phase, copy files from Assets.bundle into the *.app targets, like this:

    cd "${BUILT_PRODUCTS_DIR}" ls Assets.bundle | sed '/Info.plist/d' | xargs -t -I {} cp -r Assets.bundle/{} "${CONTENTS_FOLDER_PATH}/"

However when I run the app, the UI looks wrong. The .xib's gets loaded, but no images gets loaded! The image files and nib files seems to have been copied correct into the .app folder. My hypothesis is that a compiled .nib file assumes that it's located inside the Assets.bundle folder, thus explaining why it doesn't work when it's located outside the Assets.bundle folder.

Am I missing something in this approach?


Approach 2 - Untested

Make a Assets.xcconfig file that is #imported by the {A,B,C,D}.app targets.


Approach 3 - Untested

Mirror the 'Copy Bundle Resources' from the A.app target to the {B,C,D}.app targets

With a ruby script I can update the 'project.pbxproj' file.


Approach 4 - My current approach

Maintain 'Copy Bundle Resources' manually on {A,B,C,D}.app targets.

EDIT: I want to abandon this 'Target Membership' approach, because it's a big project and multiple people are contributing.


Approach 5 - Worst case

  1. Create an Assets.bundle target.
  2. Copy the Assets.bundle folder into the *.app targets.
  3. Change all [NSBundle mainBundle] code, so it uses the Assets.bundle instead.

In this project I have >1000 image files and >150 .xib files. There is much legacy code that uses hardcoded path lookups. Rework will take time. I have done this change on small project. This is a very elegant solution. However a rework of this size will take lots of time.

neoneye
  • 50,398
  • 25
  • 166
  • 151
  • Does 'Target Membership' not meet your needs? – Art Gillespie Dec 11 '12 at 10:18
  • @ArtGillespie 'Target Membership' is my current approach (Approach 4), which is too risky. A person on the team may forget to add an asset to one of the targets. I need to guarantee that the assets are the same across all the targets. – neoneye Dec 11 '12 at 10:52

2 Answers2

5

Why not just use XCode's integrated handling? Select an asset, select which targets it should be included with in the 'Target Membership' section in the utilities panel on the right. I use this to switch xibs, graphics etc. between free and paid versions, works great for this at least.

Forgot to mention: If you're including variants of files with the same name, to make it easier put them in a folder or bundle so you can separate them. Then add a define to the target with the bundle/folder name so you can automatically load them from any path.

psonice
  • 51
  • 2
  • This is my current approach (Approach 4). The project I'm working on is huge and we are a big team of people working on it. It's important that the assets are exactly the same. If one person on the team forgets to add an asset, then the apps may come out of sync. I would like to minimize this risk. – neoneye Dec 11 '12 at 10:49
  • This is a great solution for sharing assets across multiple targets in the same project (which is what the original poster was asking about). Unfortunately, it doesn't seem to work for targets in different projects within the same workspace, which is what I'm currently trying to do. – Greg Brown Dec 06 '16 at 14:06
2

I know is an old question, but I had the same problem so I discover a way to do this with the xcodeproj library. If you want you can check this at: https://github.com/dalu93/DLSharedBundleResources/

It takes two targets as params (one as "complete" target, the other one as "to-complete target") and it adds missing files. If you open the .rb file you find also a blacklist var where you can insert an array of file names that you want to exclude from the "merge".

I hope it helps you

Luca D'Alberti
  • 4,749
  • 3
  • 25
  • 45