【问题标题】:Use swift package manager on existing xcode project在现有的 xcode 项目上使用 swift 包管理器
【发布时间】:2017-06-13 12:50:28
【问题描述】:

我是 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 文件添加到您的问题中
  • 我刚刚添加了我的 Package.swift 代码,我再次运行了swift build 命令,似乎是正确的,但是导入不起作用。
  • Swift 包管理器还处于起步阶段,你现在应该使用 CocoaPods。
  • swift package init 我猜

标签: ios swift xcode swift-package-manager


【解决方案1】:

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 包管理器现已集成到 Xcode 11 中。您可以通过转到“文件”然后“Swift 包”然后“添加包依赖项...”来添加包,将存储库的 URL 粘贴到上面的字段中,然后单击“下一步”。 Xcode 将引导您完成其余步骤。您可以通过this WWDC talk了解更多信息。

【讨论】:

  • 这里是关于ralfebert.de/ios-examples/xcode/…主题的另一篇文章
  • 那么,当您在 iOS 项目中使用 Swift 包管理器时,没有明显的 Package.swift 文件?
  • @ChrisPrince,有,但它是由 Xcode 在幕后隐藏和维护的。解决软件包后,您需要将 Packages.resolved 添加到源代码控制存储库。
【解决方案2】:

如果您使用的是 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)。
  • xcodebuild vs. swift build:很方便,如果你的Package.swift在同一目录下没有xcodeprojxcodebuild会自动生成方案供你使用,所以你不要 必须使用swift build。例如,运行xcodebuild -list 以查看从您的Package.swift 文件生成的方案列表,然后使用这些方案之一。不方便的是,没有办法/配置使xcodebuild 使用Package.swift

【讨论】:

  • 谢谢!为我工作!
【解决方案3】:

Swift 包管理器 (SPM)

[iOS Dependency manager]

消费[SPM manage dependency]

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

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 依赖的观察

import Module1
import Module2
  • Swift 库转换为单个.o format[About] 文件和.swiftmodule[About]
  • Swift 库公开 .modulemap umbrella.h[About] 用于公开模块以供 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

如果你的目标有依赖。您将获得相同的效果 - 伞库。

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

例如使用Explicit Dependency[About]。重要提示:使用相同的名称(模块和 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 本地包地址

不要在路径中使用空格( ),否则会得到

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

如果你不指定// swift-tools-version:&lt;version&gt;,你会得到:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-02
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-29
    • 2021-04-28
    • 2017-05-22
    相关资源
    最近更新 更多