Can I use CocoaPods when creating a Cocoa Touch Framework? - ios

I'm creating a new Cocoa Touch Framework (MyFramework.framework), which will have a dependency on Alamofire. This framework will be written in Swift. As a test I started a new Cocoa Touch Framework project:
File > New > Project > Framework & Library > Cocoa Touch Framework
Then, in the terminal I performed:
pod init
under this projects directory. In the newly created Podfile I added the following:
source 'https://github.com/CocoaPods/Specs.git'
# Uncomment this line to define a global platform for your project
platform :ios, '8.0'
# Uncomment this line if you're using Swift
use_frameworks!
pod 'Alamofire', '~> 3.0'
Once again, in the Terminal I performed:
pod install
and started coding away.
Everything seemed well and good till I used the MyFramework.framework Product in a Single View Project. When I attempt to run the project I get the following issue:
dyld: Library not loaded: #rpath/Alamofire.framework/Alamofire
Referenced from: /Users/me/Library/Developer/CoreSimulator/Devices/87DA70B6-49BF-441E-BD81-F4A80B0792CF/data/Containers/Bundle/Application/2E414EA8-7E54-4D71-9295-566D4FAAADE2/test.app/Frameworks/MyFramework.framework/MyFramework
Reason: image not found
I thought that Cocoa Touch Framework projects were inherently Dynamic, and therefore would include all dependencies.
Can anyone tell me why this is happening and how I may be able to fix it?
Is this an issue with CocoaPods or am I missing something?
I'm a noob to Stack Overflow so please let me know if you need more information from me.
Thanks!

Unfortunately CocoaPods doesn't support use with Cocoa Touch Framework target. I found a few references to this while digging through their issues on GitHub:
We don't really support integrating Pods into framework targets...
-neonichu on Nov 4, 2015
and
...in order for this to "just work", CP would need to do a recursive analysis of dependencies in your Xcode project and also somehow ensure that you would never use the build product in another context.
-neonichu on Jul 7, 2015
So far I've found two ways to deal with the issue:
The right way is to create a new pod spec for your framework and bring it in to your main project via CocoaPods. This resolves all of the problems CococaPods has with the dependency graph and is the recommended solution from the CocoaPods developers.
The easy way is to include the pods from your framework in your main project. This seems to work, but frankly I don't know why. This is the Podfile from my test project:
platform :ios, '9.0'
use_frameworks!
def myfirstframework_pods
pod 'Alamofire', '~> 3.0'
end
target 'MyApp' do
pod 'SwiftKeychainWrapper', '~>1.0'
myfirstframework_pods
end
target 'MyFirstFramework' do
myfirstframework_pods
end

Try adding the dependency on Alamofire in the framework's podspec as below
Pod::Spec.new do |s|
# Other setup
# Dependencies
s.dependency "Alamofire"
# Other dependencies if any

Related

Firebase for iOS inside framework

I have a project who needs firebase for login and ...
So I decided to create a project(Cocoa Touch Framework) inside my workspace to handle all firebase operation.
The firebase framework added to main app via Linked Frameworks and Libraries
I also using cocoa pods
My pod file is something like this:
platform :ios, '10.0'
inhibit_all_warnings!
def firebase
# Firebase
pod 'Firebase/Core'
pod 'FirebaseUI/Auth'
pod 'FirebaseUI/Google'
pod 'FirebaseUI/Facebook'
pod 'FirebaseUI/Phone'
pod 'Firebase/Storage'
pod 'FBSDKLoginKit'
end
target 'RKFirebaseModule' do
use_frameworks!
workspace 'Main'
project 'RKFirebaseModule/RKFirebaseModule.xcodeproj'
firebase
end
target 'App' do
use_frameworks!
workspace 'Main'
project 'App.xcodeproj'
rx_swift
rx_cocoa
end
at this point if I run the app I will get this error:
dyld: Library not loaded: #rpath/Bolts.framework/Bolts
Referenced from: /.../RKFirebaseModule
Reason: image not found
So I tried to solve this problem by adding firebase dependencies to the main app (in pod file):
target 'App' do
use_frameworks!
workspace 'Main'
project 'App.xcodeproj'
rx_swift
rx_cocoa
firebase
end
Now I'm getting bunch of error relating to duplicate implementation of classes like this:
Class FIRAIdentifiers is implemented in both /.../RKFirebaseModule.framework/RKFirebaseModule and /.../App.app/App. One of the two will be used. Which one is undefined.
So how can I solve this problems?
Any help or suggestion will be appreciated. tnx
EDIT 1: Similar cases founds here, but non of the mentioned methods works for me.
1.Duplicate symbols when framework target has a static dependency
2.Duplicate classes warnings at runtime when multiple targets are contained in the same project
EDIT 2: The first problem is normal and it is due to this fact that cocoa pods won't bundle the dependencies into the framework, so I have to use same dependencies for main app.
The second problem caused by some of the firebase static framework, so my framework have a copy of firebase static frameworks and main app has a copy too, so the error is expected here.
I have to remove duplicate static frameworks. HOW?
I had a similar issue when I was using a framework I built and this framework was used in projects that used firebase as well. The workaround I came across was through using cocoapods. I built my framework as a static framework using cocoapods (check .podspec below):
s.static_framework = true
s.dependency 'Firebase'
s.dependency 'Firebase/Core'
The example app i was working on imported my framework via cocoapods as well
use_frameworks!
pod 'gameballSDK', :path => "~/Documents/Libraries/gameballSDK"

Embedding pods to static library iOS

I'm creating a static library in iOS using Objective-C. This library will gather data from the app where this library is integrated, the gathered data from the app will be sent to the server.
I'm just wondering if is it possible to embed a cocoa pods framework in my library like AFNetworking?
Thanks in advance
Yes. It seems to be possible.
I created a static library project and tried to integrate cocoapods in to it with below steps.
pod init
Then edited the podfile to integrate AFNetworking pod in the project like below
# Uncomment the next line to define a global platform for your project
platform :ios, '9.0'
target 'Testing' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
pod 'AFNetworking', '~> 3.0'
# Pods for Testing
end
then gave
pod install
I get the below warning
[!] The Podfile contains framework or static library targets
(Testing), for which the Podfile does not contain host targets
(targets which embed the framework). If this project is for doing
framework development, you can ignore this message. Otherwise, add a
target to the Podfile that embeds these frameworks to make this
message go away (e.g. a test target).
As the first line in the warning says we are doing framework development, hence we can ignore this message and it should work fine.
Also my suggestion is to use Alamofire instead of AFNetworking as Alamofire is swift based and AFNetworking is objective-c based.

Add cocoa pod to iOS independent Framework

I would like to create a framework that is archived and distributed on its own. The problem I'm having is that I would like this library to have cocoa pod dependency libraries compiled into it. Is this possible?
It seems to work. But when I embed the framework in a sample app and invoke code of the embedded dependency I get an error: dyld: Library not loaded:... Reason: image not found
# Uncomment the next line to define a global platform for your project
platform :ios, '9.0'
target 'MySDK' do
use_frameworks!
pod 'ALBNoSQLDB', '~> 4.2'
end
Do I have to run an archive script to embed the dependent pods? Is this even possible?
Thanks.

Is this the correct way to create dynamic/embedded framework with embedded cocoa pods?

I am trying to create a Dynamic Framework to share the code among various extensions of my app.
Problem :
Here is my project structure.
MyFrameworks is a network layer of my app which inherently uses Alamofire. So structured my pod file as follow.
platform :ios, '9.0'
use_frameworks!
workspace 'CocoaPodsProjectworkspace'
def shared_pods
pod 'Alamofire'
pod 'SwiftyJSON'
end
target 'CocoaPodsProject' do
project 'CocoaPodsProject.xcodeproj'
# Pods for CocoaPodsProject
end
target 'MyFramework' do
project 'MyFramework/MyFramework.xcodeproj'
shared_pods
end
target 'CocoaPodsProjectTests' do
end
target 'CocoaPodsProjectUITests' do
end
On building the framework when I drag it as embedded binary to my Main project I get the error.
dyld: Library not loaded: .framework/Alamofire Referenced from:
/Users/sandeep/Library/Developer/Xcode/DerivedData/CocoaPodsProjectworkspace-enpobdyluhbxdwazuvbfogcspfof/Build/Products/Debug-iphonesimulator/MyFramework.framework/MyFramework
Reason: image not found
Solutions I tried :
Declaring the pods_frameworks.framework as optional in linked
binaries.
Tried changing RunPath Search path of framework Dynamic Library
Install name Running pod deintegrate and running pod install again.
Deleting derived data and relinking framework all lead to same
problem.
Solution that worked :
I realized that MyFramework.framework was trying to find the Alamofire.framework in a wrong directory and it was alway trying to search relative to project/target using the framework . So the simplest solution that I could find was to modify pod file as follow.
platform :ios, '9.0'
use_frameworks!
workspace 'CocoaPodsProjectworkspace'
def shared_pods
pod 'Alamofire'
pod 'SwiftyJSON'
end
target 'CocoaPodsProject' do
project 'CocoaPodsProject.xcodeproj'
shared_pods
# Pods for CocoaPodsProject
end
target 'MyFramework' do
project 'MyFramework/MyFramework.xcodeproj'
shared_pods
end
target 'CocoaPodsProjectTests' do
end
target 'CocoaPodsProjectUITests' do
end
As you can see I added the shared_pods to both main app and my framework project and their respective targets. Now everything works smooth. I neither had to make pods_framework optional nor had to modify the build settings of MyFramework.
Question:
Adding the shared repos to all the projects and their targets which wants to use my framework looks little redundant. Is there a better way I can specify Myframework.framework to read all its dependencies rather than reading from project using it?
I have raised a issue for the same on CocoaPods Git repo. But because it isn't inherently a issue they might not revert back. Hence posting it as a question here.Link to issue : https://github.com/CocoaPods/CocoaPods/issues/6901 if it helps.
Solved it by creating a cocoa pod for my custom Framework and using cocoa pods dependency .
Step 1 : Clean the Main/Parent project
Removed MyFramework from the project (which was added as sub
project) and remove MyFramework.framework added in embedded library of projects General settings.
Run pod deintegrate (to de-integrate the pod already added to
project)
Now that the project is clean and does not have any pod added
initialized the pod by running pod init
Step 2: Create a Pod for my Framework
Using cd command navigate to MyFramework project and once you are in
MyFramework's root folder run pod spec create MyFramework
This will create a file named MyFramework.podspec in the
MyFramework's root folder. Open MyFramework.podspec using any of the
editor tool and update it as shown in tutorial https://www.raywenderlich.com/126365/ios-frameworks-tutorial
Most important step which is not there in this tutorial is how to add
cocoa pods dependency that our framework needs to build. Turns out
thats the most easiest part. In my case I needed SwiftyJSON and
Alamofire so in .podspec file I added,
s.dependency 'Alamofire'
s.dependency 'SwiftyJSON'
Step 3:
Now open the Main/Parent projects Podfile and update it as shown
below.
target 'CocoaPodsProject' do
use_frameworks!
pod 'TestFramework', :path => 'TestFramework/'
end
What it did is, it tells main project to add TestFramework as dependency and installs TestFramework in Framework folder of main project. Because TestFramework in itself has dependency to Alamofire & SwiftyJSON when you run pod install it will not only install Alamofire but also installs SwiftyJSON and adds it to TestFramework's Framework folder.
Thats all. Now your TestFramework can access Alamofire and SwiftyJSON and Main/Patent project can access TestFramework
If you want to now update TestFramework code, till u finish develop add it as subproject to Main project (This is necessary because if you open TestFramework.xcproj u won't see Alamofire/Swifty JSON. You have to open the Parent project's workspace itself hence this solution). Once u are done with development if u decide to remove the TestFramework as subproject u can do that :)
Finally If you decide to add additional extensions to app, Lets say u add Today extension all u have to do is to modify ur Podfile as follow.
target 'CocoaPodsProject' do
use_frameworks!
pod 'TestFramework', :path => 'TestFramework/'
end
target 'CocoapodsToday' do
use_frameworks!
pod 'TestFramework', :path => 'TestFramework/'
end
Woo hooo :) Now add your frameworks to as many extensions you want :) Hope it helps.

Dependencies from subproject cause dyld: Library not loaded error

Specs:
Xcode 8.2,
CocoaPods 1.1.1,
OSX 10.12.2
I split my project in 2 projects. One contains my providers (does api calls, database access, etc), the other the UI.
The UI project depends on the providers project. My configuration is working with the simulator but not with the device.
On device, I get:
dyld: Library not loaded: #rpath/Alamofire.framework/Alamofire
Referenced from:
/private/var/containers/Bundle/Application/EAD65532-DD02-4DA6-9877-7937F9D69F26/xxxxx.app/Frameworks/Providers.framework/Providers
Reason: image not found
This is my podfile:
use_frameworks!
workspace 'xxxxx.xcworkspace'
project 'xxxxx.xcodeproj'
project 'Providers/Providers.xcodeproj'
def shared
pod 'QorumLogs'
pod 'Reachability', '~> 3.2'
pod 'RealmSwift'
end
target 'Providers' do
project 'Providers/Providers.xcodeproj'
pod 'Alamofire', '~> 4.0'
pod 'Valet'
pod 'Starscream'
pod 'ChameleonFramework/Swift', :git => 'https://github.com/ViccAlexander/Chameleon.git'
shared
end
target 'xxxxx' do
project 'xxxxx.xcodeproj'
platform :ios, '8.0'
pod 'SwiftValidator', :git => 'https://github.com/i-schuetz/SwiftValidator.git', :branch => 'remove_delegate_callback'
pod 'SwiftCharts', :git => 'https://github.com/i-schuetz/SwiftCharts.git'
pod 'Google/SignIn'
pod 'SwipeView', '~> 1.3.2'
pod 'CMPopTipView', '~> 2.0'
pod 'KLCPopup', '~> 1.0'
pod 'ChameleonFramework/Swift', :git => 'https://github.com/ViccAlexander/Chameleon.git'
pod 'HockeySDK'
shared
end
I also added the binary of Providers to my UI target under "Embedded binaries"
It seems the UI project can't load the dependencies of Providers project. Don't know if this makes sense, but I also tried nesting the configuration of my UI project in Providers, in the podfile, and add inherit! :search_paths to it but it also didn't help.
It works only when I use the same dependencies in both projects.
Ideas?
Edit
I also get this warning when executing pod install, don't know if it's related:
[!] The Podfile contains framework targets, for which the Podfile does
not contain host targets (targets which embed the framework). If this
project is for doing framework development, you can ignore this
message. Otherwise, add a target to the Podfile that embeds these
frameworks to make this message go away (e.g. a test target).
While updating a Swift 2.2 project using the AlamoFire third party framework I ran into several issues just like yours including the dreaded dyld: Library not loaded ...... image not found.
After spending several hours reading about different explanations for the problem,trying to figure it out myself, and implementing many of the suggested fixes, I reached an impasse. Some of the solutions worked on simulator and not iPhone which gave me (false) encouragement to keep trying to fix the problem.
I eventually reached the conclusion that starting with a clean slate may be a better strategy. I had already shown that a new Swift 3 project could use AlamoFire 4.0 and other third party frameworks such as ReactiveSwift (via cocoapds) without a problem. I think this may be a general strategy that avoids the difficulty of tracking down build, build phase, or file location problems.
So here it is. It's very simple. Create a NEW project. Install the AlamoFire and all the other frameworks using cocoapods and test it to make sure it works. At this point delete files you will be replacing such as ViewController.swift and the Main.Storyboard, then drag over all the files from your old project. I converted to swift 3 before I did this to make things even easier. I rebuilt the project and it worked first time! Even the storyboard links were preserved like magic. 1h of work (if that) instead of several! I hope this works for you too!

Resources