Using a private framework (with pods) inside a project's podfile - ios

I've created a private framework which utilises a number of pods. I want to now use this framework (which has a podspec file) in a project also using Cocoapods.
I've searched for many hours but cannot find a working example. My use case is that I am creating multiple apps, however these apps share a lot of code and assets (storyboards, files, etc). Therefore the framework contains all these common components and needs to be used in each app target.
I currently have this but it does not work as it should:
platform :ios, '9.0'
use_frameworks!
workspace 'Project.xcworkspace'
def shared_pods
pod 1
pod 2
pod 3
end
target 'Target1' do
shared_pods
end
target 'Target2' do
shared_pods
end
target 'MyPrivateFramework' do
project 'MyPrivateFrameworkDirectory/MyPrivateFramework.xcodeproj'
shared_pods
end
target 'TestsTarget' do
inherit! :search_paths
# Pods for testing
end
The warning I receive is:
[!] 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).

I found my answer by reading this thread carefully: https://github.com/CocoaPods/CocoaPods/issues/6123 and comparing with the sample project here: https://github.com/benasher44/CocoaPodsLibExample

Related

Cocoapods: Two Apps with a shared private Framework, in a WorkSpace

I have one workspace that have 2 project and 1 common shared framework, each project can use common framework and on Two Apps with a shared private Framework, in a WorkSpace but when I added Podfile and execute pod install I got this warning
[!] The Podfile contains framework or static library 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).
and I got this error when running my project application
dyld: Library not loaded: #rpath/Alamofire.framework/Alamofire
Referenced from: /Users/alfian0/Library/Developer/Xcode/DerivedData/SIPMI-arflaxzmdqswkjgsqghdmfizsjws/Build/Products/Debug-iphonesimulator/Common.framework/Common
Reason: image not found
this is my Podfile
# Uncomment the next line to define a global platform for your project
platform :ios, '9.0'
use_frameworks!
workspace 'SIPMI'
project 'Common/Common.xcodeproj'
project 'TKIApp/TKIApp.xcodeproj'
project 'WalletApp/WalletApp.xcodeproj'
def networking_pods
pod 'Moya/RxSwift', '10.0.2'
end
def application_pods
pod 'RxCocoa', '4.1.2'
pod 'Fabric', '1.7.3'
pod 'Crashlytics', '3.10.0'
pod 'IQKeyboardManagerSwift', '5.0.7'
end
target 'Common' do
project 'Common/Common.xcodeproj'
networking_pods
end
target 'TKIApp' do
project 'TKIApp/TKIApp.xcodeproj'
application_pods
end
target 'WalletApp' do
project 'WalletApp/WalletApp.xcodeproj'
application_pods
end
and this is my project structure

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.

Targets within a target in a Podfile

I am trying to install the Google Mobile Ads SKD into my Xcode project. I installed Cocoapods and then initialized a Podfile into my project:
# Uncomment the next line to define a global platform for your project
platform :ios, '10.2'
target 'Cubical' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for Cubical
target 'CubicalTests' do
inherit! :search_paths
# Pods for testing
end
target 'CubicalUITests' do
inherit! :search_paths
# Pods for testing
end
end
However, I don't understand why there are targets within my main project (Cubical). I never really used CubicalTests or CubicalUITests, since I don't really need to test my UI or any snippet of code. I was thinking of removing these two folders.
My questions are,
1) Is there any drawback in removing the Tests and UITests folders from my Xcode project? And if I do, can I just simply delete those two targets from my Podfile?
2) Let's say I was going to keep those two targets. Would I have to add the pod to all three targets? Or do the two nested targets inherit any pods of target 'Cubical'
3) Do I need to add to Linked Frameworks the Google Mobile Ads SDK? Or is this already done by Cocoapods?
My final pod would look like this:
# Uncomment the next line to define a global platform for your project
platform :ios, '10.2'
target 'Cubical' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
pod 'Google-Mobile-Ads-SDK'
# Pods for Cubical
target 'CubicalTests' do
inherit! :search_paths
# Pods for testing
end
target 'CubicalUITests' do
inherit! :search_paths
# Pods for testing
end
end
Question 1:
There is no issue when you are removing Tests,CubicalUITests targets & folders, If you don't need to perform that kind of tests.
Question 2:
You can share pods with several targets like below,
def shared
pod 'Google-Mobile-Ads-SDK'
end
target 'Target1' do
shared
end
target 'Terget2' do
shared
end
Global pods for multiple targets
#Global Pod for all targets
pod 'Google-Mobile-Ads-SDK'
target 'target1' do
pod 'Fabric' #Pod for nested Target. i.e., Google-Mobile-Ads-SDK + Fabric
end
target 'target2' do
pod 'RadioButton'#Pod for nested Target. i.e., Google-Mobile-Ads-SDK + RadioButton
end
Pods for nested targets:
#Global Pod for all targets
pod 'Google-Mobile-Ads-SDK'
target 'target1' do
pod 'RadioButton' #Available for target1 and target2
target 'target2 copy' do
pod 'Fabric' #Available for target2 only
end
end
Question 3:
The linked frameworks are automatically done by cocoapods. See here you need to link the framework by using frameworks without cocoapods.

Including a pod inside a framework target: file not found

I'm using framework targets (for better code reuse and IB_Designables), and I've already had a framework target working perfectly. I've decided to move some other classes to a framework target too.
I've set up the pods (just a single one in this case), but whenever I try to include the pod I'm getting not found error.
No change if I try to use the modules approach too:
The problem is that I've already got another framework too, with the same settings (cross checked all the compiler settings/linker flags/build phases etc) and that framework has no issue importing its pods.
Here is my podfile (TUComponents is the working on, TUModels is the failing one):
[...]
target 'TUComponents' do
pod 'AHKNavigationController'
pod 'TTTAttributedLabel'
use_frameworks!
end
target 'TUModels' do
pod 'JSONModel'
use_frameworks!
end
Even weirder; Xcode has no problem code-completing importing the JSONModel/JSONModel.h header (or JSONModel in case of module #import). But when I try to compile, it fails.
What might be wrong with my configuration?
UPDATE: If I give up using frameworks in pods and use regular old static library, and set allow non-modular includes in frameworks to YES, I can build. But I have no idea why I can't build when using Pod frameworks.
Maybe try solution from: https://www.natashatherobot.com/cocoapods-installing-same-pod-multiple-targets/
platform :ios, '9.0'
use_frameworks!
# My other pods
def testing_pods
pod 'JSONModel'
end
target 'TUComponents' do
pod 'AHKNavigationController'
pod 'TTTAttributedLabel'
testing_pods
end
target 'TUModels' do
testing_pods
end
From iOS - Build fails with CocoaPods cannot find header files :
Make sure your Podfile includes link_with on targets missing a config file. Cocoapods only sets the first target by default otherwise. e.g.
platform :osx, '10.7'
pod 'JSONKit', '~> 1.4'
link_with 'Pomo', 'Pomo Dev', 'Pomo Tests'
Restarting Xcode fixed it for me
The following steps worked in my case:
Quit the Xcode n Simulator
Delete Drived data
Again open your project
Clear it

iOS , ld: framework not found GoogleMaps for architecture arm64

I'm developing an app using google maps. I will explain what I did with google maps, and maybe you can help me.
I was using Google maps frameworks without POD, but after a few errors about Google map Key I deleted the google map frameworks reference and I installed it using POD. Everything is working fine, but when I hit
Product -> TEST
now I get this error:
ld: framework not found GoogleMaps for architecture arm64
Any idea how fix this?
Thank you!
Podfile looks like this Cocoapods v1.0 beta 6):
platform :ios, '8.0'
use_frameworks!
target 'Project' do
pod 'GoogleMaps'
target 'ProjectTests' do
inherit! :search_paths
pod 'Mockingjay'
end
end
Update Please check if you have same build settings in the Architectures and Build active Architectures only keys of the targets
Your podfile should look like this
platform :ios, '8.0'
use_frameworks!
target 'Project' do
pod 'GoogleMaps'
end
target 'ProjectTests' do
//inherit! :search_paths
pod 'Mockingjay'
end
End the project target before you start the ProjectTest target, also why you add inherit! :search_paths? it's usually not needed unless you have some special requirement
Old Answer
If you want to you pods in the Test target than you have to add then in the test also the same way you have added in project's main target
So your cocoa pods like this if "SwiftCocoaPods" is your main target name
//other top level imports
target “SwiftCocoaPods” do
pod "GoogleMaps"
end
target “SwiftCocoaPodsTests” do
pod "GoogleMaps"
end
Then you should add pods for the test also like "SwiftCocoaPodsTests". you may replace the name with whatever you Test target name is
Else if you want to add the same pods in the multiple target you can use def and use that in all the targets which looks like this
def project_pods
pod "GoogleMaps"
//add other pods which you want in all the targets
end
target “SwiftCocoaPods” do
project_pods
end
//only add project_pods instead of pods individually
target “SwiftCocoaPodsTests” do
project_pods
end
This works for me:
platform :ios, '9.0'
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
def all_pods
pod 'GoogleMaps'
end
abstract_target 'Map Base' do
all_pods
target 'Map' do
end
target 'Unit Tests' do
end
target 'Device Tests' do
end
end
You can try this workaround by opening Xcode with Rosetta as suggested in https://github.com/googlemaps/google-maps-ios-utils/issues/355#issuecomment-800912985
It will hit your performance but works.
1 - With Xcode closed (Important) Go to finder -> Applications
2 - Right Click on Xcode and select "Get Info"
3 - On the info panel check "Open using Rosetta"
4 - Double Click in the large bottom preview of the info panel.
See this comment:
https://github.com/googlemaps/google-maps-ios-utils/issues/355#issuecomment-1060959728

Resources