Cocoapods, Add Dependencies to All Targets in a Generic Way

Cocoapods, add dependencies to all targets in a generic way

Doing something like this will probably work.

def common_pods
pod 'Pod1'
pod 'Pod2'
pod 'Pod3'

end

project = Xcodeproj::Project.open "../Project.xcodeproj"
project.targets.each do |t|
target t.name do
common_pods
end
end

For more details on this approach, check out this thread on the Cocoapod's repo:

https://github.com/CocoaPods/CocoaPods/issues/5898

Share same pods across all sub-framework projects in a workspace

After taking some inspiration from this answer that @KirilS linked, I came up with this modified pod file that works:

use_frameworks!
def shared_pods
pod 'Pod1'
pod 'Pod2'
end

workspace 'MyApp'
abstract_target 'MyAppDependency' do
shared_pods
Dir["**/*.xcodeproj"].select { |project_path| !project_path.to_s.start_with?('Pods') }.each do |project_path|
proj = Xcodeproj::Project.open project_path
proj.targets.each do |t|
target t.name do
project project_path
end
end
end
end

Alternate approach with better syntax:

use_frameworks!
def shared_pods
pod 'Pod1'
pod 'Pod2'
end

my_ws = 'MyApp'

workspace my_ws
abstract_target 'MyAppDependency' do
shared_pods
Xcodeproj::Workspace.new_from_xcworkspace("#{my_ws}.xcworkspace").file_references
.select { |file| /^((?!Pods).)*\.xcodeproj/.match file.path }
.map { |file| Xcodeproj::Project.open file.path }.each do |proj|
proj.targets.each do |t|
target t.name do
project proj.path
end
end
end
end

How do I specify multiple targets in my podfile for my Xcode project?

Since CocoaPods 1.0 has changed the syntax, instead of using link_with, do something like:

# Note; name needs to be all lower-case.
def shared_pods
pod 'SSKeychain', '~> 0.1.4'
pod 'INAppStoreWindow', :head
pod 'AFNetworking', '1.1.0'
pod 'Reachability', '~> 3.1.0'
pod 'KSADNTwitterFormatter', '~> 0.1.0'
pod 'MASShortcut', '~> 1.1'
pod 'MagicalRecord', '2.1'
pod 'MASPreferences', '~> 1.0'
end

target 'Sail' do
shared_pods
end

target 'Sail-iOS' do
shared_pods
end

Old answer Pre CocoaPods 1.0:

Yes there is a better way! Check out link_with where you can do link_with 'MyApp', 'MyOtherApp' to specify multiple targets.

I use this with unit tests like link_with 'App', 'App-Tests' (beware of spaces in target's names).

Example:

platform :osx, '10.8'

link_with 'Sail', 'Sail-Tests'

pod 'SSKeychain', '~> 0.1.4'
pod 'INAppStoreWindow', :head
pod 'AFNetworking', '1.1.0'
pod 'Reachability', '~> 3.1.0'
pod 'KSADNTwitterFormatter', '~> 0.1.0'
pod 'MASShortcut', '~> 1.1'
pod 'MagicalRecord', '2.1'
pod 'MASPreferences', '~> 1.0'


Approach using abstract_target:

In below example, the 'ShowsiOS', 'ShowsTV' and 'ShowsTests' targets have their own separate pods, plus ShowsKit inherited, because they are all child of the dummy target 'Shows'.

# Note: There are no targets called "Shows" in any of this workspace's Xcode projects.
abstract_target 'Shows' do
pod 'ShowsKit'

target 'ShowsiOS' do
pod 'ShowWebAuth'
end

target 'ShowsTV' do
pod 'ShowTVAuth'
end

# Our tests target has its own copy
# of our testing frameworks
# (beside inheriting ShowsKit pod).

target 'ShowsTests' do
inherit! :search_paths
pod 'Specta'
pod 'Expecta'
end
end

Is there a way to specify a dependency on another branch when building my Cocoapod?

I asked in the Cocoapods Repository and one of the contributors answered my question.

Linting (and therefore, trying to upload your pod) runs on your Podspec, not Podfile, and there is no way to specify a different branch in the Podspec.

No, non-released dependencies can only be set in the Podfile.

What I want to do is, therefore, sadly not possible.

How to satisfy cocoapod external dependancy when using specific branch

Well, it seems like specifying the source as the github repo instead of the cocoapod repo for this particular pod works.

I added this line before the target 'MyGreatApp' do line:

source 'https://github.com/Swinject/Swinject.git'

I must specify that this works for this particular pod, but might not work for other cases. The fine folks behind Swinject have a fix for an Xcode (9, beta) bug on a branch in their github repo that is not in the cocoapod repo.

So this answer works in this case, but unfortunately this might not be as generic as I hoped.

Using a pod from inside a swift package

It's possible but it's not useful because Swift Packages don't have weak linking to frameworks as XCode project does with -weak_framework <framework_name> so you need to implement non trivial steps.

In swift package you can specify a framework to link with linkedFramework:

.target(
name: "MyPackage",
dependencies: [],
linkerSettings: [
.linkedFramework("Localize_Swift")
.unsafeFlags(["-F/Users/user/.../Localize-Swift"])
]
),

Where unsafeFlags specifies the full path to dir with the framework. But unexpectedly then you can not use your package with your app because of next issue:

The package product 'MyPackage' cannot be used as a dependency of this
target because it uses unsafe build flags.

To compile Swift Package with your framework you should copy Localize_Swift.framework to target build dir of your package and then you can omit unsafe build flags of the package because the compiler sees all dependencies on the dir's root level.

.target(
name: "MyPackage",
dependencies: [],
linkerSettings: [
.linkedFramework("Localize_Swift")
]
),

The same you can do with your app after adding your package. If you copy Localize_Swift.framework to the app's target build dir then your linked swift package can be compiled because it looks for linkedFramework in the current build dir.

By default pods are generated to separate folders in target build dir e.g.: $TARGET_BUILD_DIR/Localize-Swift/Localize_Swift.framework so you can change CONFIGURATION_BUILD_DIR for Localise-Swift target in Pods project to generate the framework to the root of the target build dir or make a script to copy etc. But there is a problem that swift package dependencies are started compiling at the early begin of compilation process when you don't have any compiled pod frameworks. So at the first stage you should compile your Localize_Swift.framework before (better to make a fat framework) and then add a Pre-actions Run Script under Build in your target scheme that copies the framework from your destination to target build dir.

cp -r $PROJECT_DIR/Localize_Swift.framework $TARGET_BUILD_DIR/Localize_Swift.framework

Now both your app and your swift package can be compiled with Localize_Swift framework.

As I say in the begin it's not useful because you need to compile Localize_Swift.framework manually (or with an additional script) before the general compilation process that neutralizes convenience of cocoa pods at all.

Consider using next preferred options:

  1. Pod is avaliable as a swift package. You can make a dependency in your package and in this case both your package and the dependency will be also available in your app. By the way Localize_Swift supports swift packages.

  1. Pod has swift sources You can make your own swift package with the sources files and then link it to your package.

  2. Pod has binaries From Swift 5.3 swift package can embed xcframework so you can build this xcframework from pod's binaries and then make binary target dependency in your swift package: .binaryTarget(name: "MyLib", path: "MyLib.xcframework") (see How can I add a local library as a dependency in Swift Package Manager)

How to fix my build: .framework file with CocoaPods dependencies and 2 targets (iOS and tvOS)

I don't know how useful this question / answer will be to others who stumble across it, since I had a huge number of issues and a very specific setup. But I wanted to go ahead and post that I did find a solution to my issues.

First and foremost, I needed to set the ENABLE_BITCODE=YES and BITCODE_GENERATION_MODE=bitcode flags. However settings these two flags prevented my code from building with a linker error. This error was caused because my Resource Bundle target was using Apple Generic Versioning -- which is not supported for Resource Bundles

By setting the Versioning System build setting to "None", it fixed everything

Set deployment target for CocoaPods's pod

While some development versions of CocoaPods (as well as pre-1.0 versions) may have propagated the deployment target of the project down to the pods, this is no longer the case in 1.0. To work around this, the current developer recommends using a post-install hook.

Here's a brute force approach to force a hard-coded deployment target for every pod in the generated Pods project. Paste this at the end of your Podfile:

post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.2'
end
end
end


Related Topics



Leave a reply



Submit