在现有的Xcode项目中使用Swift Package Manager

27

我是Swift和Xcode的新手,所以在尝试将一个包集成到我的项目时遇到了问题。

我想使用以下命令添加Alamofire依赖项:

在我的项目根文件夹内:

swift init

这将创建Package.swift文件,我在其中添加了依赖项,然后运行:

swift build

一切似乎都很好,但在我的项目中,当我尝试导入我的库时:

import Alamofire

我遇到了一个错误,它说模块没有被识别。那么我的问题是,在不让一切崩溃的情况下,集成包管理器和现有项目的依赖项的正确步骤是什么。

更新:

swift build

输出结果:

Resolved version: 4.3.0
Compile Swift Module 'Alamofire' (17 sources)
Compile Swift Module 'Sample' (1 sources)

我的 Package.swift 文件是:

import PackageDescription

let package = Package(
    name: "Sample",
    dependencies: [
        .Package(url: "https://github.com/Alamofire/Alamofire.git", majorVersion: 4)
    ]
)

你能否请将你的 Package.swift 文件添加到你的问题中? - muescha
也许你应该在 Source/ 目录下编辑你的文件。 - A.C
2
Swift Package Manager仍处于起步阶段,目前您应该使用CocoaPods。 - Bobby
1
swift package init i guess - krafter
目前一定要使用Carthage。祈求iOS到SPM的转换路径快速 :O - Fattie
显示剩余2条评论
3个回答

23
如果您正在使用Xcode项目,则不需要(也不应该使用)Package.swift,只需在Xcode的Swift Packages中单击加号图标,然后添加Swift Package的GitHub URL,库也会自动添加到您的目标中(请参照下面的GIF,或者单击here中的添加图标):

额外信息

  • 一致性问题:不能同时维护Xcode项目和Swift.package以针对相同的目标。它们不会同步,并且会变得不一致,因此根据使用的工具,您将获得不同的构建结果:令人困惑。您曾经可以使用swift package generate-xcodeproj基于Package.swift创建一个xcodeproj,但这已被弃用。您对此Xcodeproj所做的更改不会反映在原始的Package.swift中。
  • xcodebuildswift build:方便的是,如果在与Package.swift相同的目录中没有xcodeproj,则xcodebuild会自动生成方案供您使用,因此您不需要使用swift build。例如,运行xcodebuild -list以查看从您的Package.swift文件生成的方案列表,然后使用其中一个方案。不方便的是,没有方法/配置使xcodebuild使用Package.swift

15

Swift Package Manager是一个独立的工具,允许无需Xcode管理依赖项和构建项目。它可以使用swift package generate-xcodeproj为您生成Xcode项目。

但是,目前Swift Package Manager只支持构建macOS和Linux平台的项目。构建iOS、tvOS和watchOS项目的唯一方法是使用Xcode,其中包括这些平台所需的SDK。

还有一些方法可以使用Swift Packages Manager来管理iOS/tvOS/watchOS的依赖关系,但这并不容易且需要手动操作。如果您有兴趣,请查看https://github.com/j-channings/swift-package-manager-ios

除此之外,我建议使用CarthageCocoaPods

Xcode 11更新

Swift Package Manager现在已经集成到Xcode 11中。您可以通过转到“文件”,然后转到“Swift Packages”,然后转到“添加包依赖项...”来添加您的包。将存储库的URL粘贴到上面的字段中,然后单击“下一步”。Xcode会引导您完成其余的步骤。您可以在这个WWDC演讲中了解更多信息。


这是关于此主题的另一篇文章,网址为https://www.ralfebert.de/ios-examples/xcode/ios-dependency-management-with-swift-package-manager/。 - Fattie
请点击此处 https://dev59.com/vabja4cB1Zd3GeqPnOG1#47954098,了解如何将Swift Package Manager集成到现有的Xcode项目中。 - Fattie
1
那么,如果您在iOS项目中使用Swift Package Manager,就不会有明显的Package.swift文件吗? - Chris Prince
1
@ChrisPrince,有一个隐藏的包管理器由Xcode维护。一旦解决了包的依赖关系,您需要将“Packages.resolved”添加到您的源代码控制存储库中。 - Eneko Alonso

1

Swift Package Manager(SPM)

[iOS 依赖管理器]

使用: [SPM 管理依赖项]

生成: 如果您正在开发库/模块(模块化),则应该注意支持它

Package.swift - 清单文件。

  • 这是一个硬编码名称。
  • 应该放置在相同或更高的级别,否则:
target '<target_name>' in package '<package_name>' is outside the package root

Package.swift 示例

// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
 
let package = Package(

    name: "PackageName1",

    //Supported platforms
    platforms: [
        .iOS(.v11)
    ],
    
    //Product list - executable binary
    products: [
        .library(
            name: "LibraryName1",
            targets: ["TargetName1"]),
    ],

    //Additional SPM dependencies declaration(packages) which are used in targets
    dependencies: [

        //Local package path
        .package(name: "PackageName2", path: "../Feature1")

        //Local package URL
        .package(name: "PackageName2", url: "file:///some_local_path", .branch("master"))

        //Remote package URL
        .package(name: "PackageName2", url: "https://github.com/user/repo", .branch("master")),
    ],

    targets: [
        //Source code location. implicitly `Sources/<target_name>`(Sources/TargetName1) or explicitly `path:`
        .target(
            name: "TargetName1",
            dependencies: [
                //using dependencies from package.targets and package.dependencies

                //package.targets
                "LibraryName2"

                //package.dependencies
                .product(name: "PM2LibraryName1", package: "PackageName2")
            ]),
            path: "Sources/TargetName1"
    ]
)

Swift 依赖项的观察

  • [SWIFT_MODULE_NAME, PRODUCT_NAME, EXECUTABLE_NAME] == package.targets.target.name
  • package.products.library.name 仅用于 Xcode 表示
  • Library 被使用[关于]
  • 当目标有依赖于另一个目标源代码时,将使用一种来自 .modulemap[关于] 的显式多模块方式将其包含在单个库中,并且可以考虑访问权限
import Module1
import Module2
  • Swift库通过.modulemap umbrella.h[关于]暴露模块,以便Objective-C消费者通过@import SomeModule;使用。
- You are able to work with `Package.swift` in Xcode if double click on it
.swiftpm/xcode with .xcworkspace will be generated 
- When you work with `Package.swift` you are able to check it, just save this file
- When you work with `Package.swift` you should specify schema and device(platform)
- When you build `Package.swift` 
  - library and .swiftmodule is located:
<path_to_derived_data>/DerivedData/<folder_name_where_Package.swift_located>-<randomizer>/Build/Products/<platform>
//e.g.
/Users/alex/Library/Developer/Xcode/DerivedData/someFolder-ccivqbbjujxuvdcxtuydyqfeepfx/Build/Products/Debug-iphonesimulator
  - .modulemap and umbrella.header is located:
<path_to_derived_data>/DerivedData/<folder_name_where_Package.swift_located>-<randomizer>/Build/Intermediates.noindex/<project_name>.build/<platform>/<target_name>.build/<.modulemap> and plus /Objects-normal/<arch>/<tarhet_name-Swift.h>

- When you build consumer with `Package.swift` results files will be located:
<path_to_derived_data>/DerivedData/<target_name>-<randomizer>/Build/Products/<platform>

- When you work with consumer of `Package.swift` SPM clones it into
<path_to_derived_data>/DerivedData/<target_name>-<randomizer>/SourcePackages/checkouts

package.products.library.targets

您可以指定多个目标。这意味着可以从单个可执行二进制文件(一种类似于“伞”库)中使用多个模块。

producer:
package.products.library.targets: ["TargetName1", "TargetName2"]

consumer: 
1. adds single library
2. several imports

import TargetName1
import TargetName2

package.targets.target.dependencies

如果您的目标有依赖关系,您将获得相同的效果 - Umbrella库。

1.从同一软件包中添加另一个目标

例如,使用显式依赖项[关于]。重要提示:使用相同的名称(模块和SPM目标)。如果您没有在package.targets.target.dependencies中设置依赖项,则会出现以下错误

Undefined symbol

2.从另一个软件包添加产品。其他软件包中的所有目标将被公开。

2.1 本地软件包路径

您无法在消费端使用它。但至少可以让您进行调试。

package <package_name_1> is required using a revision-based requirement and it depends on local package <package_name_2>, which is not supported

2.2 本地包 URL

路径中不要使用空格( ),否则会出现以下错误

The URL file:///hello world/some_local_path is invalid

如果您不指定// swift-tools-version:<version>,则会得到以下结果:

package at '<some_path>' is using Swift tools version 3.1.0 which is no longer supported; consider using '// swift-tools-version:5.3' to specify the current tools version

*不要忘记在测试之前提交您的更改并更新[关于]


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