Cocoapods: Reject installation if a static library is used as a transitive dependency while using frameworks

Created on 10 Dec 2014  ·  32Comments  ·  Source: CocoaPods/CocoaPods

Static libraries and frameworks are only linked to the user target by classic CocoaPods. That approach will not work if we are building frameworks and have a vendored static library as a transitive dependency, because the linker expects all symbols to be resolved in this case.

Using -undefined dynamic_lookup or linking to both the dynamic framework and the user target could be solutions to pursue for the future, but as a first step, we should reject these cases.

To reject vendored_libraries we can simply use the file extension, for vendored_frameworks we have to check if the included binary is statically or dynamically linked.

enhancement

Most helpful comment

iOS 7 & Dynamic Frameworks

Regarding your second issue: Getting dynamic frameworks work on iOS 7 is only possible for Development & Ad Hoc builds. It's the App Store which will reject such apps when submitting. We solved that by having separate targets for dev/testing & App Store: Testing uses dynamic frameworks while App Store imports the framework's Swift files directly. So far this works fine as long as there are no file name collisions.

Static Transitive Dependencies

The workarounds necessary for making this work depend on the static Pod you're trying to use.

Let's use Crashlytics as an example.
I'll assume you use the latest non-beta CocoaPods version.

We have a dynamic framework Pod in our app called CrashlyticsService which basically just abstracts away our Crashlytics code. It's also written in Swift.

The Podspec is similar to this:

Pod::Spec.new do |s|

    s.name         = 'CrashlyticsService'
    s.platform     = :ios, '7.0'
    s.source_files = '**/*.swift'

    s.dependency 'Crashlytics'

    s.pod_target_xcconfig = {
        'FRAMEWORK_SEARCH_PATHS' => '$(inherited) $(PODS_ROOT)/Crashlytics',
        'OTHER_LDFLAGS'          => '$(inherited) -undefined dynamic_lookup'
    }
end

Because Crashlytics's Pod is not a valid framework (it includes headers of the unrelated Fabric framework - I reported that bug to them but they didn't fix it yet) I slightly modified the Pod's header files & use this modified version instead in our app's Podfile:

# tell CocoaPods what version of Crashlytics you want
pod 'Crashlytics', :git => 'https://github.com/fluidsonic/Crashlytics.git', :tag => 'v3.1.0'

# tell CocoaPods to use your dynamic framework (you most likely already have something like this)
pod 'CrashlyticsService', :path => 'Modules/Services/Crashlytics'

In order to prevent CocoaPods from complaining about the use of static transitive dependencies you use this simple hack in your Podfile:

pre_install do |installer|
    # workaround for https://github.com/CocoaPods/CocoaPods/issues/3289
    def installer.verify_no_static_framework_transitive_dependencies; end
end

If you already have another pre_install hook must add the code to the existing one instead.

Other static Pods are added in a similar way although some will need more or other workarounds.
If you have any problems when integrating the example or other static Pods then just post the errors here.

All 32 comments

Even if we find a workaround for the linking without duplicating symbols, mixing frameworks and static libaries won't work for another reason: we don't build clang modules for static libraries, which causes compiler errors, if the framework's public headers import public headers of the static library with a non-module-import.
I guess, that happens because public headers are imported by the umbrella header and will have implicit clang module exports. That also includes transitive imported headers. If the imported header is not within the same target, it can't probably be exported as nested module, if it isn't already part of a clang module itself.

So I'm trying to work around a few complications. My app is Objective-C. My framework is written in Swift, and depends on Swift frameworks, Objective-C frameworks, and static libraries distributed as CocoaPods/frameworks.

So I've got the static library as a transitive dependency issue as the main bad guy.
I've also got the no-dynamic-frameworks on iOS 7 issue, less so of an issue, but would be amazing to tackle.

@fluidsonic seems to have some serious wisdom on this topic.. as apparently Our app uses use_frameworks! (aka dynamic frameworks) for development & testing and use_frameworks!(false) (aka static libraries) when submitting to the App Store (due to lack of iOS 7 support). We've split our app into a lot of parts/modules (using separate Pods for each) which are linked together by CocoaPods. These modules in turn use several static library Pods as transitive dependencies and they work for us even when all Pods are built as dynamic frameworks.

Sounds like magic to me. Eager to hear more/see some snippets/podfiles/spec if possible!

iOS 7 & Dynamic Frameworks

Regarding your second issue: Getting dynamic frameworks work on iOS 7 is only possible for Development & Ad Hoc builds. It's the App Store which will reject such apps when submitting. We solved that by having separate targets for dev/testing & App Store: Testing uses dynamic frameworks while App Store imports the framework's Swift files directly. So far this works fine as long as there are no file name collisions.

Static Transitive Dependencies

The workarounds necessary for making this work depend on the static Pod you're trying to use.

Let's use Crashlytics as an example.
I'll assume you use the latest non-beta CocoaPods version.

We have a dynamic framework Pod in our app called CrashlyticsService which basically just abstracts away our Crashlytics code. It's also written in Swift.

The Podspec is similar to this:

Pod::Spec.new do |s|

    s.name         = 'CrashlyticsService'
    s.platform     = :ios, '7.0'
    s.source_files = '**/*.swift'

    s.dependency 'Crashlytics'

    s.pod_target_xcconfig = {
        'FRAMEWORK_SEARCH_PATHS' => '$(inherited) $(PODS_ROOT)/Crashlytics',
        'OTHER_LDFLAGS'          => '$(inherited) -undefined dynamic_lookup'
    }
end

Because Crashlytics's Pod is not a valid framework (it includes headers of the unrelated Fabric framework - I reported that bug to them but they didn't fix it yet) I slightly modified the Pod's header files & use this modified version instead in our app's Podfile:

# tell CocoaPods what version of Crashlytics you want
pod 'Crashlytics', :git => 'https://github.com/fluidsonic/Crashlytics.git', :tag => 'v3.1.0'

# tell CocoaPods to use your dynamic framework (you most likely already have something like this)
pod 'CrashlyticsService', :path => 'Modules/Services/Crashlytics'

In order to prevent CocoaPods from complaining about the use of static transitive dependencies you use this simple hack in your Podfile:

pre_install do |installer|
    # workaround for https://github.com/CocoaPods/CocoaPods/issues/3289
    def installer.verify_no_static_framework_transitive_dependencies; end
end

If you already have another pre_install hook must add the code to the existing one instead.

Other static Pods are added in a similar way although some will need more or other workarounds.
If you have any problems when integrating the example or other static Pods then just post the errors here.

So, this is pretty great. I got my transitive static dependency (Firebase, in this case) working.

A couple questions on that front, given that I'm using a custom podspec for Firebase..
1) Is it possible to define pre_install hooks in podspecs?
2) Could the s.pod_target_xcconfig be put in the Firebase podspec instead of the consuming framework podspec?

So, my afternoon is already 100 times better. I'm still very interested about the iOS 7/Swift situation though. Besides how you actually pulled off automating the pulling of the frameworks Swift files in, I'm most interested in what happens then to namespaces? If the Swift files are just being pulled in manually instead of as a framework, don't they then lose their module/namespace? If so, I think Swift frameworks like Alamofire, ReactiveCocoa, etc. would just crumble to pieces... types would be redefined, access control means nothing, etc.

Great that the workarounds work for you too!

Static Transient Dependencies

Regarding your questions:

  • Unfortunately you can not use the pre_install hook in .podspecs. If you want to distribute a public framework which depends on these workarounds you'll have to mention them in the set-up instructions for developers using your framework.
  • I do not think you can set the necessary built settings from within the static Pod's .podspec. You could try using user_target_xcconfig instead of pod_target_xcconfig but I don't think that this will work. Like for the other question you'll have to mention the workaround in the set-up instructions.

iOS 7

The situation here is indeed really bad but I don't think there's much room for improvement.

  • We'll drop iOS 7 support in our app as soon as iOS 9 goes live, which is in 8 days. 5% of our users who still use iOS 7 simply won't get any more app updates. The little usage doesn't justify the efforts and downsides for us anymore. So we don't care much about a cleaner solution.
  • We don't use any automation to add the Swift files from the frameworks to our app's App Store target. We update the references manually from time to time whenever we need to make a new App Store archive. Usually this takes us 1-2 hours every few weeks which is okay.
  • You're right, all Swift files share the same namespace when you add them to the same project. None of the frameworks we use explicitly refer to their own namespace by name so we had no issues here. We also had luck that no symbol collisions occurred so far. In the end this depends on the frameworks you are using.

What is a problem though are the import statements which must not be used when everything is thrown in the same namespace - i.e. in App Store builds. We solved that by using conditional compilation (for which you have to touch the code):

import UIKit

#if !FALLBACK
    import Module1
    import Module2
#endif

Then you just need to add the -DFALLBACK flag to the App Store target and all imports are gone.

We're really looking forward for dropping iOS 7 support asap...

Okay, I think that's what I expected. Thanks for confirming!
Thanks again!

@fluidsonic One last question: trying to push my podspec to a private spec repo, and its failing with the transitive static dependency error. How can I circumvent that (given that the pre_install hook hack is Podfile only)?

Okay, we're done with iOS 7 support in our app and will drop it now!

3550 seems to have broken the approach to use use_frameworks! for one target and use_frameworks!(false) for other targets. CocoaPods now always uses frameworks which will break for use_frameworks!(false) builds because the frameworks are built but never copied nor does the App Store support the frameworks on iOS 7.

We might get around the problem by using deduplicate_targets: false mentioned in the release notes but for some stupid reason this must be set by each developer on their own machine instead of just in the Podfile. We're not investing any more time in making our app iOS 7 compatible.

Anyway that deduplication bug is not related to this GitHub issue and such a discussion should take place in the related issue. I primarily post it here as an important follow-up for @mhuusko5.

@fluidsonic having issues with the..

s.pod_target_xcconfig = {
        'FRAMEWORK_SEARCH_PATHS' => '$(inherited) $(PODS_ROOT)/Crashlytics',
        'OTHER_LDFLAGS'          => '$(inherited) -undefined dynamic_lookup'
    }

.. method, where my project builds fine for simulator/device, but get a symbol not found (from the static library) error at runtime when targeting device.

Ever run into this?

It appears that the framework is in fact being loaded, and classes of that framework are accessible. The only things inaccessible/causing the crash are "FOUNDATION_EXPORT"s.

Anyone have any idea why CP would successfully link a static library, but not some of its exported string variables?

What exactly is not found? What does the log say?

It was some random NSString consts. Ended up fixing this yesterday, and while I'm at it, completely avoiding the need for..

s.pod_target_xcconfig = {
    'FRAMEWORK_SEARCH_PATHS' => '$(inherited) $(PODS_ROOT)/FRAM_NAME',
    'OTHER_LDFLAGS' => '$(inherited) -undefined dynamic_lookup'
}

.. and..

pre_install do |installer|
    # workaround for https://github.com/CocoaPods/CocoaPods/issues/3289
    def installer.verify_no_static_framework_transitive_dependencies; end
end

.. by creating a pod for the framework as follows...

Pod::Spec.new do |s|
  s.name = 'Spotify-iOS-SDK'
  s.module_name = 'Spotify'
  s.summary = 'The new Spotify iOS SDK.'
  s.version = '0.10.3'
  s.license = { :type => 'proprietary', :text => 'https://developer.spotify.com/developer-terms-of-use/' }
  s.author = { 'Spotify' => 'https://developer.spotify.com/' }
  s.homepage = 'https://developer.spotify.com/technologies/spotify-ios-sdk/'
  s.platform = :ios
  s.ios.deployment_target = '7.0'
  s.requires_arc = true
  s.framework = 'Foundation', 'AVFoundation'
  s.source = { :http => 'https://github.com/spotify/ios-sdk/archive/beta-10.zip' }

  # The goods

  s.pod_target_xcconfig = {
    'OTHER_LDFLAGS' => '$(inherited) -ObjC'
  }

  s.preserve_paths = 'ios-sdk-beta-10/Spotify.framework/Spotify'

  s.prepare_command = 'touch Empty.m && cp ios-sdk-beta-10/Spotify.framework/Spotify libSpotify.a && cp ios-sdk-beta-10/Spotify.framework/Headers/* .'

  s.source_files = 'Empty.m', '*.h'
  s.public_header_files = '*.h'

  s.vendored_libraries = 'libSpotify.a'
end

Another working example of this method (the one I yanked it from), is Firebase as of a couple days ago: https://github.com/CocoaPods/Specs/blob/master/Specs/Firebase/2.4.1/Firebase.podspec.json

Anyway, so it behaves perfectly with use_frameworks! or not, as a direct or transitive dependency, with Swift or Obj-C. Very nice and tidy.

Will report back if I end up having any issues. Have done sim/device builds, haven't tried a TestFlight build or App Store submit, but I'm not expecting issues. In the case of Firebase, their static lib is even bitcode enabled, and it behaves appropriately bitcode wise when used as a direct or transitive dependency.

0.39.0.rc.1 seems to break everything again. Getting a bunch of undefined symbol errors from transitive library pods, when compiling.

Has the way static libraries are treated changed?

@mhuusko5 please open a new issue with the information requested in the contributing guidelines

@mhuusko5 Same here. Tried your solution, all good for simulator builds, but getting errors like this when building for device:

Undefined symbols for architecture arm64:
  "__mh_execute_header", referenced from:
      -[DeviceInfo executableUUID] in libSplunkMint.a(DeviceInfo.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I'm trying to include dynamic framework into the project, which uses SplunkMint static framework/library as a transient dependency.

Have you opened a new issue to track this one?

I'm using 1.0.0.beta5 at the moment.

@mhuusko5 @fluidsonic have you find a definitive way of including a dependency on a podfile to a pod that has a dependency with static framework?

@matynz I don't think there is a definitive solution for this issue.
It always depends on the Pods you're trying to use and how you want to use them.
Google & Firebase Pods for example are total pain to use with dynamic frameworks. And the workarounds only work if you use each static framework/library in only a single Pod and not from multiple Pods.

Our app has two static dependencies left: AppsFlyerFramework and GoogleAnalytics. They're both linked to and used inside a sub-Pod of our app instead of from the app target directly. That way we can abstract our tracking logic through our sub-Pod(s).
We used to have a lot more static frameworks but less and less were necessary over time.

All the hacks & workarounds we did in order to use them along our dynamic frameworks are doing fine in production for more than a year now.
We'll continue to use them until we no longer need any static frameworks. We don't accept that static dependencies prevent us from using dynamic frameworks which would in turn prevent us from building a well-structured modularized app (and Swift still requires dynamic frameworks).

We're currently using these workarounds:

Podfile: Disable CocoaPod's check for transitive static dependencies.

pre_install do |installer|
    # workaround for https://github.com/CocoaPods/CocoaPods/issues/3289
    def installer.verify_no_static_framework_transitive_dependencies; end
end

Podfile: Make sure the static frameworks are not linked to the app itself by editing the generated xcconfig files. We link the static frameworks directly to the Pod which needs them. Note that while the Pod is called AppsFlyerFramework the actual framework is named AppsFlyer.

post_install do |installer|
    project = installer.pods_project

    installer.aggregate_targets.each do |target|
        project.build_configurations.each do |build_configuration|
            configFilePath = target.xcconfig_path(build_configuration.name)
            configFile = File.read(configFilePath)
            configFile = configFile.gsub(/-framework "AppsFlyer" /, '')
            configFile = configFile.gsub(/-framework "GoogleAnalytics" /, '')
            File.open(configFilePath, 'w') { |file| file << configFile }
        end
    end
end

We've also made our own .podspec for the GoogleAnalytics Pod which turns the static library into a static framework since Swift can only work with frameworks/modules:

GoogleAnalytics.podspec:

{
    "name": "GoogleAnalytics",
    "version": "3.14.0",
    "summary": "Google Analytics - measure your app performance",
    "description": "Google Analytics lets you track application events you care about and gain insights from discovery and installation to conversion and engagement",
    "homepage": "https://www.google.com/analytics",
    "license": {
        "type": "Copyright",
        "text": "Copyright 2015 Google Inc."
    },
    "authors": "Google, Inc.",
    "platforms": {
        "ios": "5.0"
    },
    "vendored_frameworks": [
                           "GoogleAnalytics.framework"
                           ],
    "frameworks": [
                   "CoreData",
                   "SystemConfiguration"
                   ],
    "libraries": [
                  "sqlite3",
                  "z"
                  ],
    "source": {
        "http": "https://www.gstatic.com/cpdc/69fd9fe84a8fea60-GoogleAnalytics-3.14.0.tar.gz"
    },
    "prepare_command": "mkdir -p GoogleAnalytics.framework/Modules && mv Headers/Public GoogleAnalytics.framework/Headers && mv Libraries/libGoogleAnalytics.a GoogleAnalytics.framework/GoogleAnalytics && echo 'framework module GoogleAnalytics {\n  umbrella header \"GoogleAnalytics.h\"\n\n  export *\n  module * { export * }\n}' > GoogleAnalytics.framework/Modules/module.modulemap && echo '#import \"GAI.h\"\n#import \"GAIDictionaryBuilder.h\"\n#import \"GAIEcommerceFields.h\"\n#import \"GAIEcommerceProduct.h\"\n#import \"GAIEcommerceProductAction.h\"\n#import \"GAIEcommercePromotion.h\"\n#import \"GAIFields.h\"\n#import \"GAILogger.h\"\n#import \"GAITrackedViewController.h\"\n#import \"GAITracker.h\"' > GoogleAnalytics.framework/Headers/GoogleAnalytics.h && rm -rf Headers Libraries"
}

Last but not least we had to update the .podspecs of our sub-Pods which need these libraries. This one for example needs the AppsFlyerFramework pod:

Pod::Spec.new do |s|

    # omitted some properties not relevant for the workaround

    s.frameworks = 'AppsFlyer' # make sure the framework is linked to this Pod directly
    # note that you must also link all transitive dependencies of the static framework too, should it need some (e.g. SystemConfiguration framework, sqlite3, zlib)

    s.dependency 'AppsFlyerFramework' # obviously

    # add the static framework to the framework search path so that you can actually use it
    s.pod_target_xcconfig = {
        'FRAMEWORK_SEARCH_PATHS' => '$(PODS_ROOT)/AppsFlyerFramework'
    }
end

Again, the solution depends a lot on the static Pods you want to use and on the Pods using them.

HTH

Any update to this?

I was curious about why can't just embed the static lib in the lower most framework depend on it.
If only one framework direct depend on the lib, this solution works well.
If two or more framework depend on it, then can extract a intermediate framework direct depend on the lib.

Can anyone detailed point out shortcomings of this solution?This will break the Module Header?

Or dynamic generate a intermediate framework from the static lib, then referenced by other lib or framework.

I have a A.framework which i am using in my swift app Test.

A.framework has a podspec which has s.dependency = 'Crashlytics' which is a static framework.

Now when i do pod install on swift app Test, in Test's podfile i have to write below since i am using static framework:

pre_install do |installer|
# workaround for https://github.com/CocoaPods/CocoaPods/issues/3289
def installer.verify_no_static_framework_transitive_dependencies; end
end
Now when i compile Test, it give me 'Crashlytics, file not found error'. If i manually go to Test->Pods->A->Link binary with library->browse and add crashlytics.framework, error goes away.

How can i add a run script which will automate this manual step for me.

Thanks.

@jamehta to achieve that we add the relevant info to our framework's .podspec.
Note that you must also include all frameworks and libraries used by Crashlytics since CocoaPods will not add these to the Pod too,

s.frameworks = 'Crashlytics', 'Security', 'SystemConfiguration' # plus other frameworks you use
s.libraries = 'c++', 'z'

s.pod_target_xcconfig = {
    'FRAMEWORK_SEARCH_PATHS' => '$(inherited) $(PODS_ROOT)/Crashlytics/iOS'
}

In addition we have to prevent CocoaPods from linking the static framework to the main binary or otherwise Crashlytics would be linked twice, which can result in weird problems.

in Podfile:

pre_install do |installer|
    # workaround for https://github.com/CocoaPods/CocoaPods/issues/3289
    def installer.verify_no_static_framework_transitive_dependencies; end
end


post_install do |installer|
    project = installer.pods_project

    # prevent frameworks which they are already linked with a module from being linked with the main target again
    installer.aggregate_targets.each do |target|
        project.build_configurations.each do |build_configuration|
            configFilePath = target.xcconfig_path(build_configuration.name)
            configFile = File.read(configFilePath)
            configFile = configFile.gsub(/-framework "Crashlytics" /, '')
            File.open(configFilePath, 'w') { |file| file << configFile }
        end
    end
end

@fluidsonic i already tried this. s.frameworks adds Crashlytics to link binary build phase but it has some weird path for Crashlytics.framework which is Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/Crashlytics.framework. When i re-add manually by clicking + sign in link binary build phase of Testapp->Pods->A->Build Phase->Link binary with library and selecting Crashlytics.framework from Test app->Pods->Crashlytics->iOS->Crashlytics.framework, it works fine but automatically it does not. also i have to use below:
'FRAMEWORK_SEARCH_PATHS' => '$(inherited) $(PODS_CONFIGURATION_BUILD_DIR)/Crashlytics'

if i use '$(inherited) $(PODS_ROOT)/Crashlytics', after pod install when i go and check TestApp->Pods->A->Build Settings->Framework search path, it overrides all the other entries of my dependencies mentioned in A's podspec and just have two entries 1) inherited 2) PODS_ROOT/Crashlytics.

also found that s.frameworks is for system frameworks and crashlytics is not system framework. not sure if it is the right thing to use. may b that is the reason it is not adding right .framework ?
I also tried s.vendored_frameworks = 'Crashlytics.framework', 'Fabric.framework', 'Applause.framework' but no luck.

@jamehta I've added the missing $(inherited) to my comment.

The path you mentioned is not the one used by CocoaPods. It's likely the one where the Crashlytics Mac App installed the Crashlytics framework. Don't use that path!
Also do not add any framework manually to your own Pod. Let CocoaPods do all the work.

s.frameworks works for any framework - not just system frameworks, as long as the framework can be found using FRAMEWORK_SEARCH_PATHS.

When you applied all changes I've posted above, what error do you get and what is the content of the directory <your project>/Pods/Crashlytics?

error i get is when i use above code:

screen shot 2017-05-10 at 2 25 31 pm

also i dont see "Crashlytics" under /Pods/Crashlytics folder. but using s.frameworks as 'Crashlytics' i see that in my Testapp->Pods->A->Build Phase->Link binary with library as seen in attachment below(i have not added this entry for crashlytics but it was automatically added due to s.frameworks addition in podspec).

screen shot 2017-05-10 at 2 32 37 pm

As you see in screenshot above path that it takes is weird. that is the reason build fails with crashlytics not found since right framework file is not added.

lol, stupid Crashlytics Pod! Why can't they just release it Open Source…

The path is wrong. It should read like that in the podspec:

s.pod_target_xcconfig = {
    'FRAMEWORK_SEARCH_PATHS' => '$(inherited) $(PODS_ROOT)/Crashlytics/iOS'
}

(updated by complete comment above)

'FRAMEWORK_SEARCH_PATHS' => '$(inherited) $(PODS_ROOT)/Crashlytics/iOS'

OR

'FRAMEWORK_SEARCH_PATHS' => '$(inherited) $(PODS_ROOT)/iOS/Crashlytics'

Tried both without luck.

i still feel problem is with the path of crashlytics that is added in link binary phase. it has weird path
as seen below: from where is it taking this path and why it is taking wrong path ?

screen shot 2017-05-10 at 3 15 48 pm

so i still see the same erorr.

My test project I've just created works fine with my latest change.

Is there a Crashlytics framework at that weird location?

Still the same error?

What code is causing the error?

Can you post your Podfile and podspec please?

I am using cocoapods-1.2.1

This is my podfile:

source 'https://github.com/CocoaPods/Specs'

platform :ios, 8.0
project 'App'

use_frameworks!
inhibit_all_warnings!
target 'App' do
    pod 'Activity', '0.0.6'
end

target 'AppTests' do
end

pre_install do |installer|
    # workaround for https://github.com/CocoaPods/CocoaPods/issues/3289
    def installer.verify_no_static_framework_transitive_dependencies; end
end

post_install do |installer|
    project = installer.pods_project
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings['ENABLE_BITCODE'] = 'NO'
            config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = ""
            config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
            config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
            config.build_settings['CLANG_ENABLE_OBJC_WEAK'] ||= 'YES'
            config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '8.0'

        end
    end

    installer.aggregate_targets.each do |target|
        project.build_configurations.each do |build_configuration|
            configFilePath = target.xcconfig_path(build_configuration.name)
            configFile = File.read(configFilePath)
            configFile = configFile.gsub(/-framework "Crashlytics" /, '')
            File.open(configFilePath, 'w') { |file| file << configFile }
        end
    end

end

Below is my podspec:

Pod::Spec.new do |s|
s.name      = "Activity"
s.version   = "0.0.6"
s.summary   = "Activity"
s.homepage  = "https://github.com/jamehta/Activity"
s.author    = "PayPal"
s.platform  = :ios, "7.0"
s.source    = { :git => "https://github.com/jamehta/Activity.git", :tag => "0.0.2" }
s.dependency  'ActivitySdk', '0.0.4'
s.source_files = 'Activity/**/*.swift', 'Activity/Activity.h'
s.frameworks = 'Crashlytics', 'Security', 'SystemConfiguration'
s.libraries = 'c++', 'z'
s.pod_target_xcconfig = {
        'FRAMEWORK_SEARCH_PATHS' => '$(inherited) $(PODS_ROOT)/Crashlytics/iOS'   
    }
end

Your podspec lacks an s.dependency for Crashlytics ;)
Add it!

@fluidsonic thanks for helping out !! may b i lost it in back and forth changes to attempt the solve.

@fluidsonic You mind helping me diagnose a similar problem? I am using a pod called AnalyticsKit which allows for reporting analytics to multiple providers with little effort and most of the providers have their own static framework like Crashlytics/Intercom for example. AnalyticsKit is made up of various subspecs for each provider along with Core I am trying to add a few subspecs to my app and I had everything building at one point but then was getting runtime errors when Crashlytics was trying to be initialized in the appDidLaunch. Here is the AnalyticsKit CocoaPod (My own fork) where you can look at the podspec and this is what I have in my Podfile for my app that also depends on Crashlytics:

target 'AppTarget' do
    platform :ios, '9.0'

    pod 'Crashlytics'
    pod 'Intercom'
end

pre_install do |installer|
    def installer.verify_no_static_framework_transitive_dependencies; end
end

post_install do |installer|
    project = installer.pods_project

    installer.aggregate_targets.each do |target|
        project.build_configurations.each do |build_configuration|
            configFilePath = target.xcconfig_path(build_configuration.name)
            configFile = File.read(configFilePath)
            configFile = configFile.gsub(/-framework "Crashlytics" /, '')
            configFile = configFile.gsub(/-framework "Intercom" /, '')
            File.open(configFilePath, 'w') { |file| file << configFile }
        end
    end
end

I currently am getting errors such as this now in my app target:
screen shot 2017-05-22 at 12 35 43 pm

@kdawgwilk : [EDIT] In case it helps the Linker Errors are due to the absence of _Fabric_ framework in the base podspec... .

Was this page helpful?
0 / 5 - 0 ratings