简体   繁体   中英

How to import a package's dependency when using Swift Package Manager?

I started a new Xcode Project. I imported a package using Swift Package Manager (eg Quick ).

I see Quick in the sidebar in Xcode.

I can now use Quick by first importing it:

import Quick

Everything works great with Quick.


I noticed that in the sidebar of Xcode, when I imported Quick, it automatically imported its dependencies (eg Nimble ).

I assumed I could start using this dependency by importing it, however that lead to an error:

import Quick
import Nimble // ❌ No such module 'Nimble'

If I try omitting the import and just using a line of code from Nimble directly, I get an error as well:

expect(1 + 1).to(equal(3)) // Use of unresolved identifier 'expect'

How do I use Nimble in my project?


I'm guessing one way to resolve this is to explicitly add the Nimble package via Swift Package Manager too.

However, this seems wrong because:

  1. I already have the source code for Nimble in my Xcode project
  2. I don't want version mismatches between the explicit Nimble version that I get from Swift Package Manager, and the implicit Nimble I get from Quick.

How do I import a package's dependency when using Swift Package Manager?

To use Nimble in your project, you have to install it in the same way as Quick, using the SPM. and you can import Quick in your class

1- The SPM only downloads the dependencies once, obviously of the same version or range.

2- You must control the version, setting the dependencies in the same range of versions.

Swift package manifest has product field that can be used by library authors to declare build artifacts available to client:

A package product defines an externally visible build artifact that's available to clients of a package. The product is assembled from the build artifacts of one or more of the package's targets

Whenever you are using a package you have the choice of importing targets that are used by these declared products. Let's suppose you have packege A which has product B and in product B targets C and D are exposed, when using A you can import C and D .

Now, Let's suppose package A uses package E 's target F and G in C and D respectively. In this scenario using package A also makes F and G from package E available to your project.

Now let's consider your scenario: you are using package Quick 's product Quick which exposes target Quick and you can import Quick without any issue. Although package Quick is using package Nimble internally in its test targets it doesn't use Nimble in Quick target which is what the package exposes publicly and you are using. To use Nimble you have explicitly add Nimble package.

However, this seems wrong because:

  1. I already have the source code for Nimble in my Xcode project
  2. I don't want version mismatches between the explicit Nimble version that I get from Swift Package Manager, and the implicit Nimble I get from Quick.

I would say this behavior is correct and should be expected. Dependency managers allow dependency authors to specify their dependecy with proper constraints and author of Quick has specified that their public target Quick doesn't have any dependency on package Nimble and any of its targets. This gives you the flexibility of independently choosing version constraints of packages Quick and Nimble which you would expect since their author has told SPM that they are independent.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM