博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Just 一个轻量级网络加载库
阅读量:6554 次
发布时间:2019-06-24

本文共 6740 字,大约阅读时间需要 22 分钟。

前言

最近在做Swift3迁移工作的时候,遇到了一个很尴尬的事情,Alamofire的库最低支持iOS 9.0了,可是我们的项目必须支持iOS 8.0+,本着不重复造轮子的想法,于是我决定换一个轻量级的网络加载库

Talk is cheap, show me the code!

请求方式

Just支持的请求方式有: DELETE  GET HEAD OPTIONS PATCH POST  PUT

同步请求\异步请求

Just支持同步请求和异步请求,Alamofre支持异步请求,不过我们平时开发中大多数请求也都是异步完成的

当我们用Swift开发时,我们倾向于避开同步网络请求,因为同步请求会阻塞主线程,这将影响Cocoa/Cocoa Touch应用程序刷新UI。然而,使用同步请求也没有什么inherantly。事实上,同步的代码通常更容易理解。

// 发起一个同步请求var r = Just.get("http://httpbin.org/get", params:["page": 3])// … "r" becomes available here复制代码

想变成异步请求也是非常简单的

// 发起一个异步请求Just.get("http://httpbin.org/get", params:["page": 3]) { (r) in       // the same "r" is available asynchronously here}复制代码

但是需要注意的是异步请求的callback是不运行在主线程的因此我们如果想在callback中刷新UI必须自己使用GCD或者NSOperationQueue来回到主线程

HTTP REQUEST

虽然上面的简单的例子都是调用具体的get/post请求方法 但是这些方法最终还是调用 JustAdaptor 的方法,JustAdaptor是个protocol 这就体现了Swift面向协议开发的强大之处. Show the code:

public protocol JustAdaptor {  func request(    _ method: HTTPMethod, // 请求方式    URLString: String, // 请求地址    params: [String: Any], // 请求参数 使用字典样式    data: [String: Any], // 请求参数 例如 表单数据    json: Any?, // 请求参数    headers: [String: String], // 请求头信息 字典样式    files: [String: HTTPFile], // 上传文件    auth: Credentials?, // 认证信息    cookies: [String: String], // 请求cookie    redirects: Bool, // 是否允许重定向    timeout: Double?, // 超时时间    URLQuery: String?, //     requestBody: Data?, // 请求体    asyncProgressHandler: TaskProgressHandler?, // 进度操作 用于做上传或下载的进度    asyncCompletionHandler: ((HTTPResult) -> Void)? // 完成操作 所有的服务器返回信息包在HTTPResult对象中    ) -> HTTPResult  init(session: URLSession?, defaults: JustSessionDefaults?)}复制代码

简单的请求

GET请求 一个简单的get请求:

// 无参数Just.get("http://httpbin.org/get"){ (r) in       // 异步请求结果}// 带参数Just.get("http://httpbin.org/get", params:["page": 3]) { (r) in       // 异步请求结果}复制代码

POST请求 一个简单的post请求:

Just.post("http://httpbin.org/post") { (r) in       // 异步请求结果}复制代码

还有很多别的请求方式就不在一一赘述.

取消请求

有开启请求自然也有取消请求方法

r.cancel()复制代码

更复杂的请求

如果想发送表单数据,可以用data参数:

// 请求体会变成firstName=Barry&lastName=Allen// Content-Type头信息将加入application/x-form-www-encodedJust.post("http://httpbin.org/post", data:["firstName":"Barry","lastName":"Allen"])复制代码

JSON数据也是一样的

// 请求体是JSON encoded// Content-Type头信息呢是'application/json'Just.post("http://httpbin.org/post", json:["firstName":"Barry","lastName":"Allen"])复制代码

Redirect

默认情况下,Just会遵循服务器的redirect设置,你也可以用allowRedirect控制这种行为

// redirectsJust.get("http://httpbin.org/redirect/2").isRedirect // false// no redirectsJust.get("http://httpbin.org/redirect/2", allowRedirects:false).isRedirect // true复制代码

此外, 你也可以设置永久redirect

// permanent redirectJust.get("http://httpbin.org/status/301", allowRedirects:false).isPermanentRedirect // true// non permanent redirectJust.get("http://httpbin.org/status/302", allowRedirects:false).isPermanentRedirect // false复制代码

FILES

用Just上传文件也是很简单的

import Foundationlet elonPhotoURL = Bundle.main.url(forResource: "elon", withExtension: "jpg")!let uploadResult = Just.post("http://httpbin.org/post", files:["elon": .url(elonPhotoURL, nil)]) // <== that's itprint(uploadResult.text ?? "")复制代码

在这里,文件是用一个NSURL指定。 或者,一个文件可以是操作文件数据或只是一个字符串。但是在这两种情况下,需要一个文件名。

let someData = "Marco".data(using: String.Encoding.utf8)! if let text = Just.post(    "http://httpbin.org/post",    files:[        "a":.data("marco.text", someData, nil), //一个 Data类型文件        "b":.text("polo.txt", "Polo", nil)      // 一个 String类型文件    ]    ).text {    print(text)}复制代码

还可以这样;

if let json = Just.post(    "http://httpbin.org/post",    data:["lastName":"Musk"], // 参数    files:["elon":.url(elonPhotoURL, nil)] // 文件    ).json as? [String:AnyObject] {    print(json["form"] ?? [:])      // lastName:Musk    print(json["files"] ?? [:])     // elon}复制代码

LINK HEADERS

许多HTTP api链接头,增加api的自我描述 例如 Github分页功能API就是这样:

let gh = Just.head("https://api.github.com/users/dduan/repos?page=1&per_page=5")gh.headers["link"] // 
; rel="next",
; rel="last"复制代码

Just对于解析link headers更容易:

gh.links["next"] // ["rel": "next", "url":"https://api.github.com/user/75067/repos?page=2&per_page=5"]gh.links["last"] // ["rel": "last", "url":"https://api.github.com/user/75067/repos?page=9&per_page=5"]复制代码

COOKIE

如果你希望服务器返回cookie可以这么做:

// returns an NSHTTPCookieJust.get("http://httpbin.org/cookies/set/name/elon", allowRedirects:false).cookies["name"]复制代码

发起一个带着cookie的请求

Just.get("http://httpbin.org/cookies", cookies:["test":"just"]) // ok复制代码

AUTHENTICATION

如果请求是受到基本身份验证或摘要式身份验证,请使用身份验证参数元组提供用户名和密码

Just.get("http://httpbin.org/basic-auth/flash/allen", auth:("flash", "allen")) // ok复制代码

TIMEOUT

你也可以设置超时时间

Just.get("http://httpbin.org/delay/5", timeout:0.2).reason复制代码

UPLOAD AND DOWNLOAD PROGRESS

上传和下载文件也是很简单

Just.post(    "http://httpbin.org/post",    files:["large file":.text("or", "pretend this is a large file", nil)],    asyncProgressHandler: { p in        p.type // 方式 .Upload or .Download        p.bytesProcessed // 当前大小        p.bytesExpectedToProcess // 总大小        p.percent // 百分比    }) { r in    // finished}复制代码

CUSTOMIZATION / ADVANCED USAGE

如果你想改变Just的一些默认设置,需要使用JustSessionDefaults自定义写个性化设置

let myJustDefaults = JustSessionDefaults(    // NSJSONSerialization reading options    JSONReadingOptions: .mutableContainers,     // NSJSONSerialization writing options    JSONWritingOptions: .prettyPrinted,     // 每个请求的头信息    headers:  ["OH":"MY"],         // 多部分post请求边界                 multipartBoundary: "Ju5tH77P15Aw350m3",    // NSURLCredential持久性选项    credentialPersistence: .none,    // en(de)coding for HTTP body    encoding: String.Encoding.utf8         )复制代码

使用:

let just = JustOf
(defaults: myJustDefaults)just.post("http://httpbin.org/post").request?.allHTTPHeaderFields?["OH"] ?? ""复制代码

HTTP RESULT

HTTP请求的结果被放在一个单一的对象 Show the code:

public final class HTTPResult : NSObject {  public final var content: Data?  public var response: URLResponse?  public var error: Error?  public var request: URLRequest? { return task?.originalRequest }  public var task: URLSessionTask?  public var encoding = String.Encoding.utf8  public var JSONReadingOptions = JSONSerialization.ReadingOptions(rawValue: 0)  public var ok: Bool {    return statusCode != nil && !(statusCode! >= 400 && statusCode! < 600)  }  public var json: Any? {    return content.flatMap {      try? JSONSerialization.jsonObject(with: $0, options: JSONReadingOptions)    }  }  public var statusCode: Int? {    return (self.response as? HTTPURLResponse)?.statusCode  }  ......复制代码

判断请求是否成功可以用ok或者statusCode两个属性

r.okr.statusCode复制代码

其他描述:

// 服务器返回数据r.headers // response headersr.content // response body as NSData?r.text // response body as text?r.json // response body parsed by NSJSONSerielizationr.url // the URL, as URLr.isRedirect // is this a redirect response复制代码

总结

由于本人学识短浅,文章有错误的地方还望不吝指出.

转载于:https://juejin.im/post/5aa542b8f265da238b7da2ad

你可能感兴趣的文章
Neo4j CQL -(17)- NULL值
查看>>
BZOJ4554: [Tjoi2016&Heoi2016]游戏 luoguP2825 loj2057
查看>>
json_encode后的中文不编码成unicode
查看>>
iOS 导航栏title显示右偏移
查看>>
字符串处理 2015百度之星资格赛 1002 列变位法解密
查看>>
修改纵断面图标注栏
查看>>
Linux 杂记
查看>>
Flex创建带有空间信息的椭圆(Polygon)
查看>>
【转】参照protobuf,将json数据转换成二进制在网络中传输。
查看>>
wpf 输入停止一段时间后。执行事件
查看>>
享元模式
查看>>
Python中的str与bytes之间的转换的三种方法
查看>>
java异常常见面试问题
查看>>
课后作业5
查看>>
Centos7.1环境下搭建BugFree
查看>>
共用y轴的双图形绘制
查看>>
(错误) Eclipse使用Maven创建Web时错误
查看>>
第31讲 | 数字货币钱包服务
查看>>
P2073 送花
查看>>
iOS端项目注释规范附统一代码块
查看>>