How to build Swift framework with 3rd party SPM dependencies - ios

I've built swift frameworks before, but I've never dealt with one that has 3rd party dependencies.
What I have right now is a Swift framework that has a dependency on several Swift packages. When I build it I see MyFramework.framework in the products folder as well as bunch of dependencies. I can make XCFramework out of it, but when integrating (embedding) it into another app I see an error that MyFramework is missing its dependencies (see image below).
What am I doing wrong or missing?

Creating a framework (or xcframework) that has embedded other frameworks is not supported for iOS(I believe this is answered here).
But there is an other way. You can statically link all the dependencies of your library, so in the final framework the binary will also contain the code of its dependencies.
If you are using CocoaPods and the name of the framework is aFramework you can do:
target 'aFramework' do
pod 'Alamofire', :linkage => :static
end
Then you can use the created aFramework.framework in a application target that does not have the Alamofire framework, since the code will be "embedded" in the aFramework's binary.

Related

iOS framework to wrap existing framework

I'm trying to define a common framework in a project that provides an implementation-agnostic layer. For example, provide a protocol like Analytics and a set of methods/properties as its interface, and provide the implementation through a singleton object so different app targets would use the same implementation.
The issue is when importing the framework from within an app target, a compiler error occurs like so:
import Core // Missing required module 'Firebase'
What needs to be done?
In the Podfile, dependencies are installed only for the framework targets, not the app targets.
Dependencies should set to Core.podspec if you make framework manager by Cocoapods
Pod::Spec.new do |s|
s.name = 'Core'
s.dependency 'Firebase'
end
iOS framework to wrap existing framework,You have astray when you have this idea, One framework depends on the other. put the depends framework together with it when you use it, not contain or wrap. Cocoapods provides a simple way, create a new warehouse containing the two dependent frameworks, The idea of the first floor is right.
It turns out to be a pod installation configuration issue.
Changed the installation targets and the hierarchy, and things were solved.

How to build a Cocoa touch framework in iOS?

I want to build a Cocoa touch framework in iOS. My framework named as 'MyFramework' which depends on third party frameworks like 'GoogleWebRTC'.
I tried adding this through cocoa pods and also with drag into MyFramework project. But the issue is when I import MyFramework into any other Project, it gives error:
Module 'WebRTC' not found
I have also seen that Apple discourage umbrella frameworks:
Why are umbrella frameworks discouraged?
Then:
I want to understand how I can include this GoogleWebRTC.framework or any other third party lib. in MyFramework project and distribute to others.
Help is Appreciated!
Solution for me was that I have to explicitly add GoogleWebRTC in the app with my framework.
And if your framework can install by pods then you can mention your dependent third parties lib. in podspec file as below:
s.ios.dependency 'dependent framework pod'

Framework target, App target and cocoaPods working together, how to maintain dependencies

I am creating a framework that uses third party frameworks like alamofire. I have created a App that uses this framework and also uses third party framework again like alamofire(both could use it). So now I have 2 targets, I added both in workspace, I did pod init but it could only link with only one .xcodeproj and create its own workspace.
I also tried
Can I use CocoaPods when creating a Cocoa Touch Framework?
but pod install didn't work as it was not able to find target and if dragged in same folder it ask to specify target path as it only want one .xcodeproj
Please if somebody could help me with this. How to access cocoa pods framework in both custom framework and app.
Ideally the Pod should be in your App.
Even though your Framework is also using the same third party framework the pod install should be done for that at App level and both App and framework should be able to read it.
Have said that, if you are developing Framework independently you can install POD at that time in framework but when your are using this framework in app then the third party framework can be installed at app level and frameworks should also be able to read it since they are now also part of same App target.

ObjC: Statics are not consistent across multiple frameworks when contained in cocoapod

So my situation specifically uses the Objection dependency injection library. However, I believe this could be an issue for other libraries as well.
Platform
iOS 8.0 Xcode 6.1.1. Cocoapods 0.35. Objective-C.
Set up:
I have 4 projects. 3 universal frameworks and a test app (I'm creating an api). The test app does not utilize cocoapods (though some other app might).
All three of my frameworks need to use injection. I created a pod file that looks like
workspace 'workspace.xcworkspace'
platform :ios, '8.0'
xcodeproj 'path/to/proj/one'
xcodeproj 'path/to/proj/two'
xcodeproj 'path/to/proj/three'
target :Project1 do
pod 'Objection', '1.4'
end
target :Project2 do
pod 'Objection', '1.4'
end
target :Project3 do
pod 'Objection', '1.4'
pod 'SDWebImage', '~>3.7.1'
end
Problem
When I use this set up singletons don't work in Objection. However, they only don't work if they (the singleton class) is defined in project 1 and then I call [JSObjection createInjector]; in project 2 (the projects don't make a difference, it is that create is called in a different project to the definition).
Current theory
After battling with this for a while I believe it is due to the warning along the lines of:
Objection is defined in Project 1, Project 2 and Project 3.
Which one will be used undefined.
So when the class registers itself with the injection system (e.g through objection_register_singleton(ClassX)). It is using the JSObjection definition from its project, which might not be the one being used for a class that injects it (e.g. objection_requires_sel(#selector(myClassXObject))).
Question
I want to be able to use the iOS frameworks setup as, from what I understand, it is better overall than static libs. However, I also want to be able to use Cocoapods (and have any app, that uses my api, use Cocoapods).
How do I either a) share one definition across multiple frameworks or b) setup a framework as a Cocoapod (I've seen that this is being developed).
I would love to be able to keep the frameworks linked through the xcode workspace so when one is built the frameworks it depends on are also built. Though having said that, my api will probably become a Cocoapod at some point anyway.
Thanks in advance (and for reading to here)
Indigo

handling dependencies for iOS Framework project

I've created iOS Framework project using this method: https://github.com/jverkoey/iOS-Framework
Works pretty neat but I'm a little confused on how to include libraries/frameworks that are needed by my framework to work and, in particular, how to do it so that in case 3rd party client app that uses my framework can include these libs as well without conflicts.
Let's say my framework code needs these two things:
FacebookSDK.framework
libFlurry.a
The first one is an iOS Framework. When I add it to "Link Binary With Libraries" phase in my Framework and try compile the client project that uses my framework the linker complains about missing symbols - I need to add FacebookSDK to the client project which is great: there is no possibility of conflicts if client apps wants to use Facebook.
However when I do the same with Flurry static library I get duplicate symbols error when compiling client project. Which confuses me a bit, because isn't FacebookSDK.framework just a packaged static library?
ukaszs-iMac:FacebookSDK.framework lukasz$ file Versions/A/FacebookSDK
Versions/A/FacebookSDK: Mach-O universal binary with 3 architectures
Versions/A/FacebookSDK (for architecture i386): current ar archive random library
Versions/A/FacebookSDK (for architecture armv7): current ar archive random library
Versions/A/FacebookSDK (for architecture cputype (12) cpusubtype (11)): current ar archive random library
So my questions are:
why a library embedded in framework (like Facebook) is not linked to my Framework project product, whereas library included as .a file is?
how to include .a file in my framework so that it does not produce duplicate symbols error when client app using my framework also needs this particular static library?
For the use case you are describing, you should be linking to these external libraries from your application, NOT your own framework. It can be one or the other, but it can't be both.
If you decide that these dependancies belong as the responsibility of the application, you would remove them from "Link Binary With Libraries" and any other explicit linking configuration, and just project your framework project with the path to these frameworks and libraries so it can find the symbols (but not link against them) at compile time (i.e. the path to the libraries should be included LIBRARY_SEARCH_PATHS).
Use cocoapods , it's easy (http://cocoapods.org/)
Your application developers will have to include the podfile and download the dependencies.
While developing your SDK use a reference application/demo app on top of the SDK to simulate this.
You shouldn't link anything when building your framework but just create a *.a binary with your framework's objects.
Also you should not include code from other libraries in your framework as client applications may be adding the same libraries directly or requiring different versions of them, thus creating conflicts.
Off course you can reference *.h header files from other libraries in your framework in order to compile your objects.
As a result the installation steps for your framework should detail other required frameworks/libraries needed, their supported versions, how to add resource files (if any), etc. Just some of the many reasons why you may want to consider Creating a CocoaPods' podspec instead.
You should use CocoaPods. Your dependency on Facebook can be done by linking against the CocoaPod.
If you want to include that particular version of Facebook in your pod, you can put it in your repo and use the vendored_frameworks property to refer to it.
Similarly if you wanted to vendor libFlurry.a, you could do so using s.vendored_libraries.
For system libraries, you don't need to vendor them, e.g. libZ.a.
I strongly recommend creating your CocoaPod using pod lib create YourPodName. They've recently changed the mechanism for how this works and it's really nice.
You can create an Example project that shows how to use your code in context of an app.
Then one of the other neat things I just learned about, someone can do pod try YourPodName and it will automatically download, integrate and run the Xcode project.
CocoaPods is worth the trouble.
I am building my framework project using CocoaPods.
The framework uses some 3rd libs from CocoaPods.
Podfile specifies to install dependency on target of the framework.
When I build the framework, it includes all libs in the binary.
If I add use_frameworks! in Podfile, when the framework is built, it will not include 3rd party libs.
Use CocoaPods dependancy manager. Here's a good guide,
7 miniute video tutorial
Mostly if you install third party frameworks you can install with cocoapods (which is really nice, I would definitely do that) or they offer you to download the framework and include it in your Project.
If you decide to download the library and include it there is normally a list of frameworks you need in the "Getting started" guide.
Means: Offer them to install using cocoapods and to download your library but do not include anything else, give them a list what they need.

Resources