- 原文地址:Creating Swift Package Manager tools from your existing codebase
- 原文做者:Paul Samuels
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:iWeslie
- 校对者:LoneyIsError, iWeslie
Swift 包管理器(SPM)很是适合编写快速工具,你甚至能够从应用程序中提取现有代码。诀窍是你须要意识到你能够将文件夹符号连接到 SPM 项目中,这意味着经过一些工做你能够建立一个包装生产代码部分的命令行工具。前端
虽然它很依赖于项目,可是常见的用例是建立支持、调试和持续集成(CI)验证工具。例如,许多应用程序为了实现功能而使用远端的数据,应用程序须要将远程数据转换为自定义的类型,而且使用业务规则对此数据执行有用的操做。在此流程中会有多个故障点显示出应用程序的崩溃或不正确的行为,所以解决的方法是在有附加调试器的状况下启动并进行调试,Swift 包管理器将是一个帮助发现问题并潜在地阻止问题的好工具。android
你不能使用 UIKit
框架的下的代码,由于这项技术仅适用于基于 Foundation
库的代码。虽然这听起来有限制,可是在理想状况下,业务逻辑和数据操做的代码都不该该都不该该引入有关 UIKit
框架下的东西。ios
具备依赖性致使了该技术更加难,不过你仍然能够使用它,可是须要在 Package.swift
中进行更多的配置。git
这取决于你的项目结构。我这里有一个示例项目。这是一个小型的 iOS 项目,它显示了一个博客的帖子列表(你并不须要看项目自己,项目自己并不重要)。项目中博客的帖子来自于假的 JSON 数据,它没有特别好的结构,所以应用程序须要进行自定义解码。为了保持它的轻量级,我将如下面的方式构建最简单的包装器:github
你能够疯狂地给它添加更多的更能,可是这个简单的工具将会让咱们在不启动模拟器的状况下,快速为咱们提供关于生产代码是否能够接受某些 JSON 的反馈或者显示任何可能发生的错误。web
这个示例项目的基础结构以下:swift
.
└── SymlinkedSPMExample
├── AppDelegate.swift
├── Base.lproj
│ └── LaunchScreen.storyboard
├── Info.plist
├── ViewController.swift
└── WebService
├── Server.swift
└── Types
├── BlogPost.swift
└── BlogPostsRequest.swift
复制代码
我特地建立了一个仅包含我想重用的代码的 Types
目录。想要建立利用次生产代码的命令行工具,咱们能够执行如下操做:后端
mkdir -p tools/web-api
cd tools/web-api
swift package init --type executable
复制代码
如今咱们已经搭建了一个能够操做的项目。首先让咱们把生产代码进行连接:api
cd Sources
ln -s ../../../SymlinkedSPMExample/WebService/Types WebService
cd ..
复制代码
你要给这个连接使用相对路径,不然在迁移到别的电脑上时会奔溃bash
如今项目的结构如今看起来像这样:
.
├── SymlinkedSPMExample
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── Info.plist
│ ├── ViewController.swift
│ └── WebService
│ ├── Server.swift
│ └── Types
│ ├── BlogPost.swift
│ └── BlogPostsRequest.swift
└── tools
└── web-api
├── Package.swift
├── README.md
├── Sources
│ ├── WebServer -> ../../../SymlinkedSPMExample/WebService/Types/
│ └── web-api
│ └── main.swift
└── Tests
复制代码
如今我须要更新 Package.swift
文件来给代码建立一个新的 target 而且添加一个依赖,从而使得 web-api
可执行文件能够使用这些生产代码
Package.swift
// swift-tools-version:4.0
import PackageDescription
let package = Package(
name: "web-api",
targets: [
.target(name: "web-api", dependencies: [ "WebService" ]),
.target(name: "WebService"),
]
)
复制代码
既然 SPM 知道如何构建项目,那就让咱们利用生产解析代码来写以前提到的代码吧。
main.swift
import Foundation
import WebService
do {
print(try JSONDecoder().decode(BlogPostsRequest.self, from: FileHandle.standardInput.readDataToEndOfFile()).posts)
} catch {
print(error)
}
复制代码
有了这些后,咱们如今能够开始经过这个工具运行 JSON 来看看生产代码是否会处理它:
如下是咱们尝试经过这个工具发送有效 JSON 时的样子:
$ echo '{ "posts" : [] }' | swift run web-api
[]
$ echo '{ "posts" : [ { "title" : "Some post", "tags" : [] } ] }' | swift run web-api
[WebService.BlogPost(title: "Some post", tags: [])]
$ echo '{ "posts" : [ { "title" : "Some post", "tags" : [ { "value" : "cool" } ] } ] }' | swift run web-api
[WebService.BlogPost(title: "Some post", tags: ["cool"])]
复制代码
下面是当咱们输入无效的 JSON 时所获得的错误信息示例:
$ echo '{}' | swift run web-api
keyNotFound(CodingKeys(stringValue: "posts", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"posts\", intValue: nil) (\"posts\").", underlyingError: nil))
$ echo '{ "posts" : [ { } ] }' | swift run web-api
keyNotFound(CodingKeys(stringValue: "title", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "posts", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"title\", intValue: nil) (\"title\").", underlyingError: nil))
$ echo '{ "posts" : [ { "title" : "Some post" } ] }' | swift run web-api
keyNotFound(CodingKeys(stringValue: "tags", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "posts", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"tags\", intValue: nil) (\"tags\").", underlyingError: nil))
复制代码
posts
posts
没有 title
posts
没有 tags
在实际应用中,我将用管道的方式输出一个实时或暂存断点的 curl
结果,而非手写的 JSON 代码。
这真的很酷,由于我能够看到生产代码没有解析其中的一些示例,而且我能够看到解释了错误缘由的信息。若是没有这个工具,我须要手动运行应用程序并找出一种方法来获取不一样的 JSON 有效负载而来运行解析逻辑。
本文介绍了经过 SPM 使用生产代码来建立工具的基本技术。你能够真正地运行它并建立一些漂亮的工做流程,例如:
我已经开始在我本身的项目中使用这个想法了,我很高兴它能帮助我和我团队的其余成员。
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。
![]()