Add project dependencies in Xcode - ios

I am working with the AR Drone to develop new application.
I want to establish a dependency between two projects. So when I compile one, I hope Xcode will help compile the another one automatically. I had searched with Google for this question. The solutions found are quite old and not applicable for Xcode 4.
Right now, I have two project, namely, ARDroneEngine.xcodeproj and FreeFlight.xcodeproj.
ARDroneEngine is a library for FreeFlight. Here comes the screenshot.
If I compile FreeFlight with iPhone / iPad simulator, it is fine since the ARDroneEngine is last compiled with the same setting. This is where the question lies. To test my application, I want to compile and run FreeFlight in my iPhone. So when I change the setting to "FreeFlight > xxx's iPhone" and compile, the error occurs: "Apple Mach-O Linker Error".
I think the problem is rooted from the Target Dependencies between two projects.
A quick workaround will be: Compile the ARDroneEngine again with the new Scheme "ARDroneEngine > xxx's iPhone" and launch FreeFlight in Xcode for my iPhone.
But I want a more complete solution with the dependencies between projects. If more information is required to solve the problem, I can always provide new info.
Thanks,
Steven

Xcode's solution to cases like this is to use a Workspace that encompasses both projects: then, when one project has a target that references the build product of another, it automagically works out the dependencies and builds them in order.
Create a new Workspace (File > New > Workspace); name it and save it anywhere you like (though putting it in a parent folder to both project directories might be a good idea).
Add both projects (drag the xcodeproj files from the Finder into the navigator pane, or use File > Add Files).
Expand the Products group of your library project so you can see the (placeholder for the) built library (libARDroneEngine.a).
Select the app project (FreeFlight) in the navigator and its app target in the editor -- you should be looking at the Summary pane for the target (the one with bundle identifier, deployment info, entitlements, and most importantly, the "Linked Frameworks & Libraries" list).
Drag the library (libARDroneEngine.a) from the navigator (where you made it visible in step 3) into the Linked Frameworks & Libraries list.
That's it! Now you can choose the FreeFlight > xxx scheme and it'll automatically build the library project before building the app.
You can probably get a more complete summary of these instructions (with screenshots and all) in the Xcode help for Workspaces.

Related

XCode framework/library development workflow

I'm new to OSX/iOS development and I'm developing a library project (Cocoa Touch Framework) for iOS. While working on the library I would like to test changes to the code, but because it's a library, I can't run it straight away from XCode and view it's output. What I'm used to do in other platforms, (Windows for example) is to create a another project under the same solution (Visual Studio), add the library to this project and write my test code there. Unfortunately I didn't find a way to do something similar in XCode, my workflow now consists of quitting/opening two different projects, copying frameworks around and re-adding framework dependencies.
Surely there must be a better way to do this...
There are lots of post already in the SO .
But keeping it simple just follow these steps :
1.) Drag and drop Xcode project to your Xcode project 2.) go to build phase and then select your project (which u have imported ) to target. 3.) Search path - > user header search path (select your library) and also enter other linker flag.
Simple !
Is't exactly the same in Xcode :)
If you have a project (without a test build accompanying it) is:
1) See, no test Target :(
2) Click on the target that you want a test environment for (in my case, locates) so it's highlighted.
3) Click on the "edit" menu, then pop down to "Conver to" then "XCTest"
(yet another one of Apple's ambiguous places to hide things!)
Follow the wizard and that'll create you an XCTest build target that can be run on demand and through CI.
Have fun!

Xcode won't add "Embedded binary" after deleting "DerivedData"

Alternative titles to aid search:
Adding Embedded Binaries fails in Xcode
Xcode won't link framework from separate project
App crashes on device because of missing framework, works in simulator
Overview
After deleting the "DerivedData" folder (or performing a "Product > Clean") in xcode6, I cannot add CocoaTouch frameworks from another project to the "Embedded Binary" section (under General tab).
Or, Xcode hits a linker error because it cannot find a framework that if previously could.
Other symptoms
Clicking on the + under "Embedded Binaries" shows the Framework selector but selecting a framework in different project in the workspace does nothing.
When you add the framework to the Embedded Binaries, there will be a reference added to your project for it. If you select that reference after your steps above, you will probably find that it has an Absolute Path reference to the framework rather than a relative one, which we'd like. Change the location to Relative to Build Products and the reference should always be discoverable if do a "hard" clean or use another computer etc.
I have made a video which describes how best to add a built framework from one project to an app target in another sibling project.
This it the only way i have discovered to restore the embedded binaries, please leave comments if you find some steps are not required.
Prerequisites: Read Daniel Tull's answer.
Remove all framework projects from the workspace
Perform a "clean build" and/or remove the "DerivedData"
Add project back into the workspace
Build the project (possibly optional)
In the General tab of the app target click the + under "Linked Frameworks and Libraries", select the framework.
Build and run in the Simulator (there should be no issues building or running)
Build and run for device (this might cause a crash due to the framework not being correctly linked, ignore this crash)
Click the + under "Embedded Binaries", select the framework. This should add it to the project (possible duplicate under "Linked Frameworks and Libraries")
Repeat for all required frameworks
Once building and running (on device) is confirmed you can remove any duplicate (and/or red) frameworks in the Project Navigator or target General tab
Just to add to #Daniel's answer, if your Location dropdown is greyed out you may have selected the wrong file. Make sure to select the framework that's in your app project (not framework project).

Cannot add embedded binaries (other projects) to project dependencies in XCode

I have an XCode workspace created with XCode 6.0.1. It constains 2 (Swift) libraries and one iOS app (Swift) that depends on those 2 libraries. I had stable setup that allowed me to run the iOS app on both iPhone and simulators: The 2 library projects were added as Embedded Binaries (see picture) of the app.
Now, I have XCode 6.1. Recently, I deleted DerivedData folder in ~/Library/Developer/Xcode folder while XCode was running. After that my workspace did not work - the iOS app would fail to compile and I got linker error saying it cannot find the library projects.
I tried to solve it by removing my the 2 libraries from Embedded Binaries of the app project - and I cannot add them back. Clicking + button under Embedded Binaries in project settings displays workspace projects correctly but selecting and adding my library project does not add them to the list of Embedded Binaries. I have solved the linker error by creating new workspace. The app compiles but how it links the libraries is a mystery to me: They are not in listed Embedded Binaries or Linked Frameworks and Libraries not in the Frameworks search path. There appears to be no link between the app and the libraries it needs (and obviously have as it compiles) except that libraries projects are in the same workspace.
Why I cannot add library projects to Embedded Binaries? Is it normal in XCode 6.1 that dependency projects just compile and gets embedded into an app without being listed or linked anywhere?
This is a summary of my answer to the question Xcode won't add “Embedded binary” after deleting “DerivedData”, see the original question and answer for more context and information:
Remove all framework projects from the workspace
Perform a "clean build" and/or remove the "DerivedData"
Add project back into the workspace
Build the project (possibly optional)
In the General tab of the app target click the + under "Linked Frameworks and Libraries", select the framework.
Build and run in the Simulator (there should be no issues building or running)
Build and run for device (this might cause a crash due to the framework not being correctly linked, ignore this crash)
Click the + under "Embedded Binaries", select the framework. This should add it to the project (possible duplicate under "Linked Frameworks and Libraries")
Repeat for all required frameworks
Once building and running (on device) is confirmed you can remove any duplicate (and/or red) frameworks in the Project Navigator or target General tab
Ok, I ran into the same problem as you. After deleting the derived data, I could not re-link my binaries again. I think the reason is because the derived data is where the binaries are written to and linked against in your project.
What I did to solve was to select my Framework as my build target. After building it, the Framework target turned from red to black. I can see in your screenshot it is red, meaning it has not been compiled into a binary and written on disk.
Once I did this, I was able to re-link the Framework to my Project because there was a reference to it on disk. Hope this helps!
Clean your projects & build your framework first. Thereafter you can embed it.
Here is how I solved the problem:
Build the framwork.
Open the build folder and drag built framework into the app project (so it uses the path to DerivedData).
Add the framework to the list of embedded frameworks.
In the Finder, do a Show Contents on the app's xcodeproj file, then open project.pbxproj in your favorite text editor.
Find the line with the long DerivedData path. Change it so there is no name, the path is the framework name, and source tree is BUILT_PRODUCTS_DIR
Xcode should notice the change and the library in the app project will be black instead of red and will now build and run properly.
I have a very similar issue and fixed it just last night. Decided to come back to this thread and offer my workaround, as rjstelling's solution above did not help my case.
I have a workspace that contains two frameworks and one application. The App was making use of both frameworks happily for a while until I got hit by a mysterious compile eror where it decided that adding a property access to an instance variable called "cube" of a class type found in one of the framework, made access to "_cube" impossible (complaining it was not declared, while it had actually worked previously in a setter method).
Long story short, after a clean, somehow the workspace/app project lost track of the embedded framework of my iOS 8+ project. Removing the embedded framework was the last straw in that line of failure, causing my project to no longer allow be to select any frameworks for embedding.
Reverting the project & workspace to an earlier version did not get rid of the voodoo.
I ended up adding the to-be-embeded framework projects in the main app project (as files) and introduced target dependencies on the frameworks.
I was then able to re-embed the frameworks and link.
As for the _cube thing, I had to specify a getter for the property and #synthesize the property to a different name. I dont have an explanation for this one.
It's probably because your framework is a separate project and not a separate target. Try watching carefully Session 416: Building a Modern Framework at around minutes 34-36. It will show you how to set it up correctly.
This makes it a bit confusing if you wanted to share a framework across multiple projects by the way

Swift iOS module not being deployed to expected debug directory

I have a module/framework written in Swift, intended to be used on iOS. When I try to include the framework in my app, I first notice some red "not found" hints in the build phases:
But, the project builds fine - the target dependency is found, so there are no compilation issues. It's just the resulting built framework - and sure enough, upon launching, I have a linker error, it can't find the image. Looking at the build log, it's looking here:
/Users/Craig/Projects/Fluffy/build/Debug-iphoneos/
Which makes sense - that's what is defined in the Build Settings for my framework:
But the copy fails, as the source framework doesn't exist:
PBXCp /Users/Craig/projects/Fluffy/build/Debug-iphoneos/Fluffy_iOS.framework /Users/Craig/Library/Developer/Xcode/DerivedData/MyApp-dcjfhcnyzkwzxiejuuxqlsgajreb/Build/Products/Debug-iphoneos/MyApp/Frameworks/Fluffy_iOS.framework
...
error: /Users/Craig/projects/Fluffy/build/Debug-iphoneos/Fluffy_iOS.framework: No such file or directory
However, looking at the build log for my framework, I see that it's actually ending up here:
/Users/Craig/Library/Developer/Xcode/DerivedData/Fluffy-fuuewsvogdkycegheyrsabkiicxc/Build/Products/Debug-iphonesimulator/Fluffy_iOS.framework
I suppose that makes sense - DerivedData has for a while now been the default location for any built products.
And when I take a look at the expected build folder, there's not much, a lot of it is old, and none of it relates to the Debug configuration:
So my questions are: Why is my framework being placed in the DerivedData folder, when it seems to be asking in the Build Settings to be placed in the build folder relative to the project? Are these parameters (per-configuration build products path, etc.) consulted at all?
And, what should I do to reconcile this? How can my application know to look in the right DerivedData folder for the framework, for the right configuration (debug vs. release) in a way that is extensible and will work without me having to manually specify the absolute path to it?
Okay, so I figured out how to work around this. This assumes you have workspace and you have included the framework as a project in the workspace and you are trying to build a product from another project in the workspace which includes the framework.
What you need to do is find out where the framework is being built. It's usually some crazy directory under the DeriveData directory. Go to the Finder and find it for the configuration you just tried to build.
In the product target's General settings, under Embedded Binaries, drag that file into it. This should now place it in the Project Navigator. You should also see it in the Linked Frameworks and Libraries which was underneath Embedded Binaries.
Go to the Project Navigator and select the file and view it under the File Inspector. There, change the Location to Relative to Build Products.
In the target's Build Settings, for Framework Search Paths, add $(BUILT_PRODUCTS_DIR) and make that recursive. Delete the entry that was automatically added when you added the framework. It will be an explicit path which has the DerivedData path in it.
Do a deep clean and delete the DerivedData directory for good measure.
Build.
You should now see the framework turn black and it should work properly.
These are slightly modified steps provided by #Mobile Ben
Assume, you have the following Xcode project structure
-YourWorkspace
--YourFramework project
--YourApp project
step 1. Clear all the targets with Cmd+Shift+K and Cmd+Option+Shift+K (by choosing each of them in the Scheme selector and pressing the hotkey combination)
step 2. Select YourFramework project.
step 3. Choose a simulator and build (Cmd+B) YourFramework framework target
step 4: Choose Generic iOS Device and build (Cmd+B) YourFramework framework target
step 5: Select YourApp project. Press + in Embedded Binaries and choose the framework under YourFramework project
step 6: now locate the just added framework in Project Navigator (on the left). In File Inspector (on the right) select location Relative to build product.
NOTE: I believe the step 6 is required b/c of some bug in Xcode. But, though, not selecting Relative to build product by default might be a deliberate act
UPD#1: Since Xcode 8.0 (8A218a), step 6 is not needed anymore - the IDE sets Relative to Build Products automatically.
In addition to the above answer which works perfectly on Simulator. On device you will get dyld library not found error and a crash.
Here is the solution for that:
In the project that depends on this framework:
Under the build settings: Add a copy files phase and add this framework to the 'Frameworks' folder in copy file phase.

Xcode 6: No Frameworks Folder in Project Navigator

I am using Xcode 6 and following an Xcode version 4 tutorial so things are different here and there.
There doesn't seem to be a Frameworks folder in my project navigator and so when I downloaded some .framework files and added them manually in the build phase of my project editor, I had no Frameworks folder to save them in and just let them fall into the top of my project navigator. So they are there, just not in a special folder, and it doesn't look good.
So should Xcode 6 have a frameworks folder automatically, or do I need to create one myself? And if so, how can I do that? (I've only added new files so far).
In Xcode 6, the Frameworks folder is not added by default. You can drag and drop your .framework files into the project navigator (tick 'Copy items if needed'), then select them all > right click > "New Group from Selection" and name the folder 'Frameworks'.
Also, make sure the frameworks are added into the Project > Build Phases > Link Binary With Libraries. If not, drag them there from your newly created 'Frameworks' folder.
In short, no, you shouldn't need to create a Frameworks group yourself as Xcode is doing stuff automatically for you...
Apple are slowly, gently pushing developers in the direction of newer Clang features with the goal of making native iOS development more approachable for newbies who don't have previous experience of compiling and linking with C-based languages.
You'll find that Objective-C projects created with Xcode 6 have new build settings enabled by default including Link Frameworks Automatically (CLANG_MODULES_AUTOLINK) and Enable Modules (C and Objective-C) (CLANG_ENABLE_MODULES).
Suggested reading:
Modules (Clang documentation)
#import vs #import - iOS 7 (excellent Stack Overflow answer)
I found the other answers too confusing (where am I supposed to get .framework files?)
It's way simpler in Xcode 6. Just go to Capabilities and turn Maps on. That's it... really.
I would recommend using drag and drop feature to move files into Xcode. Xcode show you the Choose options for adding these files window [Copy items if needed] [Added folders]
For example Xcode can automatically add relative path ($(PROJECT_DIR)/) to:
Build Settings -> Library Search Paths if you drag and drop a library
Build Settings -> Framework Search Paths if you drag and drop a framework

Resources