How to make a custom pod library depending on Firebase pods? - ios

I have a very simple swift 3 pod library depending on Firebase pod. It has been created with pod lib create and the only line of code in the library is import Firebase. Still, Firebase does not seem to be detected.
-> FoobarLib (0.1.0)
- ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code. You can use `--verbose` for more information.
- ERROR | [iOS] xcodebuild: ~/FoobarLib/Classes/Foobar.swift:1:8: error: no such module 'Firebase'
I suppose my .podspec file is not properly configured. I have tried a simple pod dependency with s.dependency Firebase and I have tried to embed the Firebase frameworks in my library. I have played with FRAMEWORK_SEARCH_PATHS, USER_HEADER_SEARCH_PATHS, SWIFT_INCLUDE_PATHS, but I never got something working.
My sample library is hosted on github and the full error log is available on Travis. Feel free to clone it, and test pod lib lint and pod install --project-directory=Example.
I saw this related cocoapods bug report involving cocoapods guys and firebase guys, but there is no working example in it.
What should I put in my .podspec file so:
pod install --project-directory=Example succeeds, and produces a valid XCode project. i.e. I can open it, compile it without further configuration.
pod lib lint succeeds, optionally

Even if you manage to get pod lib lint to pass, you'll run into issues integrating Firebase as a dependency of a dependency because it's currently vended as a static library. FirebaseUI works around this by distributing binaries instead of having CocoaPods build from source, but it's not without its own caveats (i.e. people who use FirebaseUI cannot also use another library that depends on Firebase and correctly resolve the version of Firebase that should be used). The issue you linked discusses this in more detail.
If you would really like to distribute a library that wraps Firebase through CocoaPods, you should follow the same approach, though it's worth noting that pod lib lint fails for FirebaseUI even though it ships anyway.
CocoaPods will soon (as of Oct 2017) add a rule that allows for static frameworks to be built on top of other static frameworks, including closed-source ones. This will make it much easier to build objc libs on top of other closed static objc libs, but Swift static library support is still in the works.

Related

Working with both SPM and Cocoapods in the same project

I have an Xcode project, consisting of a swift packages, a custom cocoa pods and one target dependency.
In workspace I have:
Project ProfileUtil - xcode project of type Framework. This project contains Firebase SPM dependencies
Project DatabaseUtil - xcode project of type cocoapod. This project contains Firebase pods dependencies
Project MeditationApp - Xcode project of type iOS Application. This is the main application, and it should include ProfileUtil as a framework swift packages, and DatabaseUtil as a Pod
When I try to compile the main iOS application, Im seeing errors like:
Error: Redefinition of module 'Firebase'
module Firebase {
export *
header "Firebase.h"
}
So that got me wondering if I can mix both SPM and Cocoapods in the same project if both uses the same library internally? (I couldn't find any useful ressources online about that use case, which surprise me)
Is there a bypass I could do to fix those, because as in the moment I have to keep my custom pod DatabaseUtil as a cocoapods.
Nope. Firebase does not support being installed from both CocoaPods and Swift Package Manager in the same project. It might be possible to hack into place by hacking the workspace after a CocoaPods install, but it would be fragile.

Can't add Mapbox and MapboxNavigation SDK

In order to implement Mapbox SDK, according to official docs (https://docs.mapbox.com/ios/maps/overview/#install-the-maps-sdk,
https://docs.mapbox.com/ios/navigation/overview/), adding Mapbox-iOS-SDK and MapboxNavigation through Cocoapods, always get error, shown bellow.
I thought this is related to the usage of sourcery or SwiftGen which are the parts of project or something else, but this happened on new, clean project also, where inserting SDKs was the first step.
Cleaned derived data for few times,
remove from Podfile versioning for that SDK (pod 'Mapbox-iOS-SDK', '~> 6.0.0' as pod 'Mapbox-iOS-SDK' )
even when SDK is added through CocoaPods, can't find frameworks to add into Link Binary With Libraries
even it says Copy Bundle Resources to be checked, couldn't find what to expect there
Note:
Also tried: successfully added Mapbox and MapboxMobileEvents directly into project, but as I found MapboxNavigation SDK could be implemented only through CocoaPods or Carthage, so I'm stuck here.
I would really appreciate for someone's help, who already have faced this problem.
Multiple commands produce '/Users/x/Library/Developer/Xcode/DerivedData/mbNavigationExample-ctztmwiegsuqkigkucoydhnnoaxc/Build/Products/Debug-iphoneos/mbNavigationExample.app/Assets.car':
1) Target 'mbNavigationExample' (project 'mbNavigationExample') has compile command with input '/Users/x/Desktop/mbNavigationExample/mbNavigationExample/Assets.xcassets'
2) That command depends on command in Target 'mbNavigationExample' (project 'mbNavigationExample'): script phase “[CP] Copy Pods Resources”

Getting "Module not found" when building 3rd party framework that depends on a CocoaPods module

Here is my situation:
I am using CocoaPods but I can't use the "use_frameworks!" directive as it is not compatible with ReactNative
I need to include another team's SDK, distributed as a .framework
This .framework depends on PureLayout, which is available through Pods
Hence:
I installed PureLayout through Pods.
I manually linked the other team's SDK dragging it into Embedded Binaries, as per their instructions
Build fails with error Module 'PureLayout' not found. It seems that the other team's framework isn't able to find the PureLayout module included through Pods.
How can I fix? Remember I can't use_frameworks! in Podfile. Thanks.

Using a CocoaPod dependency while developing a CocoaPod

I'm creating a CocoaPod, say MyPod, which depends on another Cocoapod, say RxSwift.
So I have this in MyPod.podspec:
s.dependency "RxSwift", "~> 3.0.1"
However, while developing MyPod, how can I actually use the dependency?
import RxSwift
// ^
// No such module 'RxSwift'
public class MyClass { //...
Is there a step I'm missing, or some common convention? It looks like some other projects like Moya are using Carthage to build dependencies while developing. Should I be doing that, or maybe adding a Podfile?
I know that this shouldn't be a problem for an Example App located within the repo, which would have its own Podfile. However, I'd like to still have tests located at top level, outside of the Example App, and to be able to actually build the framework while working on it, again, outside of an Example App.
I can't speak to whether or not to use CocoaPods or Carthage. Both have their strong points and weak points. Plus the decision should be made considering many factors, some of which you might not be able to control (like a client that insists you use CocoaPods!) So I'll skip that part.
However, to your question, indeed a pod you are developing can depend on another pod. You already have the correct s.dependency line. That's necessary.
However, I suspect that the reason why you were not able to reference the dependent pod could be because you did not have a Podfile in your 'tester/example' project and/or you did not do a pod install after adding the dependency in your Podspec.
The reason for this is requirement I suspect is that since the Podspec is not actually processed at all by Xcode, you're not actually downloading (or compiling) the dependency.
Instead, when you do the pod install (via command line of course), CocoaPods will create a Pods project with your development pod, the pods you depend on (in Podspec) as well as any other pods in your Podfile.
To test this theory, I:
Created a new pod (using CocoaPod's own 'pod lib create' (https://guides.cocoapods.org/making/using-pod-lib-create.html).
Opened the workspace that CocoaPod created for me and edited the Podspec to add the dependency s.dependency 'RxSwift', '~> 3.0.1'.
Added another pod in my Example App's Podfile (to demonstrate the difference between Podfile dependencies and Podspec dependencies.)
Performed pod install in the Example App's folder.
Edited my Pod's class to do something useful AND to add the import RxSwift line.
Added a label to my Example App ("Hello World" of course).
Used PureLayout to do all the auto layout constraints for the label (and to demonstrate how the Example project has access to both pods - the development pod as well as the referenced pod PureLayout.)
You can check out the demo I created on my public GitHub:
https://github.com/ericwastaken/CocoaPod-Dependency-Demo
Honestly, I've created several pods using the pod lib create and it does indeed create a nice structure that has always worked for me. For this reason, I would recommend always using it to create your pod's skeleton.
Xcode 8 comment: pod lib create still seems to create a Swift 1.x project. So, right after you use this tool, when you open Xcode, you'll be offered to "convert" to a newer version of Swift. I would let that conversion happen right then and there (the first time) so that you can be in Swift 2.x or 3.x syntax (you choose).
I ended up using Carthage to build the framework dependencies. I imagine I could have used CocoaPods to do it as well. However, that would have required that I start using a workspace, and I didn't want to have to do that so as to keep changes as minimal as possible.
Also, with Carthage, it didn't require that I add a new Podfile/Podfile.lock, since Carthage will use the existing Cartfile/Cartfile.resolved that's already there. That's because Carthage uses the Cartfile.resolved when using the framework in another project and when building the framework on its own. Whereas, with CocoaPods, *.podspec is used when using the framework in another project but Podfile.lock (if you've added a Podfile) is required to install dependent pods in the framework itself.
This was a very challenging problem to solve, and required a combination of a few solutions pieced together. #EricWasTaken's solution helped, as well as adding:
source 'https://github.com/CocoaPods/Specs.git'
to the top of my Podfile. Then navigating to the Example app and run
pod repo update
pod install
Now the framework I am creating can find the cocoapods my framework requires.

Cocoapods "use_frameworks!" with Google Analytics and Swift libraries

I've been using use_frameworks! directive so that I can use some dependencies on my project. If I comment that directive, I get a red message saying
Pods written in Swift can only be integrated as frameworks; this feature is beta. Add 'use_frameworks!' to your Podfile or target to opt into using it.
Today I decided to use Google Analytics for iOS but when running $pod install I get
The 'Pods-MyProject' target has transitive dependencies that include static binaries
Googling around I found out it is caused because of the use_frameworks! directive and I should remove it. So I'm between a wall and a sword, what can I do to be able to work with these libraries?
PS: We are required to manage dependencies using Cocoapods, so including it in a different way is not an option. Also, I don't have a bridging header in my project, but I'm still able to work with libraries using import MyDependency

Resources