In Xcode 5, I create a game demo using Xcode's 'Game Template', it links frameworks like this:
It use SpriteKit's code, but if I remove the SpriteKit.framework, it works too. I also use CoreMotion and find it not work without link CoreMotion Framework.
Then I create a game demo using Xcode 6, it doesn't link any framework now:
But it also works.
So there is no need to link frameworks?
I mainly using Xcode 5. Without linking how can I set it to 'Optional' to not crash on iOS6 ?
Okay, so this is basically a recollection from memory, correct me if I'm wrong.
Xcode can determine at compile time which (Apple) frameworks are referenced and links with them. It can also determine which other targets the main app target references.
However there's the possibility that this isn't quite true and since you've already built the project once with all the frameworks linked, the temporary build files make it so that the build with an empty Link Binaries list still works. To verify that, run a Product -> Clean in Xcode, then build & run again.
I'm not sure about using an optional framework. Either those frameworks are implicitly optional, or the whole point of adding them to the Link Binaries list is to be able to set them as optional.
A quick test with iOS 6.0 or earlier Simulator should help you find out which way it is.
Related
Our company wants to distribute a closed-source SDK for iOS to our clients. I've been using Cocoapods to build the framework and built an example app making use of it. Previously the app worked fine on the simulator as well as when deployed on the device. However, I was also embedding the Pods.framework file in the app itself. One other piece of information that may be of interest is that the framework is written in Swift, the included cocoapods dependencies are both Swift and Objective-C.
I wanted to make the pods requirements easier to manage so the user doesn't need to be concerned with them and tried to embed the Pods.framework file inside of the SDK we're building - so I removed the steps to Embed Pods Frameworks and Copy Pods Resources from the example app, leaving them only in the framework, I also removed Pods.framework as a dependency of the example app, leaving it only in the SDK. This seemed to work in the simulator, but the app now crashes on mobile device with dyld: Library not loaded error.
Upon researching it, I stumbled into a few related discussions:
https://github.com/CocoaPods/CocoaPods/issues/344 https://objectpartners.com/2014/06/25/developing-private-in-house-libraries-with-cocoapods/
However, the suggested solution of using private pods does not look like it would work for us, it's my understanding that the source code in the private pod would still be open, and we can't share it with our clients.
Could someone advise on a solution that would work in this case?
OK, I finally have a more durable solution. It's a modified, cleaner version of my old one now that I understand how Xcode links in my Swift sub-frameworks better
Problem that makes distribution/compilation a bit ugly:
Since Swift standard libraries aren't bundled on the device like Obj-C, nor are they guaranteed to be stable between versions yet (stable binary interface promised in Swift 3: https://github.com/apple/swift-evolution#development-major-version--swift-30) we have to make sure the entire project is compiled against the same version of Swift. That means the guy using your closed-source framework has to be using the same version of Swift in their Xcode for their project as you did for compiling the library, even if he's not using Swift in his code because ultimately it's his version of Swift that gets bundled into the app and your SDK runs against. This is only an issue for closed-source frameworks because open-source ones will always be compiled against the same version as final project. Possible workaround is to restrict clients to same version you use or distribute multiple compilations (i.e. Swift 2.1 and Swift 2.0). To remedy this, you could provide users with copies of binaries compiled against multiple versions of Swift.
Aside from that, here is what I had to do during compilation/distribution to make a binary framework that works in Swift:
When building the framework:
In project target, make sure to add Pods.framework to Linked Frameworks and Libraries (make sure this is a pre-compiled RED version of Pods.framework, I had a black compiled Pods.framework in the same directory which built fine but then resulted in a framework that would cause the project to complain about missing armv7 architecture during linker phase in later project)
In Build Settings, under User-Defined section, add a field called BITCODE_GENERATION_MODE and set it to bitcode
DO NOT #import any frameworks in your bridging header, all instructions telling you to do that are leftover from Swift 1.0-1.2 days, you don't need it anymore and it does more harm than good (the later project will complain that it can't find these headers that aren't even exposed to it)
Change build target to Generic iOS Device, Archive and Export the framework
When building the project using the framework:
Drag and drop the framework into the project, in General tab add it to Embedded Binaries and Linked Frameworks and Libraries (you only need to add the framework itself, not the sub-frameworks or the pods file)
In Build Settings tab, add a new path to Framework Search Paths: $(PROJECT_DIR)/MyFramework.framework/Frameworks
Build the project
I know of familiar tutorials on this, but introduction of framework XCode 6 template has changed the game.
I already watched WWDC 2014 video about building modern frameworks but it talks more about building extensions, framework & app all inside single project. It does not specify if the framework I make with it is truly reusable across any project.
I am building framework the XCode 6 way (File->New Project->Framework and Library->Cocoa Touch Framework), but when I import it inside my test app project (separate from framework project) - I keep getting various errors.
Example: Include of non-modular header inside framework, and so on.
I know this is not what it says, and there are quite some missing steps in whatever I am doing. The older tricks may have worked for everyone, but I simply don't find which way to follow after XCode 6.
For example, there is some folder structure that a framework needs, but XCode 6 doesn't comply to it while building it. Is it right? If not, how can I change the way the XCode builds framework folder hierarchy?
Do I go back to old school or am I screwing some tiny thing in XCode 6 that I am unable to create a reusable framework?
I am not sure if you are trying to build a framework with Objective-C or Swift as your question doesn't state it. I've encountered errors you are mentioning with Swift so I'll give you my method to build Swift frameworks.
I found the process for Objective-C to be very straightforward and well documented, so I'll skip this.
As for Swift, there are a few things to consider. First, Swift static libraries are not supported, so you must exclusively use a framework (aka dynamic library) when linking an app to a library.
Here are the steps:
Create the Framework using New > Project under IOS > Framework & Library, select Cocoa Touch Framework
To avoid the "ld: warning: directory not found for option..." goto Library Search Paths in Build Settings for your target and delete the paths.
You can't mix Objective-C with Swift so don't even consider adding the Swift-Header bridge file in your code.
There are some cases in swift where you need to import code from unexposed Frameworks. I've successfully used the module-map inside the framework to deal with these case.
I also select CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES in the Build Settings to solve 'include of non-modular header inside framework module'. That seems to work
I make sure that the header file that gets generated is marked as Public (not Project). Click on the file and you'll see the selection in the inspector under 'Target Membership'
You may run into some bizarre error messages when building. Xcode has a tendency to report linker errors when your code can't compile correctly resulting in missing files the linker needs to output its binaries. Sometimes XCode won't show the errors in the files you are compiling and you need to go manually on the build output and go back to the files. Some other time, you'll get a problem where you need to delete the cache. Those issues I call XCode blues and deal with it constantly. I found this type of problems happens more often when building libraries. The rest should work as expected.
Hi I'm trying to develop an iOS app with Vuforia SDK, but where I can find a way to start to integrate this SDK? I looked on the Vuforia web site, but there aren't any interesting documentation about how to integrate the SDK in my app? There's a tutorial that I can follow to understand how it works? On the official web site there are tutorial only for Unity, but I want to develop my app in Objective-C.
I hope you can help me
I realize this is a very old thread, but maybe you'll get an email ping, or perhaps a Google-er will find this useful.
So let me guess, you want to use one of Vuforia's sample apps, but in your own project, right? And you imported everything and made it look just like their project, but it won't even come close to compiling, right? And that sample app is almost certainly the SampleVideo example? If so, read on…
1) Xcode will get the import wrong if you simply include the library in your project. What you want to do is…
a) make a copy of the build folder inside the Vuforia API and put it somewhere else
b) rename that to something more useful, like "Vuforia"
c) use Add… to put that new folder into your own project (you can refer to it, I copy)
d) go to Build Settings, type "search" into the search bar (seems redundant, I know)
e) you should now see two very important lines, Header Search Paths and Library Search Paths. if you don't, you need to find them
f) double-click on header search paths so the pop-up gizmo appears. press the + button. Now go into the finder, find the Vuforia/include folder (which might be inside your own project if you copied it, like I do) and drag that folder into the pop-up gizmo
g) repeat for the Library, but drag the lib folder in instead.
Ok, done! No, sorry, I lied…
2) import the code from their samples that you want. It might be in several different folders
3) go to Build Phases and while that screen is up, do a build.
4) lots of errors will appear about ARC. use the search bar to find those files and add a "-fno-objc-arc" flag to each one. Repeat as required.
5) do another build, note that you're missing libraries which Vuforia couldn't be bothered to tell you about (sigh). So in Build Phases, open Link Binary With and add…
a) AVFoundation
b) AudioToolbox
c) QuartzCore
d) CoreMedia
e) CoreVideo
f) MediaPlayer
g) OpenGLES
h) CoreMotion
i) SystemConfiguration
6) do another build. Now you'll get a different error, but it won't be obvious it's different until you click on it. Look for "missing required architecture". If you see this, change your target to your phone, because Vuforia doesn't work in the simulator. Which makes sense because it doesn't have a camera… or not, because my apps do a lot more than just Vuforia but this limitation means I can't test any of it on the sim. (sigh)
7) so you switch the target to your shiny new iPhone 5S, build and… get errors about missing architectures. So now you see it's missing arm64… so you have to go to your Build Settings, remove Standard Architectures and add in armv7 and armv7s.
8) now you can look at the warnings and go about fixing the errors in their code, and the long-ago deprecated calls. naturalSize is easy:
AVURLAsset getting video size
One last warning. Once you get everything compiling and such, you'll try to import one of the Vuforia headers into your own code and then you'll get another error about "namespace". Make sure to change any file that imports from their code to a .mm as well.
Are you having fun yet?
I hope this link will be helpful for you, https://developer.vuforia.com/resources/dev-guide/step-2-installing-vuforia-sdk-ios
https://developer.vuforia.com/resources/dev-guide/getting-started-ios-native-sdk
Place your unarchived Vuforia sdk in your development
directory/folder.
Add libQCAR.a framework in your project.
Set libQCAR.a framework path in XCode build setting "Library Search Paths"
Set Vuforia header classes folder path from unarchived Vuforia sdk
in your development directory/folder in "Header Search Paths"
Today Vuforia 4.0 is simple. There is no need to "Add libQCAR.a framework in your project." and so on.
Take care of the path of folder in this image!!!
Step by step:
https://developer.vuforia.com/library/articles/Solution/Installing-the-Vuforia-iOS-SDK
https://developer.vuforia.com/library/articles/Solution/Installing-the-Vuforia-iOS-Samples
https://developer.vuforia.com/library/articles/Solution/Compiling-and-Running-a-Vuforia-iOS-Sample-App
For Vuforia 4.0 (currently in beta), Maury's answer didn't quite do it for me. I kept getting errors about "missing required architecture armv7s", even though I had set Architectures to armv7 / armv7s.
I then also to also change:
C++ Language Dialect in Build Settings to: C++ 11
C++ Standard Library in Build Settings to: libc++
After making the above changes my project built successfully.
So I have a big project (Let's call it A), and some guys with app B wanted to put part of my app in their app, so I created a framework to be added to their app. The steps of creating it were cleaning the code of my app leaving only what's related to what they want, Creating a framework from that, Creating an example app that uses the framework to debug and see that everything works. Until now in terms of frameworks what I did was that I just added to my Example App all the frameworks from my app (A).
Now I came to the point of cleaning out things and leftovers from the frameworks and the Example App, before I send it to B app guys. So I started to delete frameworks from my example app one by one, each time building and running on my device, and every time everything worked perfect. Every 2-3 frameworks I stopped to do deep build-clean, and deleted the app from my iphone, and still everything works. I ended up deleting specific framework that I specifically imported in one of my A app framework classes, still works. My last resort was to delete both UIKit AND Foundation frameworks. Still works perfectly. I did deep clean, uninstall from my iPhone, deleted the DerivedData folder contents, and restarted the computer, and everything still compiles, builds and works.
The only problem I started getting was that my Localytics session gave NSLogs about that the AdSupport framework is missing and that could harm the tracking... still no crash.
As far as I know i'm compiling the framework of my A app without any frameworks in it (Is it even possible to compile frameworks inside a framework?). My framework is built with this wonderful git: iOS Universal Framework Mk 8 (i'm creating a real framework not a fake one).
I basically care about all this because I do want to check out which of the frameworks are useless and can be deleted, and my project is too big to go over and check if and who is using any of the frameworks.
I'm using Xcode 5.0.1, ios7 SDK, iphone5c.
I did made sure all the frameworks I have deleted didn't stay in the Link binary with Libraries section...
These are the frameworks I have deleted from my Example App project:
CoreGraphics CFNetwork SystemConfiguration MobileCoreServices QuartzCore CoreData StoreKit AdSupport ( <-The only one I got any response to getting red of) AVFoundation CoreText XCTest UIKit Foundation
Thanks ahead for any help or idea (:
I know this thread is a bit old, but I just had the same problem and thought my answer could help someone else.
Somehow the TestFlight library I was using had all the required symbols within it. Removing libTestflight.a from my link step forced me to link UIKit/CoreGraphics again.
The process of going from code to binary with C is a multi-step one. Preprocess, compile, link, load.
Source (.c/.m) is preprocessed into a .i file (removes comments, evaluates macros, etc.).
Preprocessed code (.i) is lexed, parsed, and compiled into assembly (.s).
Assembly (.s) is compiled into machine code in an object or library file (.o/.so/.a).
Object files (.o/.a) are linked into a single binary.
At runtime, the system figures out which shared libraries (.so) the executable needs and loads them.
As you are building a library, your compilation stops after step 3, so you don't need to actually have the library binaries, you just need the header files to declare the functions (and any typedefs, structs, macros, etc.). The person using your library, however, will go through steps 4 and 5, and so will need the library binaries.
I have a C library whose code resides in say /repos1/clib. I build that from the command line using the latest iOS sdk to create clib.a (including a debug build for the simulator) which I copy to an iOS project say in /repos2/proj.
I have been using this setup for several years. The old C library very occasionally might require some debugging and I was pleased by the fact that Xcode simply stepped into the library code that was outside the project (inside repos1) without having to do any setup - it just worked.
But this was up until a few Xcode versions ago. I am not sure exactly when it changed - perhaps when they moved from gcc to llvm? - since I very seldom needed to debug the C code, but for a while now I only get dissasembly when I try to debug the C library from the iOS project (including at least references to the C file name & line number). For the few times I need to debug it is very inconvenient (I create a temp project that includes the C code).
So, any idea why it worked before and doesn't now? Where should I look? Could it be the way I build the C library, maybe there was a flag in gcc I was using that does not have an equivalent in llvm (I can find and post the old build command I was using if it is relevant)? Is the issue in Xcode and there is a way to tell it where to look for the sources?
Thanks!
Edit: To make it clear, I can add the C library either as the source or as a subproject in Xcode, however for reasons that are out of scope this is not helpful for this specific project. So, can it work like it used to with older Xcode versions? If not, it would still be interesting to know why not.
The recommended approach is to create a library project in Xcode, one for iOS (there is a template for it), then when you get that to build add that project to your app, make sure the lib is a dependency and gets linked. There are many tutorials on the web how to do this.
Then as iOS evolves and new architectures (armv7s) arrive you simply update both projects.
I was struggling with the same issue.
I tried resetting in library/application project all options related to symbol stripping and copy application project to same truecrypt drive as library project but it didn't help.
In my case it appeared it was an app project issue. Same library could be debugged in another app project with source code so that was a clue.
I had more than one version of the same library in app project and set only target membership to choose which should be used. Not sure if that could affect my app project somehow.
Nevertheless after deleting all libraries and copying them to app project again I was able to debug libraries with access to source code.