如何在现有的 macOS 项目中使用 Swift Package Manager?

30

我一直在使用Cocoapods管理我的Swift项目的依赖项。我发现了这个包,它没有列在Cocoapods中。它建议使用Swift Package Manager。然而,每当我尝试使用Swift Package Manager做任何事情时,它最终完全破坏了我的整个项目。

因此,为了弄清楚如何实际使用Swift Package Manager,我在测试项目中进行测试。

以下是我尝试过的:

  1. 从Xcode创建一个新项目

文件 -> 新建 -> 项目 -> Cocoa App

产品名称:basic-ssh-test

这将创建一个基本应用程序,当我点击“运行”时加载一个空白窗口。只是为了好玩,我在我的AppDelegateapplicationDidFinishLaunching函数中添加了print("test"),所以当我运行程序时,调试窗口上显示“test”。

现在我想将Shout包添加为依赖项。

  1. swift package init --type executable

这将创建以下文件:

Creating executable package: basic-ssh-test
Creating Package.swift
Creating README.md
Creating .gitignore
Creating Sources/
Creating Sources/basic-ssh-test/main.swift
Creating Tests/

现在我将把“Shout”依赖项添加到我的新的Package.swift文件中:

// swift-tools-version:4.0
import PackageDescription

let package = Package(
    name: "basic-ssh-test",
    dependencies: [
        .package(url: "https://github.com/jakeheis/Shout", from: "0.2.0")
    ],
    targets: [
        .target(
            name: "basic-ssh-test",
            dependencies: ["Shout"]),
    ]
)

我将拉取所需的依赖项:

  1. swift package resolve

这会导致依赖项被拉取到 .build 目录中:

Fetching https://github.com/jakeheis/Shout
Fetching https://github.com/jakeheis/CSSH
Fetching https://github.com/IBM-Swift/BlueSocket
Cloning https://github.com/IBM-Swift/BlueSocket
Resolving https://github.com/IBM-Swift/BlueSocket at 0.12.91
Cloning https://github.com/jakeheis/CSSH
Resolving https://github.com/jakeheis/CSSH at 1.0.3
Cloning https://github.com/jakeheis/Shout
Resolving https://github.com/jakeheis/Shout at 0.3.0

现在,我重新生成了xcodeproj文件:

  1. swift package generate-xcodeproj

现在,当我打开xcodeproj文件时,会有一个名为Sources的新组,其中只有一个目录basic-ssh-test和一个名为main.swift的单一Swift文件,其中包含print("Hello, world!")的代码。

我实际上感兴趣的代码现在位于名为basic-ssh-test的蓝色文件夹中。所有必要的文件仍然在那里,但是Xcode正在运行main.swift文件,而不是运行我的应用程序。我可以看到调试输出是“Hello, world!”而不是“test”。

我读过几篇教程声称,Swift Package Manager将移动我的源代码并继续像以前一样构建,但显然情况并非如此。

我的构建设置中也不再有“主界面”选项,因此我无法将“MainMenu.xib”选择为我的应用程序起始点。

这本质上与我尝试使用Swift Project Manager与我的现有项目时发生的情况相同。它会引入依赖项,但基本上会忽略我整个现有项目,并只运行“hello world”代码。

如何使用Swift Package Manager向现有项目添加依赖项而不忽略现有代码库?


你需要创建一个新的“构建目标”并进行良好的配置。 - MatthewLuiHK
谢谢@MatthewLuiHK。我创建了一个新的构建目标,但它具有与现有构建目标相同的选项,即在构建设置中没有“主界面”选项。我该如何设置主界面? - Ben Harold
您的目标应该是“应用程序”类型 - MatthewLuiHK
4个回答

7
我认为SPM仅与Mac命令行执行程序或库兼容。 这里 明确指出SPM不支持iOS、watchOS或tvOS平台。但是,由于macOS AppKit/Cocoa应用程序目标与iOS或tvOS Xcode目标非常相似,我想这句话意味着SPM不能直接用于macOS Cocoa应用程序,这也是你所希望的。
看起来有 这里的一些工作 是关于如何在iOS应用程序目标上使用它,这应该可以大部分转化为macOS Cocoa目标。

那个链接还说,如果UIKit和AppKit在正确的系统位置上,它们“应该可以工作”。我不确定他们希望UIKit如何工作,如果iOS没有。这听起来更像是“你必须自己解决”,而不是“它根本不会工作”。 - Ssswift
@Ssswift 我认为他们指的是将UIKit导入编译以便作为依赖项。 - allenh

5
在撰写本答案时,Swift Package Manager 不支持 iOS、tvOS 和 watchOS 平台。因此,您需要直接将包中的文件添加到您的项目中。
我建议您在项目中创建一个 Dependencies 组,然后再在该组下面创建一个与包名相同的组,就像这个答案所示:
首先,您需要将要导入到项目中的依赖文件添加到我们之前创建的 Dependencies 组中的包名称下。
文件添加完成后,您可以像编写自己的代码一样访问代码,如下图所示,无需导入任何内容。详细信息请参见这里。希望对您有所帮助。 enter image description here

3

你可以使用SPM创建一个窗口应用程序(我有一个整个项目等待ABI来完成这个任务),你只需要在swift.main中添加一些样板代码即可。我会找出来给你。

然而,其他人提出的方法在当前版本的SPM中永远不会起作用。

不过,我看到你确实希望使用SPM来管理依赖关系(保持更新等)。所以我认为你可以更容易地实现这一点。

与其创建一个默认目标为可执行文件,不如创建一个库(可能称之为basic-ssh-dependencies)。生成你的Xcode项目并将它拖入主要的Xcode项目中,并配置你的目标依赖于它。当你从SPM中更新库以更改依赖项时,应重新生成Xcode-proj。

让我知道你的进展和任何问题,或者如果我误解了你要实现的目标,请告诉我。


2

XCode 11更新

使用XCode 11现在要容易得多了。截至本文撰写时,当前版本为XCode 11.3.1。

对于现有的XCode项目:

  1. 进入 File->Swift Packages->Add Package Dependency...
  2. 输入要添加的托管包的URL
  3. 选择应用程序将使用哪些版本的规则
  4. 点击 Finish

文件、Swift Packages、添加包依赖项...

添加URL

包规则

已添加该包


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接