Я хочу отправить свою библиотеку с помощью диспетчера пакетов Apple Swift. Однако моя библиотека содержит файл .bundle с несколькими строками, переведенными на разные языки. Используя cocoapods, я могу включить его, используя spec.resource. Но в SwiftPM я не могу этого сделать. Любое решение?
Как включить ресурсы/ресурсы в библиотеку диспетчера пакетов Swift?
Ответ 1
Менеджер пакетов еще не имеет определения того, как ресурсы будут связаны с целями. Мы осознаем необходимость этого, но пока у него нет конкретного предложения. Я подал https://bugs.swift.org/browse/SR-2866, чтобы убедиться, что у нас есть ошибка, отслеживающая это.
Ответ 2
Поскольку пакеты инфраструктуры еще не поддерживаются, единственный способ предоставить активы пакета с целью SPM - через Пакет. Если вы реализуете код в своей среде для поиска определенного пакета в вашем основном проекте (поддерживая пакеты активов), вы можете загрузить ресурсы из указанного пакета.
Пример:
Доступ к связанным ресурсам:
extension Bundle {
static func myResourceBundle() throws -> Bundle {
let bundles = Bundle.allBundles
let bundlePaths = bundles.compactMap { $0.resourceURL?.appendingPathComponent("MyAssetBundle", isDirectory: false).appendingPathExtension("bundle") }
guard let bundle = bundlePaths.compactMap({ Bundle(url: $0) }).first else {
throw NSError(domain: "com.myframework", code: 404, userInfo: [NSLocalizedDescriptionKey: "Missing resource bundle"])
}
return bundle
}
}
Используйте связанные ресурсы:
let bundle = try! Bundle.myResourceBundle()
return UIColor(named: "myColor", in: bundle, compatibleWith: nil)!
Вы можете применять одну и ту же логику ко всем файлам ресурсов, включая, помимо прочего, раскадровки, xib, изображения, цвета, большие двоичные объекты данных и файлы различных расширений (json, txt и т.д.).
Примечание: иногда это имеет смысл, иногда нет. Определите использование по собственному усмотрению проекта. Потребовались бы очень конкретные сценарии, чтобы оправдать разделение раскадровок /Xib на объединенные ресурсы.
Ответ 3
Вы также можете загружать отдельные ресурсы динамически.
Предположим, что для тестирования ваших пакетов нужны какие-то фиктивные данные JSON. Вы поместите фиктивные JSON файлы в каталог Tests/JSONMocks
. Затем в Package.swift
:
targets: [
.testTarget(
name: "MyTargetTests",
dependencies: ["MyTarget"],
path: "Tests"
),
]
И загружать их динамически:
static func dataForJSONFileNamed(string: String) -> Data {
// find mock JSON files if using Swift Package Manager:
let currentDirectoryURL = URL(fileURLWithPath: FileManager.default.currentDirectoryPath)
let fileURL = currentDirectoryURL
.appendingPathComponent("Tests", isDirectory: true)
.appendingPathComponent("JSONMocks", isDirectory: true)
.appendingPathComponent(string)
.appendingPathExtension("json")
let jsonFileData = try! Data(contentsOf: fileURL)
return jsonFileData
}