59

I have a public fork of a library that already exists in CocoaPods/Specs. In a Podfile, I can reference this forked pod by doing this:

pod 'CoolLibrary', :git => 'git@github.com:myname/CoolLibrary-Forked.git', :commit => 'abcdef1234567890abcdef1234567890'

I tried putting this in my MyLibrary.podspec:

s.dependency 'CoolLibrary', :git => 'git@github.com:myname/CoolLibrary-Forked.git', :commit => 'abcdef1234567890abcdef1234567890'

But get the following error message:

-> MyLibrary.podspec
 - ERROR | The specification defined in `MyLibrary.podspec` could not be loaded.


[!] Invalid `MyLibrary.podspec` file: [!] Unsupported version requirements. Updating CocoaPods might fix the issue.

Is it possible to specify a dependency in a .podspec in this way (i.e. for a pod that has a podspec, but which isn't in CocoaPods/Specs)?

Nick Forge
  • 21,344
  • 7
  • 55
  • 78

2 Answers2

83

This is not allowed from podspecs, because allowing so would make it next to impossible for other podspecs to define what package they depend on and/or other packages could break because of unexpected API differences.

For instance, consider two pods that depend on AFNetworking, but one specifies an external source location (Pod A) while the other only specifies a minimum version requirement (Pod B):

  • Pod A: s.dependency 'AFNetworking', :git => 'https://arbitrary/location'
  • Pod B: s.dependency 'AFNetworking', '> 2'

Now there are a couple of potential problems:

  1. At this point we have no idea what version is in the ‘Pod A’ repo until we download it, which is a massive waste of time in case the various common dependencies on AFNetworking (e.g. ’Pod B’) can’t be satisfied.
  2. But what’s even worse is if ‘Pod A’ does match the dependency version requirement of other pods (e.g. ‘Pod B’), but the AFNetworking code is actually from a forked source location and it changes some essential API that ’Pod B’ depends on. This will silently break the promise that CocoaPods tries to make.

I hope this makes it clear why we cannot introduce a way for podspecs to silently break the version promises. However, from your Podfile you are allowed to override any pod’s source location, because it is the end-user (the app developer) who is in control and there should not be any unexpected breakage.

alloy
  • 20,908
  • 2
  • 30
  • 40
  • 4
    Good explanation. I understand the issue, but what's then the right way of doing that? Let's say I forked a repo because I need some changes. I cannot add it to Cocoapods under a slightly different name and put me as the author in the podspec. However I need it as s.dependency in another project that I have on Cocoapods. – Hons Jul 31 '14 at 16:45
  • 4
    @Hons By overriding the location of that pod **in your Podfile**, as the OP does with `CoolLibrary`, _before_ you specify any of the dependencies that actually depends on `CoolLibrary`. – alloy Aug 01 '14 at 21:06
  • 1
    I'll throw in my two bits: I like npm's approach. You may have multiple versions of the same library, but every library gets the dependency it wants. Shrink-wrap. CocoaPods is closer to how Bower does it. – funroll Aug 17 '14 at 14:28
  • That’s because of how JavaScript allows you to easily re-namespace, which is unfortunately not possible with Objective-C. We have a [plugin](https://github.com/CocoaPods/cocoapods-packager) meant for prebuilt-binary distribution which tries to re-namespace, but it’s not 100% guaranteed to work, especially not when making dynamic method calls. – alloy Aug 18 '14 at 10:09
  • 1
    @alloy How would you suggest we handle this issue with a private spec repository in our company? – Sascha Wolf Mar 18 '16 at 15:51
  • @alloy then how do I add a dependency which has :git => 'https://github.com/saty/somelib.git' – Saty Apr 18 '16 at 10:55
  • 2
    This is terrible design. Learn something from gradle. – Arunav Sanyal Jan 02 '17 at 01:43
5

Dependencies are very simple, having only the ability to define the name and the version specifier of an Pod. They cannot be extended with the same extensions as a dependency in the Podfile.

orta
  • 4,225
  • 1
  • 26
  • 34