Swift包管理器:创建自定义框架
我想在Swift中创建一个自定义框架,以便在多个项目中使用它。所以我从Swift包管理器:创建自定义框架,swift,xcode,swift-package-manager,Swift,Xcode,Swift Package Manager,我想在Swift中创建一个自定义框架,以便在多个项目中使用它。所以我从 mkdir TestFramework && cd TestFramework swift package init --type library 及 然后我开始在其中创建一些类,并构建代码。结果是一个.framework文件。我将它移动到我的另一个项目并将其链接到那里(因此我只需将.framework文件夹复制到Xcode项目并将其添加到目标中)导入测试框架可以工作,但我无法访问任何类,我在框架中创建:使
mkdir TestFramework && cd TestFramework
swift package init --type library
及
然后我开始在其中创建一些类,并构建代码。结果是一个.framework
文件。我将它移动到我的另一个项目并将其链接到那里(因此我只需将.framework文件夹复制到Xcode项目并将其添加到目标中)<代码>导入测试框架可以工作,但我无法访问任何类,我在框架中创建:使用未解析标识符“TestClass”
奇怪的是:TestFramework.framework/Versions/A/TestFramework
似乎是一个可执行文件。这是包裹。swift:
let package = Package(
name: "TestFramework",
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "TestFramework",
targets: ["TestFramework"]),
],
最好的方法是使用Xcode顶级工作区(文件->新建->工作区)。因此,创建一个名为Example的工作区 作为第二步,创建一个名为lib的目录,并将其放在示例目录中。严格来说,将其放在目录中不是必需的,但我这样做是为了将文件保存在单个项目目录中。下一步在
lib
目录中运行:
swift package init --type library
并添加一些代码来创建您的框架
接下来,使用Xcode创建一个新项目。所以File->New->Project并将该项目也存储在Example目录中(同样,将其放入Example目录并不严格要求)。现在让我们假设您创建了一个名为TestUI的Cocoa应用程序
现在打开示例工作区,使用文件->将文件添加到“示例”将两个项目添加到工作区。您应该为lib
目录添加生成的lib.xcodeproj
,为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
现在转到示例工作区,选择TestUI->Build Settings->All并在搜索框中输入“Other Swift Flags”
打开并添加以下两个字段:
-Xcc
-fmodule-map-file=$(SRCROOT)/../lib/lib.xcodeproj/GeneratedModuleMap/xxx/module.modulemap
就这样。现在应该都能用了。对于编译和运行,甚至不需要在TestUI应用程序中嵌入二进制文件,尽管我认为这对于分发是必要的 最好的方法是使用Xcode顶级工作区(文件->新建->工作区)。因此,创建一个名为Example的工作区 作为第二步,创建一个名为lib的目录,并将其放在示例目录中。严格来说,将其放在目录中不是必需的,但我这样做是为了将文件保存在单个项目目录中。下一步在
lib
目录中运行:
swift package init --type library
并添加一些代码来创建您的框架
接下来,使用Xcode创建一个新项目。所以File->New->Project并将该项目也存储在Example目录中(同样,将其放入Example目录并不严格要求)。现在让我们假设您创建了一个名为TestUI的Cocoa应用程序
现在打开示例工作区,使用文件->将文件添加到“示例”将两个项目添加到工作区。您应该为lib
目录添加生成的lib.xcodeproj
,为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
现在转到示例工作区,选择TestUI->Build Settings->All并在搜索框中输入“Other Swift Flags”
打开并添加以下两个字段:
-Xcc
-fmodule-map-file=$(SRCROOT)/../lib/lib.xcodeproj/GeneratedModuleMap/xxx/module.modulemap
就这样。现在应该都能用了。对于编译和运行,甚至不需要在TestUI应用程序中嵌入二进制文件,尽管我认为这对于分发是必要的 确保您的类和其他类型是公共的,包括方法和初始值设定项
在框架上工作时,避免在单元测试中使用
testable
,这有助于测试公共界面,因为消费应用程序会看到它 确保您的类和其他类型是公共的,包括方法和初始值设定项
在框架上工作时,避免在单元测试中使用
testable
,这有助于测试公共界面,因为消费应用程序会看到它 谢谢大家!!您还应该提到:当工作区打开时,您应该在构建之前编辑GUI的方案。。。我在那里添加了libraray,以便在我对库进行更改后也可以编译它。同时,库中的所有类和方法都必须是公共的。谢谢!您还应该提到:当工作区打开时,