Moya 15.0.0
本文件的中文版本可在这里找到。
您是一位聪明的开发者。您可能使用 Alamofire 来抽象化对 URLSession
的访问,以及那些你并不特别关心的复杂细节。但是,就像许多聪明的开发者一样,您编写了临时的网络抽象层。它们可能被称为 "APIManager" 或 "NetworkModel",并且通常都会以灾难告终。
临时的网络层在 iOS 应用程序中很常见。它们有几个不好的地方:
- 难以编写新应用程序(“我从哪里开始?”)
- 难以维护现有应用程序(“哦,天哪,这是一团糟...”)
- 难以编写单元测试(“我怎样才能再来一次?”)
所以,Moya 的基本想法是,我们想要一个足够封装直接调用 Alamofire 的网络抽象层。它应该足够简单,以便常见的事情变得容易,但也足够全面,以至于复杂的事情也变得容易。
如果你使用 Alamofire 来抽象化对
URLSession
的访问,为什么不用来抽象化 URL、参数等的细节呢?
Moya 的一些强大功能:
- 编译时检查正确的 API 端点访问。
- 让您使用关联枚举值定义不同端点的明确用法。
- 将测试存根视为一等公民,这使得单元测试变得超级容易。
您可以在愿景文档中了解更多关于项目方向的信息。
示例项目
在仓库中,我们提供了两个示例项目。要使用它,请下载仓库,运行 carthage update
下载所需的库,并打开 Moya.xcodeproj。您将看到两个方案:Basic
和 Multi-Target
- 选择一个然后进行构建和运行!这些示例的源文件位于项目导航窗口的 Examples
目录中。祝您玩得开心!
项目状态
此项目正在积极开发中,在 Artsy 的新拍卖应用 中使用。我们将其视为生产使用。
安装
Moya版本与Swift版本
下表显示您应为您的Swift版本使用哪个Moya版本。
Swift | Moya | RxMoya | ReactiveMoya |
---|---|---|---|
5.X | >= 13.0.0 | >= 13.0.0 | >= 13.0.0 |
4.X | 9.0.0 - 12.0.1 | 10.0.0 - 12.0.1 | 9.0.0 - 12.0.1 |
3.X | 8.0.0 - 8.0.5 | 8.0.0 - 8.0.5 | 8.0.0 - 8.0.5 |
2.3 | 7.0.2 - 7.0.4 | 7.0.2 - 7.0.4 | 7.0.2 - 7.0.4 |
2.2 | <= 7.0.1 | <= 7.0.1 | <= 7.0.1 |
注意:如果您在项目中使用Swift 4.2,但使用Xcode 10.2,即使我们使用了Swift 5.0,Moya 13也应该能正确运行。
升级到Moya的新主要版本?请参阅我们的迁移指南。
Swift Package Manager
注意:以下说明是在不支持Xcode UI的情况下使用 SwiftPM。最简单的方法是进入项目设置 -> Swift Packages 然后添加Moya。
要使用Apple的Swift包管理器进行集成,而不需要Xcode集成,请在您的 Package.swift
文件中添加以下依赖项:
.package(url: "https://github.com/Moya/Moya.git", .upToNextMajor(from: "15.0.0"))
然后指定"Moya"
为目标中使用Moya的依赖项。如果你想使用响应式扩展,还要分别将"ReactiveMoya"
,"RxMoya"
或"CombineMoya"
作为目标依赖项添加。以下是一个PackageDescription
的示例
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "MyPackage",
products: [
.library(
name: "MyPackage",
targets: ["MyPackage"]),
],
dependencies: [
.package(url: "https://github.com/Moya/Moya.git", .upToNextMajor(from: "15.0.0"))
],
targets: [
.target(
name: "MyPackage",
dependencies: ["ReactiveMoya"])
]
)
注意:如果你正在使用ReactiveMoya,我们使用的是我们自己的ReactiveSwift分支。这个分支为版本6.1.0及以后添加了2次提交,以移除发布中的测试依赖项。这是为了防止在Xcode 11/11.1上使用Xcode预览时构建测试依赖项(FB7316430)。如果你不想使用我们的分支,只需将另一个依赖项添加到你的SPM包列表中:[email protected]:ReactiveCocoa/ReactiveSwift.git
,然后它应该检索原始存储库。
Combine注意:如果你正在使用<); CombineMoya,请确保使用Xcode 11.5.0或更高版本。使用早期版本的Xcode,你必须手动将Combine作为弱连接框架添加到你的应用程序目标中。
Accio
Accio是一个基于SwiftPM的依赖项管理器,可以为iOS/macOS/tvOS/watchOS构建框架。因此,Moya的集成步骤与上述描述完全相同。一旦你的Package.swift
文件配置完成,运行accio update
而不是swift package update
。
CocoaPods
对于Moya,在你的Podfile中使用以下条目
pod 'Moya', '~> 15.0'
# or
pod 'Moya/RxSwift', '~> 15.0'
# or
pod 'Moya/ReactiveSwift', '~> 15.0'
#or
pod 'Moya/Combine', '~> 15.0'
然后运行pod install
。
在你想使用Moya的任何文件中,别忘了用import Moya
导入框架。
Carthage
Carthage用户可以指向此存储库并使用任意生成的框架,即Moya
、RxMoya
、ReactiveMoya
或CombineMoya
。
在你的Cartfile中添加以下条目
github "Moya/Moya" ~> 15.0
然后运行carthage update --use-xcframeworks
。
如果你是第一次在项目中使用Carthage,你需要按照以下链接中的说明执行一些额外步骤:[Carthage](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application)。
注意:目前,Carthage无法提供仅构建特定存储库子模块的方法。所有子模块及其依赖项都将使用上述命令构建。但是,你不需要将未使用的框架复制到项目中。例如,如果你没有使用
ReactiveSwift
,你可以在carthage update
完成之后安全地删除该框架以及与ReactiveMoya
一起的ReactiveSwift
框架。或者,如果你正在使用ReactiveSwift
但不是RxSwift
或Combine
,那么可以安全地删除RxMoya
、RxTest
、RxCocoa
、CombineMoya
等等。
手动方式
- 打开终端,使用
cd
命令进入您的顶级项目目录,然后在您的项目尚未初始化为git仓库的情况下,运行以下命令
$ git init
- 通过运行以下命令,将Alamofire和Moya添加为git 子模块
$ git submodule add https://github.com/Alamofire/Alamofire.git
$ git submodule add https://github.com/Moya/Moya.git
- 打开新的
Alamofire
文件夹,将Alamofire.xcodeproj
拖入您应用程序Xcode项目的项目导航器中。对于Moya
文件夹中的Moya.xcodeproj
也进行同样的操作。
它们应该嵌套在您应用程序的蓝色项目图标下方。它们位于其他所有Xcode组之上或之下无关紧要。
- 请在项目导航器中验证
xcodeproj
的部署目标是否与您的应用程序目标的部署目标相匹配。 - 接下来,在项目导航器(蓝色项目图标)中选择您应用程序项目,以导航到目标配置窗口,并在侧边栏中选择“目标”标题下的应用程序目标。
- 在该窗口的最顶部工具栏中,打开“通用”面板。
- 在“已安装的应用程序”部分下单击
+
按钮。 - 您将看到两个不同的
Alamofire.xcodeproj
文件夹,每个文件夹都包含两个不同版本的Alamofire.framework
,而被嵌套在“产品”文件夹中。
您可以选择哪个“产品”文件夹无关紧要,但选择顶层或底层的
Alamofire.framework
则非常重要。
- 选择iOS的顶层
Alamofire.framework
和macOS的底层一个。
您可以通过检查项目构建日志来验证您选择了哪个。Alamofire的构建目标将列为例
Alamofire iOS
、Alamofire macOS
、Alamofire tvOS
或Alamofire watchOS
。
-
在“已安装的应用程序”部分下再次单击
+
按钮,并添加正确的Moya
构建目标。 -
这就完成了!
三个框架将自动作为目标依赖项、链接框架和在复制文件构建阶段中嵌入的框架添加,这正是您在模拟器和设备上构建所需的全部。
使用方法
在进行了一些设置后,使用Moya实际上非常简单。您可以像这样访问API
provider = MoyaProvider<GitHub>()
provider.request(.zen) { result in
switch result {
case let .success(moyaResponse):
let data = moyaResponse.data
let statusCode = moyaResponse.statusCode
// do something with the response data or statusCode
case let .failure(error):
// this means there was a network failure - either the request
// wasn't sent (connectivity), or no response was received (server
// timed out). If the server responds with a 4xx or 5xx error, that
// will be sent as a ".success"-ful response.
}
}
这是一个基本示例。许多API请求需要参数。Moya将这些参数编码到您用于访问端点的枚举中,如下所示
provider = MoyaProvider<GitHub>()
provider.request(.userProfile("ashfurrow")) { result in
// do something with the result
}
不再出现URL中的错误。不再遗漏参数值。不再需要处理参数编码。
更多示例,请参阅文档。
响应式扩展
响应式扩展更加出色。Moya 为 ReactiveSwift、RxSwift 和 Combine 提供了响应式扩展。
ReactiveSwift
ReactiveSwift
扩展提供了两种方法:`reactive.request(:callbackQueue:)` 和 `reactive.requestWithProgress(:callbackQueue:)`,它们立即返回 SignalProducer
对象,你可以开始、绑定、映射等操作。处理错误,例如,我们可以这样做
provider = MoyaProvider<GitHub>()
provider.reactive.request(.userProfile("ashfurrow")).start { event in
switch event {
case let .value(response):
image = UIImage(data: response.data)
case let .failed(error):
print(error)
default:
break
}
}
RxSwift
RxSwift
扩展同样提供了两种方法:`rx.request(:callbackQueue:)` 和 `rx.requestWithProgress(:callbackQueue:)`,但返回类型有所不同。在 `rx.request(:callbackQueue)` 的情况下,返回类型是 Single<Response>
,它发出单个元素或错误。在 `rx.requestWithProgress(:callbackQueue:)` 的情况下,返回类型是 Observable<ProgressResponse>
,因为我们可能从进度中获得多个事件和一个最后的响应事件。
例如,为了处理错误,我们可以这样做
provider = MoyaProvider<GitHub>()
provider.rx.request(.userProfile("ashfurrow")).subscribe { event in
switch event {
case let .success(response):
image = UIImage(data: response.data)
case let .error(error):
print(error)
}
}
除了使用信号而不是回调块之外,还有一系列针对 RxSwift 和 ReactiveSwift 的信号操作符,它们将尝试将网络响应从数据映射为图像、某些 JSON 或字符串,分别为 mapImage()
、mapJSON()
和 mapString()
。如果映射失败,你将在信号中得到错误。还提供了一些方便的方法来过滤出特定的状态码。这意味着你可以将处理 API 错误如 400 的代码放在与处理无效响应相同的代码位置。
Combine
Combine
扩展提供了 requestPublisher(:callbackQueue:)
和 requestWithProgressPublisher(:callbackQueue)
方法,分别返回 AnyPublisher
和 AnyPublisher
。
以下是一个 requestPublisher
的使用示例:
provider = MoyaProvider<GitHub>()
let cancellable = provider.requestPublisher(.userProfile("ashfurrow"))
.sink(receiveCompletion: { completion in
guard case let .failure(error) = completion else { return }
print(error)
}, receiveValue: { response in
image = UIImage(data: response.data)
})
社区项目
Moya 拥有一个非常棒的社区,有些人创建了一些非常有用的扩展。.
参与贡献
嗨!你喜欢 Moya 吗?太棒了!我们实际上真的需要你的帮助!
开源不仅仅是写代码。Moya 可以在你的以下任何方面得到你的帮助:
- 寻找(并报告!)错误。
- 新功能建议。
- 回答问题。
- 改进文档。
- 评审拉取请求。
- 帮助管理问题优先级。
- 修复错误/新功能。
如果你对其中任何一项都感兴趣,请发送拉取请求!在你的第一次贡献之后,我们将把你添加为仓库成员,这样你就可以合并拉取请求并帮助引领项目。
Moya 的社区拥有巨大的正能量,维护人员致力于保持项目精彩。如在 CocoaPods 社区 中一样,始终假设积极意图;即使评论听起来很刻薄,也要给人好处。
请注意,本项目以贡献者行为守则发布。通过参与本项目,你同意遵守其条款。
添加新源文件
如果你向 Moya 添加或删除源文件,则需要相应地更改此仓库根目录下的 Moya.xcodeproj
项目的设置。该项目用于 Carthage。不用担心,如果你忘记,提交拉取请求时会有自动警告。
帮助我们改进Moya文档
无论是核心成员还是初次尝试的用户,您可以通过改善文档对Moya做出宝贵的贡献。请通过以下方式帮助我们:
- 发送关于您认为模糊或遗漏的内容的反馈
- 建议改进某些主题的表达方式或解释方法
- 通过GitHub发送拉取请求
- 改进中文文档
许可证
Moya遵循MIT许可证发布。有关更多信息,请参阅License.md。