Moya 15.0.0

Moya 15.0.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布上次发布2021年9月
SPM支持 Swift Package Manager

Ash FurrowBoris BüglingPierre-Marc AiroldiColin T.A. GraySunshinejrEsteban TorresAntoine v.d. LeePedro VerezaBas BroekSteven Deutsch 维护。



Moya 15.0.0

Moya 15.0.0

CircleCI codecov.io Carthage compatible Accio supported CocoaPods compatible Swift Package Manager compatible

本文件的中文版本可在这里找到。

您是一位聪明的开发者。您可能使用 Alamofire 来抽象化对 URLSession 的访问,以及那些你并不特别关心的复杂细节。但是,就像许多聪明的开发者一样,您编写了临时的网络抽象层。它们可能被称为 "APIManager" 或 "NetworkModel",并且通常都会以灾难告终。

Moya Overview

临时的网络层在 iOS 应用程序中很常见。它们有几个不好的地方:

  • 难以编写新应用程序(“我从哪里开始?”)
  • 难以维护现有应用程序(“哦,天哪,这是一团糟...”)
  • 难以编写单元测试(“我怎样才能再来一次?”)

所以,Moya 的基本想法是,我们想要一个足够封装直接调用 Alamofire 的网络抽象层。它应该足够简单,以便常见的事情变得容易,但也足够全面,以至于复杂的事情也变得容易。

如果你使用 Alamofire 来抽象化对 URLSession 的访问,为什么不用来抽象化 URL、参数等的细节呢?

Moya 的一些强大功能:

  • 编译时检查正确的 API 端点访问。
  • 让您使用关联枚举值定义不同端点的明确用法。
  • 将测试存根视为一等公民,这使得单元测试变得超级容易。

您可以在愿景文档中了解更多关于项目方向的信息。

示例项目

在仓库中,我们提供了两个示例项目。要使用它,请下载仓库,运行 carthage update 下载所需的库,并打开 Moya.xcodeproj。您将看到两个方案:BasicMulti-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用户可以指向此存储库并使用任意生成的框架,即MoyaRxMoyaReactiveMoyaCombineMoya

在你的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但不是RxSwiftCombine,那么可以安全地删除RxMoyaRxTestRxCocoaCombineMoya等等。

手动方式

  • 打开终端,使用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 iOSAlamofire macOSAlamofire tvOSAlamofire 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 为 ReactiveSwiftRxSwiftCombine 提供了响应式扩展。

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) 方法,分别返回 AnyPublisherAnyPublisher

以下是一个 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