Может ли пакет swift обеспечить поддержку других пакетов, не имея их в качестве зависимостей? - PullRequest
0 голосов
/ 04 марта 2020

Я делаю пакет и хочу предоставить некоторые расширения для другого пакета, если он включен в модуль, который использует мой пакет. Я думаю, что-то вроде:

#if canImport(PromiseKit)
import PromiseKit
// Perhaps some internal extension on a PromiseKit class, as a helper for below
// Some public extension on my class. This code will use PromiseKit.
#endif

Идея состоит в том, что если модуль-потребитель устанавливает мой пакет, и если у него тоже есть PromiseKit, то мой пакет обеспечивает некоторую поддержку PromiseKit. Кроме того, мой пакет вообще не нуждается в PromiseKit в качестве зависимости.

Изначально мне нужно пометить PromiseKit в качестве зависимости в моем Package.swift, чтобы Xcode мог установить его, поэтому я могу получить помощь по автозаполнению, когда написание расширений. Но если я оставлю это так, установка моего пакета все равно установит PromiseKit, потому что он помечает его как зависимость, что делает canImport избыточным.

Так что после написания кода внутри canImport я должен просто удалить зависимость от Package.swift?

Но затем, через некоторое время, если API PromiseKit изменится, модуль-потребитель, устанавливающий мой пакет, больше не сможет компилироваться, верно?

Есть ли хороший способ сделать это? Если пакет не имеет каких-либо зависимостей, но обеспечивает некоторую поддержку пакетов A, B, C, D, E, F, в идеале, если кто-то установил мой пакет, я не хочу, чтобы он также устанавливал все эти пакеты , Есть ли способ добиться этого? Или это то, что я пытаюсь сделать плохой практикой?


Обновлено:

Я обнаружил нечто очень странное. Моя стратегия была проста:

  1. Объявить зависимость
  2. Написать код поддержки для нее
  3. Удалить зависимость
  4. Подготовить ее в #if canImport(...)

Оказывается, это не сработает. Я знаю это, потому что я установил свой пакет в новый проект, а также установил PromiseKit, но мой код поддержки был недоступен, несмотря на многочисленные очистки, перестройки и перезапуск Xcode.

Это заставляет меня поверить, что код #if canImport(...) не запускается в контексте, который знает о среде нового проекта. Это запускается в каком-то другом контексте. В противном случае он обнаружит, что PromiseKit установлен, и этот код будет запущен, и его API будет доступен.

Обратите внимание, что если я объявлю зависимость PromiseKit в моем пакете и обновлю пакеты нового проекта, Xcode установит PromiseKit автоматически, и мой код поддержки становится доступным. Но тогда #if canImport(...) по существу избыточен, и мой пакет заканчивает тем, что приносит все эти пакеты вместе с ним, что я не хочу делать.

Вопрос может быть уменьшен до: «Может ли пакет знать если модуль доступен в потребляющем проекте? "

1 Ответ

0 голосов
/ 05 марта 2020

Я узнал, как заставить его работать.

  1. Объявить зависимость
  2. Написать код поддержки для него
  3. Подготовить его в #if canImport(...)
  4. Убрать зависимость

Теперь непостоянная часть. В потребляющем пакете, как только я установлю свой пакет, мой код поддержки будет доступен . Но как только я убегу, игра окончена; он больше не будет компилироваться после запуска. В этом случае я узнал, что мне нужно удалить мой пакет, очистить, собрать, установить его снова, собрать. Затем он успешно скомпилируется; Компилятор знает об API поддержки кода. Я также могу запустить его, и код поддержки работает.

...