Xcode Workspace with Multiple Projects and Coca Pods Setup - ios

Ok, let's start with the basics since I cannot friggin get this to work (see Xcode Workspace - Not finding imports from framework project pod)...
I want to create an Xcode workspace that has two projects:
Cocoa Touch Framework Swift project
Swift Demo app project for the framework
Nr. 2 should also contain a UI Testing target.
Then I want to use Cocoapods to provide the WHOLE workspace (both projects!) as a pod AND I want to 'link' the framework project into the demo app project so that it can be used there.
Can somebody guide me through this incl. how the pod file needs to look for this?

You need define the pods that will be common for all your projects first
# Uncomment this line to define a global platform for your project
platform :ios, '8.2'
# Uncomment this line if you're using Swift
use_frameworks!
# Define main pods.
def main_pods
#your main pods
pod 'AwesomeCache', '~> 5.0'
pod 'DZNEmptyDataSet', '1.8.1'
end
# Your FirstProjectName.
target 'FirstProyectName' do
main_pods
#here you can add any other for this specific project
pod 'Branch'
end
# Your SecondProjectName.
target 'SecondProjectName' do
main_pods
#here you can add any other for this specific project
pod 'Alamofire'
pod 'Fabric'
pod 'Crashlitycs'
end
target 'FirstProjectTestName' do
end
target 'FirstProjectTestUIName' do
end
post_install do |installer|
puts("Update debug pod settings to speed up build time")
Dir.glob(File.join("Pods", "**", "Pods*{debug,Private}.xcconfig")).each do |file|
File.open(file, 'a') { |f| f.puts "\nDEBUG_INFORMATION_FORMAT = dwarf" }
end
end
end
Hope this helps

Related

CocoaPods - Duplicate symbols when app & framework share a dependency

I am writing an iOS app, using CocoaPods 1.6.0 as my dependency manager. My project consists of a iOS app project (myapp-ui), as well as 3 iOS framework projects (myapp-common, myapp-model, and myapp-editor). I'm also leveraging Fabric.io for crash reporting and app metrics. My myapp-ui and myapp-model projects both make use of the Fabric and Crashlytics frameworks. My Pods file looks like this:
platform :ios, '11.0'
workspace 'MyApp.xcworkspace'
project 'myapp-ui/myapp-ui.xcodeproj'
project 'myapp-common/myapp-common.xcodeproj'
project 'myapp-model/myapp-model.xcodeproj'
project 'myapp-editor/myapp-editor.xcodeproj'
target 'myapp-ui' do
use_frameworks!
project 'myapp-ui/myapp-ui.xcodeproj'
# Pods for myapp-ui
pod 'SwiftyBeaver'
pod 'SwifterSwift'
pod 'Fabric'
pod 'Crashlytics'
pod 'KeychainSwift', '~> 13.0'
target 'myapp-uiTests' do
inherit! :search_paths
# Pods for testing
end
end
target 'myapp-common' do
use_frameworks!
project 'myapp-common/myapp-common.xcodeproj'
# Pods for myapp-common
pod 'SwiftyBeaver'
pod 'SwifterSwift'
pod 'KeychainSwift', '~> 13.0'
end
target 'myapp-model' do
use_frameworks!
project 'myapp-model/myapp-model.xcodeproj'
# Pods for myapp-model
pod 'SwiftyBeaver'
pod 'SwifterSwift'
pod 'Fabric'
pod 'Crashlytics'
end
target 'myapp-editor' do
use_frameworks!
project 'myapp-editor/myapp-editor.xcodeproj'
# Pods for myapp-editor
end
The pods install just fine, and my app builds with no issue. However, when I run it I see a large number of errors in the console that look something like this:
objc[62607]: Class CLSInternalReport is implemented in both <SOME LOCATION>/Build/Products/Debug-iphonesimulator/myapp_model.framework/myapp_model (0x11252f960) and <SOME OTHER LOCATION>/myapp-ui.app/myapp-ui (0x10f2831e8). One of the two will be used. Which one is undefined.
objc[62607]: Class Crashlytics is implemented in both <SOME LOCATION>/Products/Debug-iphonesimulator/myapp_model.framework/myapp_model (0x11252f9b0) and <SOME OTHER LOCATION>/myapp-ui.app/myapp-ui (0x10f283238). One of the two will be used. Which one is undefined.
objc[62607]: Class CLSFileManager is implemented in both <SOME LOCATION>/Build/Products/Debug-iphonesimulator/myapp_model.framework/myapp_model (0x11252fa00) and <SOME OTHER LOCATION>/myapp-ui.app/myapp-ui (0x10f283288). One of the two will be used. Which one is undefined.
objc[62607]: Class CLSAlert is implemented in both <SOME LOCATION>/Build/Products/Debug-iphonesimulator/myapp_model.framework/myapp_model (0x11252fa78) and <SOME OTHER LOCATION>/myapp-ui.app/myapp-ui (0x10f283300). One of the two will be used. Which one is undefined.
Is there a way to address these warnings? I've tried removing them from myapp-ui thinking that myapp-ui makes use of myapp-model (and would therefore inherit the dependency) but that didn't work. I'm at a loss as to how to address this. Thoughts?
I was getting the same warnings you're seeing and took me a while to find a fix. Turns out this happens when you have a dependency that comes pre-compiled, like Fabric and Crashlytics. I think it's because they are copied twice.
What I did was to add those pods only to the app target. My Podfile ended up looking somewhat like this
def pods
pod 'CGMath'
...
end
def app
pod 'Crashlytics'
pod 'Fabric'
end
target 'FrameworkTarget' do
pods
end
target 'AppTarget' do
pods
app
end

Adding Framework in App Modules in iOS SDK

I am working on a project where I have added Firebase, Crashlytics etc using POD.
Now there is a requirement to create modules for each feature available in the app, so I created Modules for each Feature (Say Profile, Payment, Linking etc) & its working fine with main container app. Now My App looks like as below
Now I want to a use Framework(say Firebase) added Via POD in my module(Say Profile) but when I tried to import in a module I am getting
No such module 'Firebase'
Please suggest me how can add Framework added Via POD in any module.
Please also let me know If I have explained my question.
Below is my POD file
platform :ios, '8.0'
use_frameworks!
def mainPodPackage
pod 'Mapbox-iOS-SDK'
pod 'ZendeskSDK'
pod 'OneSignal'
pod 'Firebase/Core'
pod 'Firebase/Messaging'
pod 'FacebookSDK'
end
target 'Production' do
mainPodPackage
end
target 'PreProd' do
mainPodPackage
end
target 'Dev' do
mainPodPackage
end
This is how you can install pod for multiple project workspace, edit your podfile as so, test target should have same project as it's target:
use_frameworks!
workspace 'Workspace_name'
project 'PjA.xcodeproj'
project 'path_to_PjB/PjB.xcodeproj'
target 'PjA' do
project 'PjA.xcodeproj'
...
end
target 'PjB' do
project 'path_to_PjB/PjB.xcodeproj'
...
end

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.

How to use CocoaPods with multiple Framework subprojects

First of all, I've turned on use_framework! in Podfile.
Assume the main project is MAIN_APP, and two subprojects are FRAMEWORK_A and FRAMEWORK_B.
MAIN_APP requires FRAMEWORK_A and FRAMEWORK_B, and FRAMEWORK_B requires FRAMEWORK_A as well.
All projects/targets are using CocoaPods to manage third party libraries.
For now, my Podfile looks like:
target :MAIN_APP do
project 'MAIN_APP'
pod 'PodA'
end
target :FRAMEWORK_A do
project 'FRAMEWORK_A'
pod 'PodB'
end
target :FRAMEWORK_B do
project 'FRAMEWORK_B'
pod 'PodC'
end
I manually added FRAMEWORK_A to build settings of FRAMEWORK_B, and both FRAMEWORK_A and FRAMEWORK_B to build settings of MAIN_APP.
All code compiles well, but when running the MAIN_APP crashes because it cannot load Framework of PodB.
I know I can manually add PodB to MAIN_APP and FRAMEWORK_B as well, but is it possible to define this kind of target dependency in Podfile?
Btw, when pod install, I got the warning:
[!] 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).
As I know, I can use nested target for host targets like:
target :FRAMEWORK_A
target :MAIN_APP
end
end
So CocoaPods will setup MAIN_APP to use FRAMEWORK_A and inherit pod dependencies from FRAMEWORK_A. But seems I cannot do it with multiple dependencies like:
target :FRAMEWORK_A
target :MAIN_APP
end
end
target :FRAMEWORK_B
target :MAIN_APP
end
end
Because target :MAIN_APP cannot be declared twice.
Is there any better solutions instead of defining pod dependencies as a function in Podfile and include in all target?
This is a great question and I've struggled with a similar situation. This is my PodFile:
platform :ios, '8.0'
workspace 'mygreatapp.xcworkspace'
project 'app/MyGreatApp/MyGreatApp.xcodeproj'
project 'platform/MyGreatFramework/MyGreatFramework.xcodeproj'
abstract_target 'This can say whatever you want' do
target 'MyGreatApp' do
project 'app/MyGreatApp/MyGreatApp.xcodeproj'
pod 'AFNetworking', '~> 2.6.0'
pod 'PromiseKit', '~> 1.5'
pod 'PromiseKit/Join'
pod 'KVOController', '~> 1.0'
pod 'FLAnimatedImage', '~> 1.0'
pod 'Crashlytics', '~> 3.3'
pod 'SSZipArchive'
end
target 'MyGreatAppTests' do
project 'app/MyGreatApp/MyGreatApp.xcodeproj'
pod 'OCMock', '~> 3.1'
end
target 'MyGreatFramework' do
project 'platform/MyGreatFramework/MyGreatFramework.xcodeproj'
pod 'SSZipArchive'
end
target 'MyGreatFrameworkTests' do
project 'platform/MyGreatFramework/MyGreatFramework.xcodeproj'
pod 'OCMock', '~> 3.1'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end
end
As you can see I'm not using frameworks and I use an abstract_target to group it all together. I wish these kinds of dependencies were easier to do in CocoaPods. I know this doesn't really answer your question but it might be helpful nonetheless.
I think you can also get around this by just making FrameworkA and FrameworkB into local (static library) pods and it will de-duplicate everything for you and integrate it into the host app properly.
Examples: https://github.com/rob-keepsafe/PodFrameworksIssue
master branch shows duplicate classes and umbrella frameworks like you have
deduped branch makes the internal dynamic frameworks into local pods (as static libs) to de-dupe and still link in the dependencies
I'm not entirely sure your issue is the same as mine, but I'm going to leave my solution here just-in-case someone has a similar issue.
I have a project with multiple sub-projects I use to modularize my code (and potentially prepare to extract to my own private pods).
I had the issue of one importing an external pod to one of the sub-projects, and receiving a dyld error due to a "missing image".
I found this Medium article from which I concluded that I had to always include the pods in the main project for the sub-projects to be able to find them. Neither of my external pods are used in the main project.
( https://medium.com/#akfreas/how-to-use-cocoapods-with-your-internal-ios-frameworks-192aa472f64b )
(I'm probably not writing the podfile as correctly or efficiently as I could, but this seems to fix my issue)
My podfile is therefore as follows:
abstract_target "RandomName" do
target "MainProject" do
inherit! :complete
workspace './MainProject.xcodeproj'
pod 'Moya', '~> 13.0'
pod 'KeychainSwift', '~> 17.0'
end
target "ModuleA" do
project './ModuleA/ModuleA.xcodeproj'
workspace './ModuleA/ModuleA.xcodeproj'
pod 'Moya', '~> 13.0'
end
target "ModuleB" do
project './ModuleB/ModuleB.xcodeproj'
workspace './ModuleB/ModuleB.xcodeproj'
pod 'KeychainSwift', '~> 17.0'
end
end

No such module `Quick` using cocoapods

I've been learning swift for three days. I'm planning to build my skill in swift especially in iOS development. I just advised by my colleague who is an iOS developer to learn swift while writing test in our app -- this is for the benefit to the company and myself which it makes sense for me. Now, I'm trying to follow this tutorial
https://medium.com/#ynzc/getting-started-with-tdd-in-swift-2fab3e07204b
After following the tutorial to rewrite the test in a framework called Quick which is very similar with Rspec. I did the installation of the CocoaPod then follow the install of the Quick framework. Use the .xcworkspaces instead of the .xcodeproj. But still I'm getting the error of No such module 'Quick'.
I did research already and removing the pods but still getting the error.
platform :ios, '9.2'
target 'FizzBuzz' do
use_frameworks!
def test_pods
pod 'Quick', '~> 0.9.0'
pod 'Nimble', '~> 3.2.0'
end
target 'FizzBuzzTests' do
inherit! :search_paths
test_pods
end
target 'FizzBuzzUITests' do
inherit! :search_paths
test_pods
end
end
screenshot of the project folder:
I recently had this issue and none of the current answers solved this for me.
The reason I was getting this error was that the Test/Spec file (NetworkSpec.swift) that I had created had a target membership of the main application target, not the tests target.
To update this, I opened the project in xcode, selected the file in the project explorer and then in the properties window on the right hand side. Then in the target membership area. I had two options.
ProjectName
ProjectNameTests
I unchecked the checkbox next to ProjectName (not the app's real name) and then checked the one next to ProjectNameTests and re-ran the tests. Everything worked as expected.
I ran into the same issue. I did not need to nest the test targets in my podfile. e.g.
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
target 'MyAppName' do
pod 'RealmSwift'
pod 'GoogleMaps'
end
target 'MyAppNameTests' do
inherit! :search_paths
pod 'Quick'
pod 'Nimble'
end
target 'MyAppNameUITests' do
inherit! :search_paths
pod 'Quick'
pod 'Nimble'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '3.0' # or '3.0'
end
end
end
I am using Xcode 8.1. Click on the currently selected scheme.
Select 'manage schemes'.
Selected scheme.
Put check mark next to test schemes and Quick.
Click on your app scheme again. Select each scheme and go to Product > Build. Finally select your main app scheme again. Now try adding 'import Quick' in one of your test classes.
Schemes
ISSUE RESOLVED
I was getting same issue. Files within Test folder did not see Nimble and Quick pods despite my Podfile was configured correctly and Target Membership for my test file set up correctly as well. I was unable to import both Pods.
Running below commands on Project folder via CLI resolved issue for me.
$ pod update Quick
$ pod update Nimble
My Podfile implementation of both pods for reference:
def include_test_pods
pod 'Quick'
pod 'Nimble'
end
Try this. Cocoapods may need to be rebuilt.
Quit XCode. Go to terminal and cd into your project.
Run pod deintegrate.
Run pod install.
Open Xcode and clean and build your .xcworkspaces project.
I had this issue that persisted through build cleans. I noticed that it was only happening in one file and files that did not have this issue had import foundation. After importing foundation on the line before it, it then worked. I thought maybe it was simply modifying the file that had done it so I removed the foundation import and the error came back. So try adding that import if you do not have it.
First thing first you just need to use pod inside your target project, so it gona share for your test target like that
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'TestNetWorkLayer' do
use_frameworks!
pod 'SwiftyJSON'
pod 'Quick'
pod 'Mockingjay'
pod 'Nimble'
pod 'Alamofire', '~> 5.0.0-rc.3'
target 'TestNetWorkLayerTests' do
inherit! :search_paths
end
end
After that you can import it inside your project
import Quick
import Nimble
class NativeApiClientSpec{
}
In my Podfile i use smth like this:
target 'Specs' do
pod 'Quick'
pod 'Nimble'
shared_pods
end
Additionally, re-open the project or use the following command: Product -> Clean and build folder
I had same issue. After a lot of trial and error, I found fix here: https://github.com/Quick/Quick/issues/402#issuecomment-149459840. I had to delete derived data and regenerate project to get Quick as build scheme
Try this;
Close xcode project
Run $ pod deintegrate
Delete Podfile.lock
Run $ pod install
and Build again!

Resources