Swift 包管理器 - UIKit 依赖

Posted

技术标签:

【中文标题】Swift 包管理器 - UIKit 依赖【英文标题】:Swift Package Manager - UIKit Dependency 【发布时间】:2016-01-13 23:11:23 【问题描述】:

我的项目中有一个 Package.swift,例如:

import PackageDescription

let package = Package(
    name: "ProjectName",
        dependencies: [
           .Package(url: "https://github.com/example/repo.git", majorVersion: 0)
        ]
 )

当我运行swift build 时,我会收到类似...的错误

/project/Packages/WebViewController.swift:1:8: error: no such module 'UIKit'
import UIKit
       ^

我应该在哪里告诉 swift 包管理器在哪里可以找到 UIKit?

【问题讨论】:

【参考方案1】:

您必须更改一些 swiftc 选项才能针对正确的 sdk 和目标构建项目

swift build -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk iphonesimulator --show-sdk-path`" -Xswiftc "-target" -Xswiftc "x86_64-apple-ios13.0-simulator"

【讨论】:

这应该是公认的答案!我也可以使用以下命令确认它适用于 iOS 14:swift build -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk iphonesimulator --show-sdk-path`" -Xswiftc "-target" -Xswiftc "x86_64-apple-ios14.0-simulator" 对于 tvOS:swift build -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk appletvsimulator --show-sdk-path`" -Xswiftc "-target" -Xswiftc "x86_64-apple-tvos14.3-simulator" 这对我有用,但是 Xcode 无法识别我想要使用 Package.swift 中指定的库依赖项的项目中的二进制文件。我想我错过了一个明显的步骤......?【参考方案2】:

目前 Swift 包管理器有完整的 Xcode 支持。通过在我的 Package.swift 清单中指定平台是 iOS,我能够绕过这个错误。

let package = Package(
    name: "MyPackage",
    platforms: [
        .iOS(.v8)
    ],

然后你可以在 Xcode 中打开 Package.swift 文件,它就可以工作了。

【讨论】:

我遇到了原始问题,即使在定义平台时也是如此。 不幸的是,我不得不为我的内部框架使用 git 子模块。 :( 定义平台后,确保在构建时选择了顶部的 iPhone 模拟器。 如何在 Xcode 中打开 Package.swift?当我尝试在 Xcode 中打开文件时,它不仅起作用。文件是否需要添加到项目中?【参考方案3】:

让它不受平台限制地工作:

您应该选择一个 基于 iOS 的目标以使其可用:

如果你让它选择macOS(默认),你会得到错误。


限制到特定平台

如果您希望您的包仅适用于特定平台(例如仅适用于 iOS),您应该在 package.swift 文件中指定平台:

let package = Package(
    name: "MyLibrary",
    platforms: [
        .iOS(.v10)
    ],
    products: [
,,,

支持多平台

如果您需要您的框架在多个平台上可用,请不要忘记检查导入框架的可用性,例如:

#if canImport(UIKit)

import UIKit

#endif

【讨论】:

这就是答案!【参考方案4】:

Swift 包管理器构建可执行文件以在 OS X(或 Linux)上运行; UIKit 是 iOS 中的一个框架,无法访问。

随着 Swift 包管理器的发展,它可能是 iOS、tvOS 和其他可以访问的。

2015 年 12 月 4 日下午 5:39,Daniel Dunbar (@apple.com) 写道:

...

好的,现在我们只为主机平台(目前是 OS X 或 Linux)进行编译。除其他外,我们目前不知道(或可供选择的选项)您所针对的 SDK 或架构。我们也没有在清单中指定与哪些平台目标兼容的机制。

【讨论】:

你能指出 Swift Package Manager 仅适用于 MacOS 和 Linux 的文档吗? 好吧,即使您可以构建一个 iOS 可执行文件,您如何将它安装到 iOS 设备上并在其上运行? swift build --help 没有显示架构选项。 swift.org/package-manager/#conceptual-overview 的文档只提到了 Darwin 和 Linux。 我期待它能够像 Carthage 那样构建一个框架。 Swift 包管理器不仅适用于 OS X 和 Linux;这些只是它支持的当前平台。计划支持其他平台。 这个答案现在似乎已经完全过时了,因为SPM supports macOS, iOS, tvOS, watchOS, and Linux, with Windows and android coming soon和macOS now has UIKit。【参考方案5】:

使用条件编译块:

#if canImport(UIKit)

// Code specific to platforms where UIKit is available

#endif

来源:https://developer.apple.com/documentation/xcode/creating_a_swift_package_with_xcode

【讨论】:

OP 需要一个快速构建错误的解决方案,而不是条件导入...【参考方案6】:

确保选择 iPhone 作为模拟器目标。 Mac 目标是默认的,这将不起作用...如果 Xcode 可以查看清单并根据该清单选择默认模拟器,那就太棒了...

【讨论】:

【参考方案7】:

如果您的umbrella header(<module_name.h>)[About] 包含

#import <UIKit/UIKit.h>

这意味着您可以跳过在每个文件中指定import UIKit。但似乎SPM 不支持它。我也不支持使用@_exported 属性

你可以明确写import UIKit

【讨论】:

以上是关于Swift 包管理器 - UIKit 依赖的主要内容,如果未能解决你的问题,请参考以下文章

Swift 包管理器教程

Swift 包管理器找不到模块

在 swift 包管理器中为 API 调用编写单元测试

如何在 Xcode 11 中删除 Swift 包依赖项?

如何使用 Swift 包管理器 binaryTarget?

iOS支持Swift包管理器吗?[已关闭]