31

[UPDATE 03/04/2015]

The question is now 4 years old, and applies to a specific version of XCode which I have now specified in the subject.


I have searched a lot for this argument, but I couldn't find a solution, I even post on stackoverflow, but I soon deleted the question becuase of very little access. Now I am trying again.

I have a workspace with two distinct projects A and B.

B has two targets, one that build a static library Blib.a, and one that build a bundle B.bundle. All of them get built in the derived directory.

In project A I can easily add the static library from the build phases. However I cannot find a way to include the bundle. B.bundle is not visible from "copy resource" tab in A. Therefore I need to add manually, with all that implies. I also thought about using a script, but I would like to use this as a very last option.

Has someone a solution for this ? Did I miss something ?

thanks

Leonardo
  • 9,607
  • 17
  • 49
  • 89

6 Answers6

19

After long investigation, it came up there's no easy way of doing this. The B.bundle is never visible to A project, and there's no settings in workspace to change that. At this point there are three solutions:

  • Include the bundle manually from "copy resources->other", I started with this, but everytime there's a change you have to drop and include the bundle again
  • Create a script to be run in build phase, if everything is built into the PRODUCTS dir you can find the bundle easily and having copied automatically into the app.bundle. This is not a bad solution. If you are using svn the script got included in project, and users have it for free without additional work.
  • As suggested by Apple tech support, use folder references.Build bundle B into a folder and add such folder to project A using the "Create Folder References for any added folders" option. Xcode 4 will update your bundle into that folder every time you built it. The added folder will appear as blue once included in your project A.

Thats's it, I personally use the script, because this solution is path independent if you use standard xcode reference variable such as BUILT_PRODUCTS_DIR and so on, and the shell script is just a cp -r-f

[UPDATE 03/04/2015]

I would like to point out that the question is now 4 years old. At that time there weren't many "official" options available. I even spoke with Apple Tech Support, which proposed solution 3 as the only available solution. It is of course very likely that things are now changed, and there is a much better solution. Just to speak, I also like to add that the three above are not "hacks" but "solutions", maybe technically outdated, but they can still be used nowadays. I intend a "hack" as a..."hack", which means it probably not going to work in future software release.

kbpontius
  • 3,867
  • 1
  • 30
  • 34
Leonardo
  • 9,607
  • 17
  • 49
  • 89
  • 3
    Hint: I used something like `cp -R -f $BUILT_PRODUCTS_DIR/MyBundle.bundle $BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/` and it works just fine. – mmilo Oct 17 '12 at 21:24
  • 1
    Because my CONTENTS_FOLDER_PATH contains a space, I had to use "$CODESIGNING_FOLDER_PATH" instead. But thanks for the tip, @mmilo – Jon Reid Mar 02 '13 at 03:34
  • 3
    It is important to use the `-L` option when using the `cp` command to ensure that the symbolic links are followed. Otherwise, when you attempt to archive your binary, you will fail validation and your *.bundle resource will not be available in *.app file. Example:`cp -R -L -f $BUILT_PRODUCTS_DIR/resource.bundle $BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/` – TPoschel Mar 15 '13 at 14:04
  • check out [@0xced's solution below](http://stackoverflow.com/questions/6690080/how-to-include-a-bundle-in-main-project-xcode-4/29170653#29170653). I had the exact same issue as OP and was able to solve it the way he suggested, which doesn't require either of the three hacks that you propose – Ilias Karim Apr 03 '15 at 08:59
  • The question is now 4 years old, at that time with XCode 4 the above were the only solutions available. – Leonardo Apr 03 '15 at 12:14
8

Here is how I did it.

  1. Drag and drop B.bundle from Project B → Products → B.bundle into the Copy Bundle Resources build phase of your app in Project A (select the Create groups options when asked). This will add B.bundle at the root of your Project A outline. You can move it into the Frameworks directory near Blib.a if it you prefer.

  2. Select B.bundle and check its Location in the Identity and Type right panel (Utilities area). By default, Xcode chooses Relative to Project. This is wrong, select Relative to Build Products instead.

  3. The path to B.bundle will now look something like ../../../../../../../../Projects/MyApp/B.bundle. This is not what you want, but you can easily fix it. Open ProjectA.xcodeproj/project.pbxproj in a text editor, search for this path and delete everything in it except for B.bundle. Your project.pbxproj should look like this:

    explicitFileType = wrapper.cfbundle; name = B.bundle; path = "B.bundle"; sourceTree = BUILT_PRODUCTS_DIR; };
    
  4. Save your project.pbxproj file. Xcode will automatically reload your project and your app should build just fine.

0xced
  • 25,219
  • 10
  • 103
  • 255
  • 1
    cheers @0xced, this is a much preferable solution to the accepted answer, and your instructions are extremely clear and clever at working around what it would seem to be is an Xcode bug (or at least misconfiguration) – Ilias Karim Apr 03 '15 at 08:58
  • but how does one add the bundle target as a dependency of the main project target? I am having to manually build it before building the main project target. the only better way I have found to add it as a dependency is by nesting the two projects, but I'm unable to add the bundle target as a dependency of the main project target when the two projects are siblings in a workspace – Ilias Karim Apr 04 '15 at 00:40
  • The static library (Blib.a) has a dependency on the resource bundle (B.bundle). Since the static library is linked by the app (implicit dependency), the resource bundle is built automatically. Schematically: Project A → Blib.a → B.bundle. – 0xced Apr 09 '15 at 12:14
  • 1
    Nice solution! For me (Xcode 7, project B as a subproject of A) B.bundle didn't even appear in the root of project A, and the option "relative to build products" was chosen by default, so steps 2-4 were not even necessary! – Erik Verboom Dec 28 '15 at 15:38
4

After searching for a long time and failing many times, I found this resource that has been an absolutely great tutorial to create Static Libraries and include bundles in your main project or even for distribution to 3rd party developers that may consume your library.

Absolutely recommended:

https://github.com/jverkoey/iOS-Framework

agarcian
  • 3,909
  • 3
  • 33
  • 55
  • The question is about sharing bundle across projects in the same workspace. – akshay1188 Feb 28 '14 at 07:30
  • If you follow the instructions presented in the project, it shows you how to create a target that contains a bundle and that accomplishes exactly that. You can share the bundle on the same workspace, or better, you can also share it with other projects. – agarcian Feb 28 '14 at 20:41
1

As of Xcode 5.1.1 I was able to drag and drop B.bundle from the Project Navigator to the Copy Bundle Resources list of project A Build Phases. I assume creating B.bundle target is not an issue.

1

In project A, is the product of project B a dependency in your scheme's Build action? I think you might have to set up this dependency (sometimes disabling the automatic dependency discovery option is best) for it to show up and be available for copying into another target. I believe this is because it doesn't really exist (like an image resource file) until it's built and Xcode needs to ensure it's built before working with it from another target.

Joshua Nozzi
  • 60,946
  • 14
  • 140
  • 135
  • Hi again :-) unfortunately I have checked, and A has a correct dependency to B. It looks strange that in copy resources phase, only project A folder is seen by xcode. Why is not showing all the content of the workspace ? – Leonardo Aug 03 '11 at 18:43
0
  1. Switch build to Generic iOS Device. This step is needed to create a non-simulator reference.
  2. Drag the .bundle to the other project's Copy Bundle Resources.
  3. Select the .bundle in the Project navigator of the other project, and change its Location to Relative to Build Products

Make sure your .bundle in added to Target Dependencies of your static library

vadimtrifonov
  • 818
  • 8
  • 7