Swift包管理器:创建自定义框架

时间:2018-05-21 11:28:10

标签: swift xcode swift-package-manager

我想在Swift中创建一个自定义框架,以便我可以在多个项目中使用它。因此我开始

config.mailer_sender

mkdir TestFramework && cd TestFramework
swift package init --type library

然后我开始在那里创建一些类,我构建了代码。结果是swift package generate-xcodeproj 文件。我将它移动到我的其他项目并将其链接到那里(因此我只是将.framework文件夹复制到Xcode项目并将其添加到目标)。 .framework有效,但我无法访问我在框架中创建的任何类:import TestFramework

奇怪的是:Use of unresolved identifier 'TestClass'似乎是一个可执行文件。这是Package.swift:

TestFramework.framework/Versions/A/TestFramework

2 个答案:

答案 0 :(得分:2)

解决此问题的最佳方法是使用Xcode顶层工作空间(文件 - >新建 - >工作空间)。因此,创建一个名为Example的工作区。

第二步创建一个名为lib的目录并将其放在Example目录中。将其放在目录中并不是严格要求的,但我这样做是为了将文件保存在单个项目目录中。接下来在lib目录中运行:

swift package init --type library

并添加一些代码来创建框架。

接下来使用Xcode创建一个新项目。所以文件 - >新 - >项目也存储在Example目录中(同样不是严格要求将其放在Example中)。现在让我们假设您创建了一个名为TestUI的Cocoa应用程序。

现在打开您的示例工作区,并使用File - >将两个项目添加到工作区。将文件添加到"示例"。您应该为lib.xcodeproj目录添加生成的lib,为TestUI添加TestUI.xcodeproj

从这一刻起,Xcode将自动处理事情。它将两个项目中的所有文件存储在一个构建目录中,您可以按照预期创建/运行/构建/调试应用程序。

结构应如下所示:

Example
|-- Example.xcworkspace
|-- TestUI
|   |-- TestUI
|   |   |-- AppDelegate.swift
|   |   |-- Assets.xcassets
|   |   |   |-- AppIcon.appiconset
|   |   |   |   `-- Contents.json
|   |   |   `-- Contents.json
|   |   |-- Base.lproj
|   |   |   `-- Main.storyboard
|   |   |-- Info.plist
|   |   |-- MailboxViewController.swift
|   |   |-- TestUI.entitlements
|   |   `-- ViewController.swift
|   `-- TestUI.xcodeproj
`-- lib
    |-- lib.xcodeproj
    |-- Package.resolved
    |-- Package.swift
    |-- README.md
    |-- Sources
    |   |-- ExampleLib
    |   |   |-- Account.swift
    |   |   |-- Credentials.swift

这种方法有一个主要限制。如果你的库有非Swift组件,例如围绕C库的包装器不会开箱即用。您将收到类似"无法找到所需框架xxx"的消息。如果你试图使用它。如果您向库中添加了一些必需的软件包,那么也会发生这种情况,即“C'根据。

我找到了以下解决方法。首先转到lib目录并运行以下命令:

find lib.xcodeproj -name module.modulemap

如果您使用/创建了xxx库,则会得到以下输出:

lib.xcodeproj/GeneratedModuleMap/xxx/module.modulemap

现在转到Example工作区并选择TestUI - >构建设置 - >全部并进入搜索框"其他Swift Flags"。

打开它并添加以下两个字段:

-Xcc
-fmodule-map-file=$(SRCROOT)/../lib/lib.xcodeproj/GeneratedModuleMap/xxx/module.modulemap

就是这样。它现在应该全部工作了。对于编译和运行,甚至不需要在TestUI应用程序中嵌入二进制文件,尽管我认为它是分发所必需的。

答案 1 :(得分:1)

确保您的类和其他类型为public,包括方法和初始化程序。

在框架上工作时,避免在单元测试中使用testable有助于测试公共界面,因为使用中的应用程序会看到它。