Just-一個輕量級網(wǎng)絡(luò)加載庫

Just.png

前言

最近在做Swift3遷移工作的時候,遇到了一個很尷尬的事情,Alamofire的庫最低支持iOS 9.0了,可是我們的項(xiàng)目必須支持iOS 8.0+,本著不重復(fù)造輪子的想法,于是我決定換一個輕量級的網(wǎng)絡(luò)加載庫Just
原文地址

Talk is cheap, show me the code!

請求方式

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

同步請求\異步請求

Just支持同步請求和異步請求,Alamofre支持異步請求,不過我們平時開發(fā)中大多數(shù)請求也都是異步完成的

當(dāng)我們用Swift開發(fā)時,我們傾向于避開同步網(wǎng)絡(luò)請求,因?yàn)橥秸埱髸枞骶€程,這將影響Cocoa/Cocoa Touch應(yīng)用程序刷新UI。然而,使用同步請求也沒有什么inherantly立膛。事實(shí)上,同步的代碼通常更容易理解揪罕。

// 發(fā)起一個同步請求
var r = Just.get("http://httpbin.org/get", params:["page": 3])
// … "r" becomes available here

想變成異步請求也是非常簡單的

// 發(fā)起一個異步請求
Just.get("http://httpbin.org/get", params:["page": 3]) { (r) in   
    // the same "r" is available asynchronously here
}

但是需要注意的是異步請求的callback是不運(yùn)行在主線程的因此我們?nèi)绻朐赾allback中刷新UI必須自己使用GCD或者NSOperationQueue來回到主線程

HTTP REQUEST

雖然上面的簡單的例子都是調(diào)用具體的get/post請求方法 但是這些方法最終還是調(diào)用 JustAdaptor 的方法,JustAdaptor是個protocol 這就體現(xiàn)了Swift面向協(xié)議開發(fā)的強(qiáng)大之處.
Show the code:

public protocol JustAdaptor {
  func request(
    _ method: HTTPMethod, // 請求方式
    URLString: String, // 請求地址
    params: [String: Any], // 請求參數(shù) 使用字典樣式
    data: [String: Any], // 請求參數(shù) 例如 表單數(shù)據(jù)
    json: Any?, // 請求參數(shù)
    headers: [String: String], // 請求頭信息 字典樣式
    files: [String: HTTPFile], // 上傳文件
    auth: Credentials?, // 認(rèn)證信息
    cookies: [String: String], // 請求cookie
    redirects: Bool, // 是否允許重定向
    timeout: Double?, // 超時時間
    URLQuery: String?, // 
    requestBody: Data?, // 請求體
    asyncProgressHandler: TaskProgressHandler?, // 進(jìn)度操作 用于做上傳或下載的進(jìn)度
    asyncCompletionHandler: ((HTTPResult) -> Void)? // 完成操作 所有的服務(wù)器返回信息包在HTTPResult對象中
    ) -> HTTPResult

  init(session: URLSession?, defaults: JustSessionDefaults?)
}

簡單的請求

GET請求
一個簡單的get請求:

// 無參數(shù)
Just.get("http://httpbin.org/get"){ (r) in   
    // 異步請求結(jié)果
}
// 帶參數(shù)
Just.get("http://httpbin.org/get", params:["page": 3]) { (r) in   
    // 異步請求結(jié)果
}

POST請求
一個簡單的post請求:

Just.post("http://httpbin.org/post") { (r) in   
    // 異步請求結(jié)果
}

還有很多別的請求方式就不在一一贅述.

取消請求

有開啟請求自然也有取消請求方法

r.cancel()

更復(fù)雜的請求

如果想發(fā)送表單數(shù)據(jù),可以用data參數(shù):

// 請求體會變成firstName=Barry&lastName=Allen
// Content-Type頭信息將加入application/x-form-www-encoded
Just.post("http://httpbin.org/post", data:["firstName":"Barry","lastName":"Allen"])

JSON數(shù)據(jù)也是一樣的

// 請求體是JSON encoded
// Content-Type頭信息呢是'application/json'
Just.post("http://httpbin.org/post", json:["firstName":"Barry","lastName":"Allen"])

Redirect

默認(rèn)情況下,Just會遵循服務(wù)器的redirect設(shè)置,你也可以用allowRedirect控制這種行為

// redirects
Just.get("http://httpbin.org/redirect/2").isRedirect // false
// no redirects
Just.get("http://httpbin.org/redirect/2", allowRedirects:false).isRedirect // true

此外, 你也可以設(shè)置永久redirect

// permanent redirect
Just.get("http://httpbin.org/status/301", allowRedirects:false).isPermanentRedirect // true
// non permanent redirect
Just.get("http://httpbin.org/status/302", allowRedirects:false).isPermanentRedirect // false

FILES

用Just上傳文件也是很簡單的

import Foundation

let elonPhotoURL = Bundle.main.url(forResource: "elon", withExtension: "jpg")!
let uploadResult = Just.post("http://httpbin.org/post", files:["elon": .url(elonPhotoURL, nil)]) // <== that's it
print(uploadResult.text ?? "")

在這里梯码,文件是用一個NSURL指定。 或者好啰,一個文件可以是操作文件數(shù)據(jù)或只是一個字符串轩娶。但是在這兩種情況下,需要一個文件名框往。

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"], // 參數(shù)
    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"]
 // <https://api.github.com/user/75067/repos?page=2&per_page=5>; rel="next", <https://api.github.com/user/75067/repos?page=9&per_page=5>; 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

如果你希望服務(wù)器返回cookie可以這么做:

// returns an NSHTTPCookie
Just.get("http://httpbin.org/cookies/set/name/elon", allowRedirects:false).cookies["name"]

發(fā)起一個帶著cookie的請求

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

AUTHENTICATION

如果請求是受到基本身份驗(yàn)證或摘要式身份驗(yàn)證鳄抒,請使用身份驗(yàn)證參數(shù)元組提供用戶名和密碼

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

TIMEOUT

你也可以設(shè)置超時時間

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 // 當(dāng)前大小
        p.bytesExpectedToProcess // 總大小
        p.percent // 百分比
    }
) { r in
    // finished
}

CUSTOMIZATION / ADVANCED USAGE

如果你想改變Just的一些默認(rèn)設(shè)置,需要使用JustSessionDefaults自定義寫個性化設(shè)置

let myJustDefaults = JustSessionDefaults(
    // NSJSONSerialization reading options
    JSONReadingOptions: .mutableContainers, 
    // NSJSONSerialization writing options
    JSONWritingOptions: .prettyPrinted, 
    // 每個請求的頭信息
    headers:  ["OH":"MY"],     
    // 多部分post請求邊界             
    multipartBoundary: "Ju5tH77P15Aw350m3",
    // NSURLCredential持久性選項(xiàng)
    credentialPersistence: .none,
    // en(de)coding for HTTP body
    encoding: String.Encoding.utf8         
)

使用:

let just = JustOf<HTTP>(defaults: myJustDefaults)
just.post("http://httpbin.org/post").request?.allHTTPHeaderFields?["OH"] ?? ""

HTTP RESULT

HTTP請求的結(jié)果被放在一個單一的對象
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.ok
r.statusCode

其他描述:

// 服務(wù)器返回?cái)?shù)據(jù)
r.headers // response headers
r.content // response body as NSData?
r.text // response body as text?
r.json // response body parsed by NSJSONSerielization
r.url // the URL, as URL
r.isRedirect // is this a redirect response

總結(jié)

由于本人學(xué)識短淺,文章有錯誤的地方還望不吝指出.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市椰弊,隨后出現(xiàn)的幾起案子许溅,更是在濱河造成了極大的恐慌,老刑警劉巖秉版,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贤重,死亡現(xiàn)場離奇詭異,居然都是意外死亡清焕,警方通過查閱死者的電腦和手機(jī)游桩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來耐朴,“玉大人,你說我怎么就攤上這事盹憎∩盖停” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵陪每,是天一觀的道長影晓。 經(jīng)常有香客問我,道長檩禾,這世上最難降的妖魔是什么挂签? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮盼产,結(jié)果婚禮上饵婆,老公的妹妹穿的比我還像新娘。我一直安慰自己戏售,他們只是感情好侨核,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著灌灾,像睡著了一般搓译。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上锋喜,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天些己,我揣著相機(jī)與錄音豌鸡,去河邊找鬼。 笑死段标,一個胖子當(dāng)著我的面吹牛涯冠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播怀樟,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼功偿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了往堡?” 一聲冷哼從身側(cè)響起械荷,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎虑灰,沒想到半個月后吨瞎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡穆咐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年颤诀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片对湃。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡崖叫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拍柒,到底是詐尸還是另有隱情心傀,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布拆讯,位于F島的核電站脂男,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏种呐。R本人自食惡果不足惜宰翅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望爽室。 院中可真熱鬧汁讼,春花似錦、人聲如沸阔墩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽戈擒。三九已至眶明,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間筐高,已是汗流浹背搜囱。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工丑瞧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蜀肘。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓绊汹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親扮宠。 傳聞我的和親對象是個殘疾皇子西乖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)坛增,斷路器获雕,智...
    卡卡羅2017閱讀 134,601評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,520評論 25 707
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司收捣,掛了不少届案,但最終還是拿到小米、百度罢艾、阿里楣颠、京東、新浪咐蚯、CVTE童漩、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,192評論 11 349
  • iOS網(wǎng)絡(luò)編程讀書筆記 Facade Tester客戶端門面模式的實(shí)例(被動版本化) 被動版本化,所以硬編碼URL...
    melouverrr閱讀 1,600評論 3 7
  • 小貓咪GG終于被帶回家了 啦啦啦春锋,好嗨森吶 射手給大家講講這個救助站吧 這個救助里面有很多狗狗 很多狗狗是因?yàn)樯眢w...
    J叔說星座閱讀 389評論 0 0