Missing framework is red and project still builds - ios

I have a missing framework shown in red in a pod project. The project still builds for running when selecting "Generic iOS Device". However, if I remove the red framework then the project stops building and Xcode reports "Undefined symbols for architecture arm64:" and a big list of symbols not being found by the linker. This is the library which I understand from this SO post has been deprecated and is no longer included in Xcode as of Xcode 10.
I'm currently downloading Xcode 9.4.1 so that I can get the old libraries, but I'm unclear why I can even build successfully when this library is red. Again if I remove it it won't build. As a related aside, the project is already set to use libc++ rather than libstdc++.
Ideas?

The solution is to delete the libstdc++.tbd, then under Xcode's general tab, Linked Frameworks and Libraries, add libc++.tbd. Also, under the Build Settings tab, C++ Standard Library should be set as libc++. In my project the C++ Standard Library was already set to libc++.
Since as of Xcode 10 libstdc++.tbd is not available it was shown in red. The calls to the standard library I think are now linked via libc++.tbd.
This other SO posts discusses the tbd files

Related

Embedding frameworks inside closed-source Swift framework

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

Building a Swift Framework with Xcode 7 (Beta 3) to use as an Embedded Binary

Ever since Embedded Binaries were introduced in iOS 8, I have been wanting to port a lot of my common code into frameworks. I decided to wait one year before doing it and this year, with Xcode 7 Beta and iOS 9, I'm starting to do that just that.
I have started a Cocoa Touch framework project in Xcode 7 and I want to compile it into a usable framework. I can get it to compile my project into a .framework, but there's a few issues; namely, the framework doesn't appear to be importable into new projects (I will describe the steps I did for that shortly). Because of that, I'm not sure if my framework has any visible symbols.
This is what I have done to create the Framework:
Created my Framework as a Cocoa Touch Framework.
Went to my target's Build Phases, went to Headers, and added all my Swift files to the "Public" section, in hopes that will export all my simbols without having to mark them as public.
I tried to archive my project as a framework. Currently, it looks like Xcode 7 Beta 3 has a bug (going to report it later today) in which it generates corrupted archive files. For this reason I couldn't get my framework from the Organizer Window. To work around this, I changed the schema of the Run action in Xcode from Debug to Release, built it and grabbed it's generated .framework from my project's build/iphoneos-release directory. This was a quick test so I didn't need the frameworks generated for emulators.
And this is what I did to try to add the framework to a new project:
Created a "Frameworks" group (for organizational purposes) and dragged the framework there, selecting "yes" when it asked me if I want to copy the file to my project's directory.
Went to my target's settings, removed my framework from "Linked Libraries" (it was added there automatically), added it to Embedded Binaries instead. This added the framework to Linked Libraries again, so I had to remove it from there twice. Leaving the framework in Linked Libraries causes a linker error (can't find the framework - no idea why but I think it's irrelevant to my problem and something I should report to Apple as well), but once you remove it from there it seems to compile fine when you add it to Embedded Binaries.
Tried to import my framework in a file. Xcode complains there is "no such module".
Unfortunately, despite the fact that embedded frameworks have been around for around a year, I can't find much writing on the topic.
So my question is: Am I creating the framework correctly, making it possible that my framework/anything else is failing due to an Xcode 7 Beta bug? Or is there a different procedure to create a framework that I want to use as an Embedded Binary? I should probably mention that I want to make this library open source, and I think distributing a plain .framework file to the people who want to use it would be neat.
I Had the same issue on Xcode 7.
I solved it by editing the build settings of the project (the one which includes the framework).
By setting the Framework Search Paths field to $(PROJECT_DIR) or to the path to the directory that contains the .framework file it should help Xcode finding the module.

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

zxing in xcode 4.5 and ios 6

As many of you noticed; zxing does not work in latest xcode (4.5/ios 6)
Here is use case:
checkout latest version from trunk (as some fixes were already added)
create single view application in xcode 4.5 with ios 6.0
use README to add dependencies, paths etc (just follow step by step)
add zxingcontroller call to class (renamed to mm)
Compilation fails both for simulator and device
It shows 31 error like this one:
Undefined symbols for architecture i386:
"std::string::c_str() const", referenced from
all 31 errors are similar, difference is in symbols name
May be somebody knows how to solve it with this use case?
p.s. if you have app from previous Xcode, it works. Problem is only if you create new app in Xcode 4.5
The issue you have encountered seems to be C++ standard library related.
Actually, whenever you see linker failures in relationship with standard library objects (e.g. std::string), you should check the project settings on all linked libraries and the app-project itself. They usually need to match!
The original ScanTest (which builds ZXingWidget as a subproject) uses the following settings and those need to match your App build-settings if you use the library as is.
For making sure, I created a brand-new project using Xcode 4.5. That project uses ZXingWidget as a prebuilt library but not as a subproject - I dont like subprojects for stuff that is not my own - though this specialty wont influence the results.
The important setting is C++ Standard Library - make sure that is set towards Compiler Default
Little clarification
Actually, you do not need to use C++ Standard Library, you may as well use LLVM C++ standard library with C++11 support. But you will have to use that exact same library in all projects, sub-projects and libraries that link with your project. So if you insist on using the more recent version of that library (C++11 support), then you will have to build the ZXing library with those settings as well.
Last but not least, make sure your Architectures and Valid Architecture settings are matching over all projects and sub projects (fixing the common armv7s linker issue).
First, make sure your Architectures setting is set towards armv7 armv7s within all projects. Then also edit the project settings of all projects towards Valid Architecture armv7s armv7.
You might also want to switch the "Other Warning Flag" -Werror off. Seems to be necessary in Xcode versions > 4.5 (LLVM compiler > 4.1).
It works for me, have you enabled -lstdc++ in your list of Other Linker Flags in the Build Settings tab of the project target? It sounds like it is not recognizing the c++ symbols needed for zXing to build. If this is the case, the above advice should help.

iOS framework project breakpoints not working

I've created an iOS framework project using the famous (and excellent) iOS Universal Framework Xcode template.
But now I've encountered an annoying problem that I can't seem to fix which is that I have an iOS application project that references the framework project and when I run that and have breakpoints set in the framework they don't get it. It seems GDB doesn't have the debug symbols for the framework.
I've made sure that debug symbols are not stripped from the framework and the type is set to "DWARF with dSYM file".
Anyone have any ideas what might be wrong and how to fix it?
My setup:
Xcode 4.2.1
iOS SDK 5.0
I ran into this issue while linking a dynamic framework to a test application in Xcode 7. I was able to avoid the error by ensuring the following in the build settings of my dynamic framework:
"Generate Debug Symbol" - 'Yes'
"Strip Debug Symbols During Copy" - 'No'
Several things comes to my mind regarding your problem. Give them a try and see which ones work for you:
Make sure to have the "Other Linker Flags" on the "Linking" section of the framework's "Build" Info.
Make sure that you have the framework's built in the correct configuration (ie, if you compiled the framework's in Release and are using it with your project set to Debug you might get issues)
Make sure you added the correct framework .a file to your project (actually two issues here: you can have added the Release version - so no debug symbols in there - AND you have to make sure that your projec is not pointing to some old build version)
Check that both the framework's and your project have the "Level of Debug Symbols" on the "Code Generation" section of the "Build" Info set to "All Symbols [full, -gstabs+ -fno-eliminate-unused-debug-symbols]"
If all alse fails try to empty the XCode caches and remove the framework reference from your project. Then clean and rebuild the framework (all configs: device-debug, device-release, simulator-debug, simulator-release, ...) and add it again to you project. Clean and rebuild your project and cross your fingers... :-)
I have also experienced this issue. One way that I have been able to work around this by merging both projects into a single workspace.
Instructions on how to do this can be found at http://developer.apple.com/library/ios/#recipes/xcode_help-structure_navigator/articles/adding_a_project_to_a_workspace.html.
NOTE: I have also experienced a bug adding projects to workspaces where there appears to be no files in the recently added project to the workspace. I have found this is easily remedied by restarting Xcode after all of the projects have been added to the workspace.

Resources