RxCocoaNetworking

一个非常轻量级的网络框架,构建于 RxCocoa 之上,专为使用 RxTest 进行测试而设计,并受到 Moya 的启发。

Swift 4.2 codecov.io Platforms

CocoaPods compatible Carthage compatible Swift Package Manager

虽然 Moya 构建于 Alamofire 之上,并提供具有 Observable 签名的 Rx 扩展,但 RxCocoaNetworking 构建于 RxCocoa 之上,后者已经为 NSURLSession 提供了带有 Observable 签名的扩展。如果以下情况,RxCocoaNetworking 适合你:

... 如果以下情况,还有额外加分:

但请注意,这绝不是 Alamofire+Moya 的完全替代品。 例如,你可能会错过一些功能,只有当 RxCocoaNetworking 保持极其轻量级时才会被支持,例如:

... 在这种情况下,Alamofire+Moya 会是更好的选择。

这个框架的实现归功于 RxCocoa 中已经嵌入的网络请求处理,以及 Swift 4.1 的条件一致性(参见 ReactiveURLSessionProtocol)。

要求

用法

如果你已经习惯了 Moya,那么好消息是 RxCocoaNetworking(有意地)具有非常相似的架构!你所需要做的就是创建一个结构来表示你的 API - 建议使用 enum - 并使其实现 TargetType 协议之一。 对你的 API 的请求由一个 Provider 管理,该 Provider 被类型化为你的具体 TargetType

无论你是否习惯使用 Moya,另一个好消息是你可以基于示例 ExampleAPI 及其 spec 进行构建。

总结 `ExampleAPI`

enum ExampleAPI {
  // Endpoints as cases:
  case rate(movieID: String, rating: Float)
  case reviews(movieID: String, page: Int)
}

extension ExampleAPI: ProductionTargetType {
  // Your API's base URL is usually what determines an API enum.
  var baseURL: URL { return URL(string: "...")! }
  
  var path: String {
    switch self {
    case .rate(let movieID, _):
      return "/movie/\(movieID)/rating"
    case .reviews(let movieID, _):
      return "/movie/\(movieID)/reviews"
    }
  }
  
  var task: Task {
    // Specify GET/POST/etc., body and query parameters:
    switch self {
    case .rate(_, let rating):
      return Task(method: .post, dictionaryBody: ["value": rating])
    case .reviews(_, let page):
      return Task(parameters: parameters)
    }
  }
  
  var headers: [String : String]? { return nil }
}

extension ExampleAPI: TargetType {
  var sampleData: Data {
    ...
  }
}

常规网络请求(没有桩)

let provider = Provider<ExampleAPI>()

默认的 Provider 参数通常是你将在生产代码中使用的参数。

立即桩化的网络响应

let provider = Provider<ExampleAPI>(stubBehavior: .immediate(stub: .default))

stub: .default 表示将使用 API 中的 sampleData。 其他 Stub 类型允许你内联指定不同的响应。

注意: 如果你实现了 ProductionTargetType,那么 stub: .default 不可用,因为该协议不需要 sampleData 👌 你总是可以单独实现 TargetType,例如,在 Tests 目标中。

可进行 RxTest 测试的延迟桩化网络响应

let testScheduler = TestScheduler(initialClock: 0)
let provider = Provider<ExampleAPI>(stubBehavior: .delayed(time: 3,
                                                           stub: .error(SomeError.anError)),
                                    scheduler: testScheduler)

订阅发生后,将在 3 个虚拟时间单位后发出一个 error

安装

依赖管理工具

CocoaPods

CocoaPods 是 Cocoa 项目的依赖管理工具。 你可以使用以下命令安装它:

$ gem install cocoapods

要使用 CocoaPods 将 RxCocoaNetworking 集成到你的 Xcode 项目中,请在你的 Podfile 中指定它:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'

pod 'RxCocoaNetworking', '~> 0.2.2'

然后,运行以下命令:

$ pod install
Carthage

Carthage 是一个分散的依赖管理工具,可自动将框架添加到你的 Cocoa 应用程序。

你可以使用 Homebrew 使用以下命令安装 Carthage:

$ brew update
$ brew install carthage

要使用 Carthage 将 RxCocoaNetworking 集成到你的 Xcode 项目中,请在你的 Cartfile 中指定它:

github "gobetti/RxCocoaNetworking" ~> 0.2.2
Swift Package Manager

要将 RxCocoaNetworking 用作 Swift Package Manager 包,只需在你的 Package.swift 文件中添加以下内容即可。

// swift-tools-version:4.1
import PackageDescription

let package = Package(
    name: "HelloRxCocoaNetworking",
    dependencies: [
        .package(url: "https://github.com/gobetti/RxCocoaNetworking.git", .upToNextMajor(from: "0.2.2"))
    ],
    targets: [
        .target(name: "HelloRxCocoaNetworking", dependencies: ["RxCocoaNetworking"])
    ]
)

手动

如果你不想使用上述任何一个依赖管理工具,则可以手动将 RxCocoaNetworking 集成到你的项目中。

Git 子模块

$ git init
$ git submodule add https://github.com/gobetti/RxCocoaNetworking.git
$ git submodule update --init --recursive

RxCocoaNetworking.framework 会自动添加为目标依赖项、链接框架和嵌入框架,在复制文件构建阶段中,这就是你在模拟器和设备上进行构建所需的一切。

嵌入式二进制文件

贡献

欢迎提出问题和拉取请求!

克隆项目后,在构建项目之前,你需要做的就是安装 Carthage 依赖项

$ carthage bootstrap

然后,要成功运行单元测试,你需要让 wiremock 脚本在后台运行

$ ./script/wiremock.sh

作者

Marcelo Gobetti @mwgobetti

许可证

RxCocoaNetworking 在 MIT 许可证下发布。 有关详细信息,请参阅 LICENSE