Using static libraries with CocoaPods 1.5 no such module at import
Asked Answered
G

2

23

With CocoaPods 1.5 released I am trying to migrate from having 10-15 dynamic pods in my projects to having them as static libraries instead, with the goal of speeding up my app start time.

At this stage my simple (i.e., simplistic) attempt has been to remove the use_frameworks command when running my pod install. This indeed transforms my pods to static libraries. But it also produces a series of "No Such Module" throughout my project when trying to import my Pods (e.g., "No such Module PureLayout or no such Module FirebaseMessaging).

I am not super versed in all the intricacies of pods and dynamic/ static libraries and have tried for the past day to find good documentation on how to properly import, use and deploy static libraries for a Swift Project but could not find clear guidelines.

I am using Xcode 10.1 and CocoaPod 1.5.2 (client version).

Could anyone help me by providing links to detailed instructions on how to move from dynamic to static libraries?

Thanks a ton!

Gigantopithecus answered 12/11, 2018 at 15:1 Comment(0)
C
29

CocoaPods 1.5.0 introduced use_modular_headers! to still provide module support with static libraries. Details in the release notes.

Alternatively you could change the modular imports in your sources to file imports.

I'd also recommend trying out the CocoaPods 1.6.0 beta since it has several fixes for static/dynamic library and framework issues.

2020 Update

CocoaPods 1.9.0 introduced use_frameworks! :linkage => :static which will generate full frameworks with statically linked libraries and module map files. This is typically an even better approach than use_modular_headers!.

Chi answered 12/11, 2018 at 16:3 Comment(2)
It works! I don't understand why but it did the trick :) What are the modular headers for and why not including them prevented my app to compile my pods?Gigantopithecus
CocoaPods does not generate modules for static libraries unless use_modular_headers! is specified.Chi
P
11

In most cases for a small project it will be enough to add use_modular_headers! instead of the removed import_frameworks!.

Alternatively you can try adding :modular_headers => true after each pod declaration of a "missing" module:

pod 'Firebase/Auth' :modular_headers => true
pod 'Firebase/Database' :modular_headers => true
pod 'Firebase/Storage' :modular_headers => true
pod 'Firebase/DynamicLinks' :modular_headers => true

However, a bigger project might contain modules that just don't want to be static, with or without modular headers. One good example is Facebook SDK. For this case there is a cool addition here, which allows to specify which modules you want to leave dynamic.

Here's an example podfile, where all libs will be static except the ones, listed in the dynamic_frameworks array:

platform :ios, deployment_target: '9.3'

inhibit_all_warnings!

# Import CocoaPods sources
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
dynamic_frameworks = ['Bolts', 'FBSDKCoreKit', 'FBSDKLoginKit', 'FBSDKShareKit']

# make all the other frameworks into static frameworks by overriding the static_framework? function to return true
pre_install do |installer|
    installer.pod_targets.each do |pod|
        if !dynamic_frameworks.include?(pod.name)
            puts "Overriding the static_framework? method for #{pod.name}"
            def pod.static_framework?;
                true
            end
        end
    end
end

target 'MyApp' do
pod 'SwiftLint'
pod 'Firebase/Auth'
pod 'Firebase/Database'
pod 'Firebase/Storage'
pod 'Firebase/DynamicLinks'
pod 'FBSDKCoreKit', '~> 4.33.0'
pod 'FBSDKLoginKit', '~> 4.33.0'
pod 'FBSDKShareKit', '~> 4.33.0'

end
Palazzo answered 19/2, 2019 at 15:9 Comment(1)
why the semicolon?Chirr

© 2022 - 2024 — McMap. All rights reserved.