Internal Linking of Cocoa Frameworks - xcode

In my open-source Cocoa project, I have two Xcode projects -- one framework and one application. I want to link the framework in the application, and whenever I build the framework, I want the linked framework in the application to be updated automatically as well.
What is the correct way to set this up, especially so that someone else who clones my project can easily build both the framework and the application?

Drag the Framework project into the App project's source list (on the left). I make a "Projects" folder in the source list for that exact purpose.
Then, you can simply select your App Target, Get Info, and add the Framework as a Direct Dependency.
Now, whenever you build your App, your Framework will be built as well.
It's recommended to use a common Build Folder as well (Xcode->Preferences->Building) to help with linking.

Related

Regenerate XCFramework if there is a code change

I have a Demo project and Framework which can be integrated with multiple ways(Cocoapods, SPM - using generated XCFramework, directly integrate with XCFramework)
For distributing Demo app to external users we integrate the Framework with SPM.
Problem with this approch is during development its makes really hard to regenerate XCFramework after each change, so I have decided to drag and drop the Framework's project to Demo app, but cant understand how to recompile XCFramework if there is a change.
Could you please help me with understading how to handle this scenario.
Create an .xcworkspace that contains the framework project and the demo app project side by side, then inside the demo app target General settings (see screenshot), add the .framework file from the framework project within the workspace instead of depending on the .xcframework binary file directly.
After that, add a "Copy File" build phase that embeds the framework file.

Xcode: how to work with library/framework conveniently while keeping code private towards others?

I have been following this tutorial: https://medium.com/better-programming/create-swift-5-static-library-f1c7a1be3e45
However, it is inconvenient to copy the new .a file every time I make a change to the library. What is the common setup during development of the static library? Do a "copy to iOS project folder" in the build script or linking the frameworks "Products" folder in the iOS project etc.?
During development, Subprojects seem to be a really useful way (https://www.raywenderlich.com/2658-creating-a-static-library-in-ios-tutorial). However, copying the project to another computer renders it useless as it seems to rely on the Subproject and not e.g. cache the data from the last build.
The background is that I want to work with a client that I don't want to give access to my private API.
I am looking for a solution that lets me
work on the project as well as the library conveniently (either by submodules or by having opened 2 Xcode windows at the time)
commit changes to the Git repo (via the Xcode Source Control) and automatically have the compiled framework being pushed, too
have my be able client to use my Project and work on the Project but only has access to the compiled library so he can't see what's inside it

Build static library Target with main Target for proper architecture in XCode?

I am currently developing an iPhone app in XCode that requires a static library that is built from another XCode project I have made. I currently have both targets in the same project, and I need the static library project to build and run for the proper architecture when I build the project that uses it.
As of now I have to open the static library project on its own, build it from there, find where it was built, and then remove the old library and add the new one to my project that uses it.
How do I do this?
The solution lies within the idea of workspaces. This s.o. thread might also be helpful. I think the general layout youll want to create is a new workspace where you will add both projects, the client and the library, that way they are both within reach.
Best of luck!

Xcode: How to use separate Projects with cross-project references to embed a framework in your application?

I am using Xcode 4.3.
I have an existing Xcode Project (originally created in Xcode 3) for a embeddable Mac OS X Framework. This Project has a few Targets, but the primary Target in this project is for my Framework. This Framework is designed to be embedded in Mac Apps and has the appropriate Installation Directory properties set. (#executable_path/../Frameworks)
I have a new Xcode Project (created just now in Xcode 4) for a Mac OS X Application. There is only a single Mac App Target in this Project.
I would like to combine my old Framework Project and/or Target into the new App Project so that I can build both the App and Framework from source in a single, combined build process. (I have done this in Xcode 3 many times, but cannot figure it out in Xcode 4).
I do not (unless it's the only way) want to build my Framework separately and then just link to it from my App Project. I want to combine the Framework Target into my Mac App Project.
Here's Apple's outdated documentation describing how to do what I want in Xcode 3:
Embedding a Private Framework in Your Application Bundle > Using Separate Xcode Projects For Each Target
How do you do this in Xcode 4?
Note: I just need to know how to add my Framework Target to the new Project. From there, I know how to add the dependencies and do all the Build Phases of linking and copying the built Framework into the app bundle.
After working through a tricky issue in Xcode 4.3.1, I discovered how to do this. I've given a full/detailed example in my answer to another question about how to embed ParseKit in a Mac App.
I also found excellent information on the topic in Chapter 16 of Mastering Xcode 4 by Joshua Nozzi.
You actually have 2 separate Xcode project files here: Application and Framework. The answer is the section below the one you find: Using Separate Xcode Projects For Each Target
Edit:
OK. Now I remember. You need to create a workspace and add both projects to it. Then you can add target in one project to the other for dependency: Adding an Existing Project to a Workspace
I don't have all the details since I don't have a Mac now. But I think you can figure it out once you created the workspace.

How should I manage dependencies across projects in an Xcode workspace?

I'm working on an iOS app project, and add the json-framework project to the workspace. The project navigator on the left shows both projects, and the build scheme selector shows the schemes from both projects too. Now I want to add the libjson.a target from the json-framework project as a dependency on the iOS app target in the other project. The expected result is that whenever the app target is built, it builds (if necessary) the library target and links the app target against it. Here are the ways I've tried to do this:
Build both as part of the same scheme. The way I try this is to edit the scheme for my app, adding 'libjson.a' to the 'Build' portion of the scheme, and by the way "Find Implicit Dependencies" is checked. Then I go to the target editor for my app target, and in "Build Phases"->"Link Binary With Libraries", I choose 'libjson.a' from the list of workspace libraries.
When I subsequently try to build the scheme, I see it build the library target, but building the app target fails with linker error "Library not found for -ljson" - suggesting that it hasn't actually discovered that the library has been built. Indeed in the project navigator, the entry under the app project for the library is still red indicating that the file doesn't exist.
Add the json target as an explicit dependency. To try this, I don't modify the build scheme, but go to the target editor for my app target and click the add button under 'Target Dependencies'. No targets from other projects in the workspace show up, so this is a non-starter.
Drag the JSON project into the other project, then add the target as a dependency. This is what I would have done in Xcode 3. In the project navigator, I grab the library project and drag it over the app project. This brings up the usual 'add files' pane, which I just dismiss by clicking 'Finish'.
There are now two entries for the library project in the project navigator: one at the top level, and one under the app project. I can now add the library target as a dependency of the app target using the target editor, and can link against it without error in the link libraries phase. But it looks broken: there are multiple entries for the same project in the navigator. Is there a different way to do this?
What should be considered the "Xcode 4-ish" way of connecting these targets in different projects in the same workspace? It would seem lacking if multiple projects in the same workspace can't actually interact with each other.
Thanks,
Graham.
I’ve just set a test project up, pretty much as you describe in version 3, by creating a new workspace and dragging the two Xcode project into it, nested as shown.
You can delete the sibling project if you have it already.
Hitting build on this and it just works, as far as I can see.
I imagine there is internal path-confusion if you have two projects, and I’d be inclined to fiddle with location settings in "View"->"Utilities"->"File Inspector" and see what effect that has.
Another thing to try is to set your paths up in Xcode "Preferences…"->"Source Trees" and refer to them that way, as described here: Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and Cross-Project References
HTH. Andy W.
I managed to get dependencies between projects in a workspace to work as I described here: http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/.
Unfortunately I can't find a way to get Xcode to discover implicit dependencies or index everything in the build as advertised. I found workaround to both but I'm hoping that less manual configuration will be needed as Xcode 4 matures.
I was going to ask the same question, thinking that my own solution couldn't be right. But I don't see it mentioned here, and it does seem to work. Clearly XCode 4 is a work in progress. :)
I have a workspace with two projects: a static library and an app which uses the library. The projects are siblings. Each project has its own scheme, and each scheme is set to only build one target. In other words, I added two projects to the workspace and that's it.
To add the static library as a dependency of the app, I just drag the libsomething.a product from the library project (Project Navigator) into the "Link Binary with Libraries" list for the app target. That's it. Now when I build the app the library project is built first and then linked. Interestingly, when I modify the app's scheme to use a different configuration (eg, Release instead of Debug), the library is built using the same configuration.
So it works, and there is clearly some automatic dependency checking going on here. But it feels wrong. Then again, so does the modal scheme editor/manager and lack of a workspace object in the project navigator... I never thought I'd say it, but the Visual Studio UI (bleh) is a lot clearer.
My bullet-proof solution to do this :
Create "Per Debug-Release / Per Architecture" settings in Build Settings in the Main project (not the lib), to include either
../MyLibProject/build/Debug-iphoneos
or
../MyLibProject/build/Release-iphonesimulator
or
etc..
depending on the configuration (you can create those kind of configuration by clicking on the + next to Debug or Release and choose either "Any iOS Simulator SDK" or "any iOS SDK".
You need to do that for both "Header Search Path" (in case your library copy some headers files, which is more than likely) AND for "Library Search Paths". Which means that for each setting, you'll probably end-up with 4 different paths (debug sim , debug ios, release sim, release ios).
That would make sure the configuration of both projects match.
Now, to auto-compile the lib, that is to create the dependency, you can use the "Build Phase -> Link to Binary With Libraries -> + -> select the .a file" advice given above.
That's the only way I managed to have something that builds and link correctly for every environment on xcode 4.5
Note : I even added the -lmyLib flag in "other linker flags", but i'm not sure that's really necessary
I've had some success with creating framework-like static libraries, though it's not a perfect solution.
I see the next variants:
Explicit dependency in a project[About]
Implicit dependency in a workspace[About]
See the Xcode user guide: Xcode Concepts -> Xcode workspace under 'Projects in a Workspace Share a Build Directory'.
All projects in a single workspace share a build directory. Dependencies are discovered automatically and build if needed:
"Xcode examines the files in the build directory to discover implicit dependencies. For example, if one project included in a workspace builds a library that is linked against by another project in the same workspace, Xcode automatically builds the library before building the other project, even if the build configuration does not make this dependency explicit. You can override such implicit dependencies with explicit build settings if necessary. For explicit dependencies, you must create project references."

Resources