Restofire 是一个面向协议的网络客户端,为 Alamofire。
特点
- 全局配置主机/标头/参数等
- 分组配置
- 每个请求的配置
- 身份验证
- 响应验证
- 类似JSONDecodable的自定义响应序列化
- 将网络请求与ViewController隔离
- 基于URLError代码自动重试
- 网络可达时最终请求
- NSOperations
- 完整文档
要求
- iOS 10.0+ / Mac OS X 10.12+ / tvOS 10.0+ / watchOS 3.0+
- Xcode 10
安装
依赖管理器
CocoaPods
CocoaPods 是 Cocoa 项目的依赖管理器。您可以使用以下命令进行安装
$ gem install cocoapods
要使用 CocoaPods 将 Restofire 集成到您的 Xcode 项目中,请在您的 Podfile
中指定
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!
pod 'Restofire', '~> 5.0'
然后,运行以下命令
$ pod install
Carthage
Carthage 是一个分散式的依赖管理器,它自动处理将框架添加到您的 Cocoa 应用程序的过程。
您可以使用以下命令使用 Homebrew 安装 Carthage
$ brew update
$ brew install carthage
要使用 Carthage 将 Restofire 集成到您的 Xcode 项目中,请在您的 Cartfile
中指定
github "Restofire/Restofire" ~> 5.0
Swift 包管理器
要将 Restofire 作为 Swift 包管理器 包使用,只需在您的 Package.swift 文件中添加以下内容。
import PackageDescription
let package = Package(
name: "HelloRestofire",
dependencies: [
.Package(url: "https://github.com/Restofire/Restofire.git", from: "5.0.0")
]
)
手动
如果您不想使用上述任何依赖管理器,您可以手动将 Restofire 集成到项目中。
Git 子模块
- 打开终端,
cd
到您的顶级项目目录,并运行以下命令(如果您的项目没有初始化为 git 仓库)
$ git init
- 通过运行以下命令将 Restofire 添加为 git 子模块
$ git submodule add https://github.com/Restofire/Restofire.git
$ git submodule update --init --recursive
-
打开新的
Restofire
文件夹,并将Restofire.xcodeproj
拖到您应用程序的 Xcode 项目的 Project Navigator 中。它应该出现在您的应用程序蓝色项目图标下方。它是在所有其他 Xcode 组之上还是之下无关紧要。
-
在 Project Navigator 中选择
Restofire.xcodeproj
并验证其部署目标与您的应用程序目标的部署目标相匹配。 -
接下来,选择 Project Navigator 中的应用程序项目(蓝色项目图标)以转到目标配置窗口,并在侧边栏中的“Targets”标题下选择应用程序目标。
-
在该窗口的选项卡栏上,打开“通用”面板。
-
在“嵌入式二进制文件”部分下点击
+
按钮。 -
您将看到两个不同的
Restofire.xcodeproj
文件夹,每个文件夹中都有一个嵌套在“Products”文件夹中的不同版本的Restofire.framework
。您选择哪个“Products”文件夹无关紧要。
-
选择
Restofire.framework
和Alamofire.framework
。 -
就这样!
自动将
Restofire.framework
添加为目标依赖项,链接框架并嵌入到复制文件构建阶段,这是您在模拟器和设备上构建所需要的一切。
嵌入式二进制文件
- 从 https://github.com/Restofire/Restofire/releases 下载最新版本。
- 接下来,选择 Project Navigator 中的应用程序项目(蓝色项目图标)以转到目标配置窗口,并在侧边栏中的“Targets”标题下选择应用程序目标。
- 在该窗口的选项卡栏上,打开“通用”面板。
- 在“嵌入式二进制文件”部分下点击
+
按钮。 - 添加下载的
Restofire.framework
和Alamofire.framework
。 - 就这样!
配置
三个级别的配置
- 全局配置 – 全局配置将应用于所有请求。这包括方案、主机、版本、头部、会话管理器、回调队列、最大重试次数、等待连通性等值。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Restofire.Configuration.default.host = "httpbin.org"
Restofire.Retry.default.retryErrorCodes = [.requestTimedOut,.networkConnectionLost]
return true
}
- 组配置 – 组配置继承自全局配置的所有值。它可以用来对具有相同行为但与全局配置不同的请求进行分组。例如,如果您有多个主机或者您的全局配置具有默认URL会话并且一些请求需要您使用短暂URL会话。
import Restofire
protocol ApiaryConfigurable: Configurable {}
extension ApiaryConfigurable {
public var configuration: Configuration {
var configuration = Configuration.default
configuration.host = "private-07c21-rahulkatariya.apiary-mock.com"
configuration.headers = ["Content-Type": "application/json"]
return configuration
}
}
protocol ApiaryRequestable: Requestable, ApiaryConfigurable {}
import Restofire
struct NoteResponseModel: Decodable {
var id: Int16
var title: String
}
struct NotesGETService: ApiaryRequestable {
typealias Response = [NoteResponseModel]
var path: String? = "notes"
}
- 请求特定配置 – 请求配置继承自组配置或直接继承自全局配置。
import Restofire
struct NoteRequestModel: Encodable {
var title: String
}
struct NotePOSTService: Requestable {
typealias Response = NoteResponseModel
let host: String = "private-07c21-rahulkatariya.apiary-mock.com"
let headers = ["Content-Type": "application/json"]
let path: String? = "notes"
let method: HTTPMethod = .post
var parameters: Any?
init(parameters: NoteRequestModel) {
let data = try! JSONEncoder().encode(parameters)
self.parameters = try! JSONSerialization.jsonObject(with: data, options: .allowFragments)
}
}
使用方法
制作请求
Requestable
提供完成处理程序以启用请求数据、接收响应。
import Restofire
class ViewController: UITableViewController {
var notes: [NoteResponseModel]!
var requestOp: RequestOperation<NotesGetAllService>!
override func viewDidLoad() {
super.viewDidLoad()
// We want to cancel the request to save resources when the user pops the view controller.
requestOp = NotesGetAllService().execute() {
if let value = $0.result.value {
self.notes = value
}
}
}
func postNote(title: String) {
let noteRequestModel = NoteRequestModel(title: title)
// We don't want to cancel the request even if user pops the view controller.
NotePOSTService(parameters: noteRequestModel).execute()
}
deinit {
requestOp.cancel()
}
}
从 UIViewControllers 隔离网络请求
Requestable
提供代理方法以在任何地方启用请求数据并在您的缓存中存储数据。
import Restofire
struct NotesGetAllService: ApiaryRequestable {
...
func request(_ request: RequestOperation<NotesGetAllService>, didCompleteWithValue value: [NoteResponseModel]) {
// Here you can store the results into your cache and then listen for changes inside your view controller.
}
}
自定义响应序列化器
- 可解码的
在项目中添加以下代码片段,将使所有关联类型为 Requestable
的响应自动使用 JSONDecoder 进行解码。
import Restofire
extension Restofire.DataResponseSerializable where Response: Decodable {
public var responseSerializer: DataResponseSerializer<Response> {
return DataRequest.JSONDecodableResponseSerializer()
}
}
- JSON
在项目中添加以下代码片段,将使所有关联类型为 Any
的 Requestable
响应使用 NSJSONSerialization 进行解码。
import Restofire
extension Restofire.DataResponseSerializable where Response == Any {
public var responseSerializer: DataResponseSerializer<Response> {
return DataRequest.jsonResponseSerializer()
}
}
等待网络连通性
Requestable
提供了一个可以设置为 true 的属性 waitsForConnectivity
。这会使第一个请求无论网络是否连通都执行。如果请求由于 .notConnectedToInternet 失败,它将在连接建立后重试请求。
struct PushTokenPutService: Requestable {
typealias Response = Data
...
var waitsForConnectivity: Bool = true
}
贡献
问题和拉取请求都欢迎!
作者
Rahul Katariya @rahulkatariya91
许可
Restofire 在 MIT 许可下发布。有关详细信息,请参阅 LICENSE。