These days I had to convert the core of an iOS app to a framework that could be shared between projects. It was fairly simple considering the “new” framework products available in Xcode. I managed to build it with the desired public headers, copied it from the “Products” folder to the new project and everything flowed smoothly.
Then, in the last “funcional tests” to check that all gears were lubed, I tried running the new project against the iOS Simulator. Not surprisingly, Xcode complained that
symbol(s) not found for architecture x86_64. Building the framework against the simulator solved it, but, on the other side of the scale, I couldn’t run it against the devices anymore. Of course, I would have to build a fat library that supported both architectures.
After extensively searching, I finally found something worthy on this Ray Wenderlich article (where else?), but it still wasn’t quite what I expected. Aside the fact that it’s an article from 2013, it’s focused on creating an Static Library, and the solution is to create an Aggregate target with a build script. But I could work on that. It was feasible. This is the original script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
First of all, it wouldn’t work because I’m using workspaces instead of a
xcodeproj, partly because of Cocoapods. So using
xcodebuild -target wouldn’t cut. Secondly, I wanted this script to be run when I archive the framework project, so it’d be run with the correct configuration, the correct environment variables, etc, etc. Lastly, the script is actually redundant if you think of running it as I intended. You wouldn’t have to build the project again for the SDK
iphoneos. Archiving the target would already do that, so I would only have to build against the
iphonesimulator SDK and then combine the executables.
Having in mind that I wanted the universal build to be created when I archived the framework target, I edited my scheme and added the script as a “Run Script” phase in “Post-actions”:
Don’t forget to “Provide build settings from” the blurred framework!
So after fixing
xcodebuild’s parameters to work with workspaces (and running the correct scheme), now all I had to do was combine (
lipo) the product of the Archive with the product of the build I just did and, finally, export it to the correct location. This is the final script:
As you can see, on step 3 I move the universal build to the archive product path. So when I export the archive after Xcode’s Organizer shows up, the final product already has the universal build: