Xcode: create Framework with pod dependecies - ios

I create a framework that use AFNetworking (installed with pod).
I can import this framework on my project and I can use all classes/methods that I exposed, so project compile.
When I try to run project on simulator, I obtain this error:
dyld: Library not loaded: #rpath/AFNetworking.framework/AFNetworking
Referenced from:
/Users/.../Library/Developer/CoreSimulator/Devices/F56F98F0-2AE0-4C87-AC9A-6E3B449762D1/data/Containers/Bundle/Application/BFA5359F-8FCE-4402-8487-CD9C002CB673/MyProject.app/Frameworks/MyFramework.framework/MyFramework
Reason: image not found
I already included 'MyFramework' under:
Build phases -> Embed Frameworks
I suppose I missing something on building Frameworks, but I can find out what! I already seen this unanswered question.
Who can I use MyFramework without installing Pod on MyProject again?

It is really delayed, for this issue but I have got my project working. It might not be the best way but it works. I am putting it here for future reference.
I wanted to do it without using Pods in the main project. The reasoning is, we are bundling our SDK into a framework.
So essentially, the first step I took was to get the framework project bundling without using the workspace. I just dragged the Pods project into the framework project.
Then I added the frameworks the the pods project creates and add them to my framework. I set them to optional and code sign. You can see them in the picture of where I added them under the build phases.
Then add them to your main project. not the framework the normal way by adding the project and or the framework. Then add it to the Embedded binaries and Linked Frameworks.

If it helps anyone, the solution mentioned by #ArtyomDevyatov does work. The trick is that you have to add 's.dependency' in podspec file.

Related

Embedding XCFramework in application with project framework dependencies

I have an Xcode workspace which features a project with an iOS Application target, and another project with a Framework target. The framework target is dependent on another framework, which is integrated in the form of an xcframework:
MyApp
MyFramework
OtherFramework
Using regular OtherFramework.framework would require it to be linked to MyFramework and then embedded in MyApp even though MyApp doesn't require the framework itself. However when integrating with xcframework, this project then fails to build with a No such module 'OtherFramework' error.
Project settings:
MyFramework Project
MyApp Project
Removing OtherFramework.xcframework from the MyApp target fixes the build issue, but then causes library not loaded errors as the framework is not present in the application.
Demo project here: https://github.com/msaps/XCFramework-Link-Issue
How are you meant to link an xcframework in an application and link in a dependent framework?
Why?
pyckamil just posted this article which explains the issue in detail: Everything wrong with XCFrameworks.
It turns out Xcode has an optimisation for the ProcessXCFrameworkLibrary step which extracts the correct .framework from an .xcframework for the active build architecture. This is only run once which causes issues for additional targets that try to link the same framework.
Update
This issue is resolved in Xcode 12.0
UPDATED - Resolved in Xcode 12.0
shinsuk came up with a reliable workaround that works by adding architecture-explicit framework search paths to ensure the correct .framework within an XCFramework is found.
Details can be found in the README.
Check build settings and defining the Framework Search Paths to a folder which contains the frameworks in question. If the frameworks are placed in your project directory, simply set the framework search path to $(SRCROOT) and set it to recursive.
check the response Getting error "No such module" using Xcode, but the framework is there
IMO, It seems not xcframework issue.
Check out this answer: https://stackoverflow.com/a/59435627/2661407
Umbrella frameworks are not supported on iOS, watchOS, or tvOS.
OtherFramework.xcframework should be signed and embedded in your host app.
and add "#executable_path/Frameworks" setting into your MyFramework.framework > Build settings > Runpath Search Paths.
I had this issue as well after using xcframework instead of framework. So I changed my project structure:
The MyFramework Peoject embed OtherFramework.xcframework,Then make it exported using #_exported import OtherFramework in MyFramework Project. And the MyApp just link MyFramework but can both import/use MyFramework and OtherFramework.
BTW, It seems to custom the #rpath and manual codesign the OtherFramework.
I had an issue like that as well.
First, make sure if you have MyFramework.framework file within the same directory as MyApp.
Second, when building MyFramework.framework, make sure that OtherFramework.xcframework is as well in MyFramework's project directory.
And one more thing, check target SDK versions. They should be somewhere on the same level.
I had the same issue as you, and after seeing your pbxproj I think it can be solved the same way.
Change your framework search path to recursive (either through UI or manually editing the pbxproj "$(SRCROOT)/../Frameworks" => "$(SRCROOT)/../Frameworks/**"), like so: https://github.com/msaps/XCFramework-Link-Issue/pull/1/files

How to add a reference (instead of copy) of a custom iOS framework in a project

I try to add a custom made framework in a project of me but as a reference.
The reason for this is that I want making changes in the framework and see them in the project without need of delete old framework - copy new one.
But something i am missing since i got the below error
No such module
The way I add the framework as a reference is to "untick" the "copy if needed" when I drag and drop it.
I am adding the framework inside the "frameworks" folder of the project.
Any help would be appreciated, thanks!
You should be linking external libraries in the menu by going to the Target’s “Build Phases” and add the library with “link binary with libraries”. This should fix your problem.
An alternative suggestion is to use CocoaPods, which are very widely used in iOS development. If you aren't familiar with Cocoapods, its sort of like web development's npm. You turn your custom framework into a Pod and add a Podfile to your iOS app. The Podfile is just a list of external dependencies. If you push a change to your custom framework, all you have to do is run
pod update
in your command line it will automatically handle the update. This would solve your problem and also keeps your project neat and organized so you don't have to juggle drag and dropping new libraries. CocoaPods also can handle a lot of the other major external libraries you may be using. See the following very easy to follow tutorials:
creating a pod,
getting started with cocoapods

How to link a (subproject) framework against a pod?

I am creating a new app MyApp, where I decided to put some parts of the app in a seperate framework MyFramework, instead of the app itself to make them reusable in other projects. The framework has its own project (MyFramework.xcodeproj) which is a subproject of the main app project (MyApp.xcodeproj). The main app project has a dependency (does linking & copying) on the framework (MyFramework.framework), of course. This part works fine so far.
Now, MyFramework needs a cocoa pod (Alamofire) in order to work. As far as I understood, I don't want to set up cocoa pods for the MyFramework.xcodeproj project directly, so I just set it up for the main app MyApp.xcodeproj (now MyApp.xcworkspace because of pods) and also included the Alamofire pod there. I then linked MyFramework.xcodeproj against the Alamofire.framework (not the MyApp_Pods.framework), but did not set Alamofire for copying. The MyApp.xcodeproj does the usual cocoapods linking/copying/bundling stuff, so also includes the Alamofire.framework in the final product. This worked partially fine.
(Note: I say 'partially fine' here because I occasionally had errors in the MyFramework sources not finding the Alamofire module when compiling, which could be fixed by re-linking the Alamofire.framework in the MyFramework.xcodeproj. Besides that, building and running the app works fine.)
The issue is now, when I try to archive the app, the Alamofire module is again not found in the MyFramework sources. The error occurs both, when archiving the MyApp (which also builds MyFramework), as well as archiving MyFramework directly. The error occurs not in the linking phase, but in the compile phase of a source Swift file that has an import Alamofire statement.
I suspect something like the linking of the Alamofire.framework to use a wrong relative path that can be found while building, but is different on archiving or such. I already tried to set the Alamofire.framework path to Relative to build products, but couldn't get this to work, not even for regular building (not archiving).
I'm now stuck and wondering whether my whole setup with linking from the MyFramework.xcodeproj project to the Alamofire.framework and having Alamofire included as a pod is correct.
Can anybody give me a hint what might be wrong here? Either in the paths or in the whole setup?
This won't tackle the problem itself, but would provide a solution that serves your need:
Transform MyFramework into a pod. Host it in your private spec repo, or — even simpler — use the git parameter in the pod file to access it.
pod 'MyFramework', :git => 'https://gitsever/maxscompany/MyFramework.git'

Embedded swift framework with cocoapods

I made a private framework that I want to use in different project. I use Cocoapods with this framework for third parties like AFNetworking, Facebook, or SDWebImage. I use an aggregate to build my framework for simulator and devices architectures.
I can build it, without any problem, but when I add my embedded framework to my new project (wrote in Objective-C), I have this error at the launch:
dyld: Library not loaded: #rpath/AFNetworking.framework/AFNetworking
Referenced from: /private/var/containers/Bundle/Application/2BE49976-94F8-43C3-BBFF-930F11642DDE/MyPhotoApp.app/Frameworks/PhotoLibrary.framework/PhotoLibrary
Reason: image not found
My new project has also Cocoapods with all the required pods of my framework.
The thing I would like, and I can't find how to do it, is to make a framework that depends of Cocoapods, but that does not contains the sources. I would like that the client add itself the necessary pods to its project.
Do you know how I can do that ?
Thank you :)
For Objective-c projects, DONOT uncomment the line use_frameworks!. It is meant only for swift projects. For future reference. :)

Cocoa Touch Framework Dependencies

I'm trying to create a Cocoa Touch Framework. To create a framework is not a problem, I used this tutorial and it is good.
I need to use third party libraries inside: like openssl, XLForm, AFNetworking. I know that it is not correct to include them in my framework, I need to create a dependencies, but I can't find how to do this.
Moreover is it possible to use pods in my framework and just make dependencies to these libs. So user which will include my framework to his project will need just install these pods.
It seems that I found solution.
Thanks to #Droppy and thanks to this question.
What I did: I just installed pods to my Framework project but used this use_frameworks! key.
Then I dragged my Framework to my Project and installed pods there, also with same key, otherwise (when pod wasn't installed in my Project) I was getting error like:
dyld: Library not loaded: #rpath/XLForm.framework/XLForm...
I used XLForm inside my Framework.

Resources