Create CocoaPod with OpenSSL-Universal as Dependency - ios

I'm trying to create a CocoaPod that has OpenSSL-Universal as a dependency. Whenever I go to the auto-generated Example subfolder and run pod install, I get the following error message:
[!] The '…' target has transitive dependencies that include static binaries: (…/Example/Pods/OpenSSL-Universal/lib-ios/libcrypto.a and …/Example/Pods/OpenSSL-Universal/lib-ios/libssl.a)
This error is not there when I remove use_frameworks! from the Podfile in this directory. However, I have another project, a Swift project, which has OpenSSL-Universal as a dependency, and because it's a Swift project, use_frameworks! is present in its Podfile. And yet somehow, it manages to perform pod install with no issues.
I've been trying to create both Swift and Objective-C CocoaPods with the OpenSSL-Universal dependency, and yet to no avail. There are other Pods, however, such as CoreBitcoin, that do have it as a dependency, and they, too, can be included in my Swift projects with use_frameworks!. However, when I try to use CoreBitcoin as a dependency in my own CocoaPod instead of OpenSSL-Universal, the same error is thrown as above, also for OpenSSL-Universal.
How do I make my own CocoaPod with that dependency? What am I doing wrong? I haven't changed any other default settings except for experimenting with the presence of the use_frameworks! flag in the auto-generated example subdirectory.

Related

The 'Pods runner target has transitive dependencies that include statically linked binaries (Users/..../LibraryX/LibraryX.framework)'

I'm building a Flutter Plugin for a native only available SDK . When it comes to the swift part, I've specified the pod in the .podspec file and now when I try to pod install in the Plugin's example app , I'm getting the above error . If the use_frameworks! is commented in the example app's Podfile , The error disappears but when present the error again arises.Also the same error does not come when putting the pod in the Podfile of the example app even with use_frameworks! directive. But I need to install it through the Plugin's .podspec file. I've also tried using s.static_framework=true and it works but an another error arises which is 'Include of non-modular header inside the framework module(Users/../LibraryA/LibraryA.framework/Headers/Xyz.h)' and couldn't solve this issue too.
What does the error exactly mean? Does it mean that the pod I'm trying to install is itself a static library or does it contain any static libraries as dependency?
Also why it gets installed when trying to install the pod in the Podfile with use_frameworks! but not in the .podspec file?
What are the ways through which I can fix this issue?

Install native iOS pod in flutter

I am facing an error while making a flutter plugin on the iOS side while using pods. The pods are installed successfully then also I am able to import them in the file.
The pod in my case which I am trying to use is Freshchat iOS SDK
Steps I have followed to install the pod
Start a new Flutter plugin project.
In .podspec file add s.dependency 'FreshchatSDK'
Run pod install in example/ios folder.
I got an error
The 'Pods-Runner' target has transitive dependencies that include statically linked binaries: (/Users/nimish/FlutterProjects/freshchat_flutter/freshchat_flutter/example/ios/Pods/FreshchatSDK/FreshchatSDK/libFDFreshchatSDK.a)
I removed use_frameworks! from podfile following this comment .
I ran pod install again and the pods were successfully installed and Pods folder was created which had FreshchatSDK folder in it.
Now I need to have use_frameworks! in my project because other plugins are not compiling because of this.
I added s.static_framework = true in .podspec and use_frameworks! in podfile. Now pod install ran successfully,
After I added the import #import "FreshchatSDK.h" in my Plugin.h file I got the error
error: include of non-modular header inside framework module
I tried this answer but was not able to resolve it.
Please help me resolve this. I'll be respectful of your time.
There is another flutter plugin available here but it has many issues and one unhandled case is making my iOS app crash so I want to make it my own.
There may be problems in the PodFile due to unmatched Targets.
When this happens to me, I used these simple steps.
Delete Podfile
Open Terminal at the specific file
Pod init
Open Podfile and adds Dependencies
Pod install

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.

Transitive dependencies on Cocoa Pod

I have an iOS Project with some third party dependencies and some of them are written in Swift. Due to that i have the flag use_frameworks! in my Podfile .
The problem occurs when I try to install AppRTC framework. AppRTC has a reference to a static library and pod install fails with the following error:
[!] The 'Pods-X' target has transitive dependencies that include static binaries: (/.../libjingle_peerconnection/libWebRTC.a)
This tutorial explains an approach to overcome this problem by placing a modified version of the podspec file for the pod where the static library resides.
https://blog.sabintsev.com/importing-c-static-libraries-into-a-swift-project-using-cocoapods-a53993c3a2ca#.fo7l8rqxi
I created a custom pospec for AppRTC and set s.vendored_libraries but I couldn't make it work.The pod dependencies of my project look like this.
If i install libjingle_peerconnection (where the static library is) and SocketRocket explicitly with cocoa pods, i do not get any error.I a only add AppRTC to my pod file i get the mentioned error.
Question 1) To which project shall i include the custom podspec?
Question 2) Do i need to install the pods separately?
|MyProject|
/ \
.... AppRTC
/ \
|SocketRocket| |libjingle_peerconnection|

Using cocoapods in a framework

I created an iOS framework that uses a library (RestKit) via CocoaPods.
In the application project that uses my framework I also use CocoaPods to include other libraries. I had to include the library from the framework as the project didn't compile otherwise.
Everything works fine, but as expected when I launch the application I get:
Class X is implemented in both /private/var/mobile/Containers/Bundle/Application/[...]/Application.app/Frameworks/Framework.framework/Framework and /private/var/mobile/Containers/Bundle/Application/[...]/Application.app/Application. One of the two will be used. Which one is undefined." in several classes from the libraries.
Is there any way in CocoaPods or in the build process to prevent having duplicate libraries when they're already being used?
Some more context to my question. Here's what I did:
Created a framework project as a Cocoa Touch Framework. Initially I added just a Podfile with a dependency for RestKit as following:
pod 'RestKit', '~>0.23'Then I removed the Podfile and just added a podspec as in the comment by #Paula Chavarría.
Created the app project. Added a Podfile with other dependencies and also the dependency to the framework as #Paula Chavarría also mentioned.
When I build the app project the framework fails building because it can't find the right headers.
I changed the header search path for the framework but it doesn't seem to be enough for the build to be successful.
Do I need to have also a Podfile in the framework? As I said in my original question, I did that at first and I ended up having duplicate libraries and that's what I'm trying to avoid in the first place.
Is there any way to tweak the Podfile or the configurations generated by it and use the headers in the app and link with the libraries in the app?
What am I missing here?... Thanks in advance! :)
If you are using Cocoapods on the application project you can create a private pod for the iOS framework. To do so you have to create a .podspec file in order to add the conflicting dependency. For Restkit the .podspec file would be like this:
Pod::Spec.new do |s|
s.name = "MyFramework"
...
s.dependency 'RestKit', '~> 0.23'
end
You can read more about these files here: http://guides.cocoapods.org/making/specs-and-specs-repo.html
After that you just have to add a dependency of your framework on the application project Podfile. You can do so through a local path or through a version control system.
pod 'MyFramework', :path => './../my-framework'
pod 'MyFramework', :git => 'https://url/to/my-framework.git', :tag => '0.0.1'

Resources