Including a static library in a Xcode project - iphone

I have developed a static library using the "iPhone OS->Library->Cocoa Touch Static Library" of Xcode. I compiled it and it works fine. Then I wanted to include this library in a new project. Here is what I've done :
Create a new Xcode project "View-based application"
Project->Add To Project : I added my static library .xcodeproj file
Project->Edit Active Target
In General tab : I've added the static library in the "Direct Dependencies"
In Build tab : I've added the path of the headers in the "Header Search Paths" In "Search Paths" section
Then I tried to use one of the classes I've put in my static library, but I get a linking error :
"_OBJC_CLASS_$_GenUIImage", referenced from:
Objc-class-ref-to-GenUIImage in TestViewController.o
Symbol(s) not found
Collect2: Id returned 1 exit status
I do not get what I did wrong. Please help.
Thanks in advance

I found the solution. I dragged & dropped the .a (library file) into the "Link Binary With Libraries" of the main project target.
However I have an other problem.
My static library contains a class that needs the AudioToolbox framework. I added it in my static library. However I need to add the framework also inside the project. Is there a way to avoid duplicating the framework in the main project?

Related

Swift Package Manager (package successfully added, but Module not found)

I'm new in Swift. I want to create iOS app that can connect to PostgreSQL database. First I found library https://github.com/vapor/postgresql.git that should be added to my project via Swift Package Manager. Using tutorial I added required library to my project successfully (File -> Swift Packages -> Add Package Dependency):
list of added packages from SPM
But when I try to import this module into my view controller, Xcode shows error that module is not found:
not found
I tried several times to rebuild my project, created new project just for testing this issue. Also I found information about build phases and added this lib as a dependency:
build phases
But I still get error: "No such module PostgreSQL".
Can anyone help me?
I found solution by myself. I compiled C static library "libpq" (can be found in PostgreSQL sources) and added it to my swift project. Included this library by adding special bridging header file. Finally I got what I wanted.
P.S. If someone what to repeat, he or she should know: static C library must be compiled for iOS device architecture (and also in iOS simulator architecture which differs from iOS device arch.).

Linking dynamic library within static framework

I am building the static iOS framework upon multiple libraries in Xcode. One of them should be the card.io. I cannot use cocoapods or carthage. So far I imported .frameworks within the .framework and it works pretty well. However card.io uses static library (.a file) with bunch of headers. It works well in dynamic type of .frameworks (or iOS app project) but in static project I get these errors on including of the .a files:
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't locate file for: -lCardIO
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: -lCardIO is not an object file (not allowed in a library)
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't locate file for: -lopencv_core
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: -lopencv_core is not an object file (not allowed in a library)
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't locate file for: -lopencv_imgproc
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: -lopencv_imgproc is not an object file (not allowed in a library)
Regarding these errors I downloaded the source codes of card.io and it looks that there is dynamic .framework target waiting for build. I tried to use this one instead of .a files and headers - so my project at least can be builded. Because the card.io does not contatin architectures for simulator (which, by the way, it should with this release 5.2.2) I am not able to test it in unit tests, so when I test this solution on device I get this error:
dyld: Library not loaded: #rpath/CardIO.framework/CardIO
Referenced from: /var/containers/Bundle/Application/55D3AF7F-83F4-4B3D-A667-0FCO93CCC441/App/AppDemo
Reason: no suitable image found.
So far my knowledge+google+stackoverflow is stuck here, because it looks that xcode does not support the .framework within .framework this way.
To this moment I spent two days with this "issue", so the question is: Does exist any solution for including dynamic library into static framework? Or any solution to include card.io into static framework?
EDIT:
Well actually the solution was more stupid than I would think (as always). Just to include card.io in the .framework go to "Project Description -> Build Settings -> Library search paths" and type the path where should xcode look for the libraries. This approach solves the first one issue of this post - this means the implementation of the .a libraries and headers.
At this moment I cannot guarantee it will work in releases based on my framework so I will update this post to confirm it later. I hope it helps someone...

Static framework linked to Cocoapod not found in Main project

I'm trying to add a static framework (Moya) to my private Cocoapod project through Carthage.
My goal is to include Moya as a static framework in my private Cocoapod (SwiftModel) and use Moya as well in my main project (as SwiftModel has a dependency to it).
I've added Moya to my framework by doing the following steps:
link framework in podspec file
s.vendored_frameworks = 'SwiftModel/Carthage/Build/iOS/Moya.framework'
add Moya to private framework (Link Binary With Libraries)
So inside my Pods project it looks like this:
Trying to add the path to "Framework Header Search Path" did not made any changes. I've tried to add it in the main project and in pods project.
When just building the private pod everything works fine and Moya is recognized. However if I want to build the main project (that includes my private pod) I'm always getting this error:
framework not found Moya for architecture arm64
As your error states that
framework not found Moya for architecture arm64
It means that Moya is not available for arm64 architecture, but your main project has following architectures;- arm64, armv7, armv7s. Remove the arm64 from your main project's valid architecture.
Also try to add -Objc in other link flags.
Try adding libz to the link library section of you project
iOS Support matrix:-

"Undefined symbols for architecture i386" on unit tests

I'm getting the following error only when I try to build the unit tests of an iPhone static library:
Undefined symbols for architecture i386:
"std::terminate()", referenced from:
-[ZipArchive dealloc] in libMyProject.a(ZipArchive.o)
"___gxx_personality_v0", referenced from:
Dwarf Exception Unwind Info (__eh_frame) in libMyProject.a(ZipArchive.o)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Building the original project works fine.
What can I be missing?
It should be noted that ZipArchive is a .mm file that references the libz.dylib framework, which is referenced both in the original project and in the test project.
Additionally, the usual Build Settings suspects have the following values:
Framework Search Paths: "$(SDKROOT)/Developer/Library/Frameworks" "$(DEVELOPER_LIBRARY_DIR)/Frameworks"
Other Linker Flags: -all_load -lxml2 - ObjC
Header Search Paths: /usr/include/libxml2
I found the solution in this post.
For some reason that eludes me, the compiler needed the ZipArchive.mm file to be renamed to .m when the static library is used in another project (the test project, in this case).
This typically occurs for one of two reasons:
You copied a framework or system header directly to your project folder instead of adding it with a reference through XCode
You've installed multiple SDKs, and the wrong framework or header is being referenced. Most frameworks aren't "Developer" frameworks. SenTestingKit.framework is an example of a developer framework, UIKit.framework isn't. Oddly, there are two different places that Developer Frameworks exist. In the /Developers/~ folder in XCode, and also in the SDK Developers folder. The default behavior is to reference the framework in XCode's developer folder. To override this, enter "$(SDKROOT)/Developer/Library/Frameworks" in "Framework Search Paths". Or in the case of an imported header or library, go the corresponding field and add "$(SDKROOT)/..."
Make sure your search paths are the same correct for all Targets:
If you are using multiple SDKs, the wrong version of the Developer Frameworks could get added (like SenTestingKit). Manually enter the the correct one under Framework Search Paths with
$(SDKROOT)/Developer/Library/Frameworks

Iphone-exif 0.91 not working when I add it to my project, gives error ".objc_class_name_EXFJpeg", referenced from:

When I add libiphone-exif.a to snapandrun in objectiveflickr I get this error:
".objc_class_name_EXFJpeg", referenced from:
literal-pointer#__OBJC#__cls_refs#EXFJpeg in SnapAndRunViewController.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
I do not know what this means, I follow the guide to add it, add all of the .h files and the libiphone-exif.a
Is there something special I have to do?
It sounds like you didn't add the library properly. It is a static library, not an Objective C or data file, so simply adding it to the project isn't enough. All that will happen is that it gets copied into the application bundle, when it needs to be statically linked into the executable. You have to open your targets and add the .a file under "Link Binary With Libraries".
I downloaded the source from the svn project from google and drag and drop into my project.
Clicking the target and marking the static lib as "weak" type instead of "required" made no difference.