SwiftHTTP 3.0.1

SwiftHTTP 3.0.1

测试已测试
语言语言 SwiftSwift
许可证 Apache 2
发布上次发布2017年12月
SwiftSwift 版本3.0
SPM支持 SPM

Dalton CherryAustin Cherry 维护。



SwiftHTTP 3.0.1

SwiftHTTP

SwiftHTTP 是在 Swift 中围绕 NSURLSession 的一个薄包装器,用于简化 HTTP 请求。

特性

  • 方便的闭包 API
  • 简单的队列支持
  • 参数编码
  • 内建 JSON 请求序列化
  • 带有进度闭包的上传/下载
  • 简洁的代码库。

首先,需要导入框架。有关如何添加框架到项目的安装说明。

import SwiftHTTP

例子

GET

最基本请求。默认情况下,将返回一个 Data 对象用于响应。

HTTP.GET("https://google.com") { response in
	if let err = response.error {
		print("error: \(err.localizedDescription)")
		return //also notify app of failure as needed
	}
    print("opt finished: \(response.description)")
    //print("data is: \(response.data)") access the response of the data with response.data
}

我们也可以添加参数,与标准容器对象类似,并将适当地序列化为各自的 HTTP 相等对象。

//the url sent will be https://google.com?hello=world&param2=value2
HTTP.GET("https://google.com", parameters: ["hello": "world", "param2": "value2"]) { response in
	if let err = response.error {
		print("error: \(err.localizedDescription)")
		return //also notify app of failure as needed
	}
    print("opt finished: \(response.description)")
}

“响应”包含所有常见的 HTTP 响应数据,例如数据的 responseObject 和响应该的标题。

HTTP 方法

所有常见的 HTTP 方法都作为便利方法提供。

POST

let params = ["param": "param1", "array": ["first array element","second","third"], "num": 23, "dict": ["someKey": "someVal"]]
HTTP.POST("https://domain.com/new", parameters: params) { response in
//do things...
}

PUT

HTTP.PUT("https://domain.com/1")

HEAD

HTTP.HEAD("https://domain.com/1")

DELETE

HTTP.DELETE("https://domain.com/1")

下载

HTTP.Download("http://www.cbu.edu.zm/downloads/pdf-sample.pdf", completion: { (response, url) in
    //move the temp file to desired location...
})

上传

可以使用 Upload 对象进行文件上传。所有要上传的文件应封装在 Upload 对象中并作为参数添加。

let fileUrl = URL(fileURLWithPath: "/Users/dalton/Desktop/testfile")!
HTTP.POST("https://domain.com/new", parameters: ["aParam": "aValue", "file": Upload(fileUrl: fileUrl)]) { response in
//do things...
}

Upload 提供了磁盘文件Url版本和数据版本。

自定义头部

可以使用标准的 NSMutableRequest API 向请求添加自定义 HTTP 头部。

HTTP.GET("https://domain.com", parameters: ["hello": "there"], headers: ["header": "value"]) { response in
    //do stuff
}

SSL 固定

SwiftHTTP 也支持 SSL 固定。

var req = URLRequest(urlString: "https://domain.com")!
req?.timeoutInterval = 5
let task = HTTP(req)
task.security = HTTPSecurity(certs: [HTTPSSLCert(data: data)], usePublicKeys: true)
//opt.security = HTTPSecurity() //uses the .cer files in your app's bundle
task.run { (response) in
    if let err = response.error {
        print("error: \(err.localizedDescription)")
        return //also notify app of failure as needed
    }
    print("opt finished: \(response.description)")
}

您可以加载一个包含证书的 Data blob,或者如果您有一个要使用的公钥,可以使用 SecKeyRefusePublicKeys bool 用于判断是否使用证书进行验证或公钥。如果选择 usePublicKeys,将自动从证书中提取公钥。

身份验证

SwiftHTTP 支持通过 NSURLCredential 进行身份验证。目前,仅测试了基本身份验证和摘要身份验证。

var req = URLRequest(urlString: "https://domain.com")!
req.timeoutInterval = 5
let task = HTTP(req)
//the auth closures will continually be called until a successful auth or rejection
var attempted = false
task.auth = { challenge in
    if !attempted {
        attempted = true
        return NSURLCredential(user: "user", password: "passwd", persistence: .ForSession)
    }
    return nil //auth failed, nil causes the request to be properly cancelled.
}
task.run { (response) in
   //do stuff
}

允许所有证书的示例

var req = URLRequest(urlString: "https://domain.com")!
req.timeoutInterval = 5
let task = HTTP(req)
//the auth closures will continually be called until a successful auth or rejection
var attempted = false
task.auth = { challenge in
    if !attempted {
        attempted = true
        return NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)
    }
    return nil //auth failed, nil causes the request to be properly cancelled.
}
task.run { (response) in
   //do stuff
}

操作队列

SwiftHTTP 同样有一个简单的队列!

let queue = HTTPQueue(maxSimultaneousRequest: 2)
var req = URLRequest(urlString: "https://google.com")!
req.timeoutInterval = 5
let task = HTTP(req)
task.onFinish = { (response) in
    print("item in the queue finished: \(response.URL!)")
}
queue.add(http: task) //the request will start running once added to the queue


var req2 = URLRequest(urlString: "https://apple.com")!
req2.timeoutInterval = 5
let task2 = HTTP(req2)
task2.onFinish = { (response) in
    print("item in the queue finished: \(response.URL!)")
}
queue.add(http: task2)

//etc...

queue.finished {
    print("all items finished")
}

取消

比如说,您想稍后取消请求,调用 cancel 方法。

task.cancel()

JSON 请求序列化

需要时,请求参数可以序列化为 JSON。默认情况下,请求使用标准的 HTTP 表单编码进行序列化。

HTTP.GET("https://google.com", requestSerializer: JSONParameterSerializer()) { response in
    //you already get it. The data property of the response object will have the json in it
}

进度

SwiftHTTP 可以监控请求的进度。

var req = URLRequest(urlString: "https://domain.com/somefile")
let task = HTTP(req!)
task.progress = { progress in
    print("progress: \(progress)") //this will be between 0 and 1.
}
task.run { (response) in
   //do stuff
}

全局处理器

SwiftHTTP还具有全局处理器,用于减少重复使用HTTP修改器的要求,例如身份验证头或设置NSMutableURLRequest属性,如timeoutInterval

//modify NSMutableURLRequest for any Factory method call (e.g. HTTP.GET, HTTP.POST, HTTP.New, etc).
HTTP.globalRequest { req in
    req.timeoutInterval = 5
}

//set a global SSL pinning setting
HTTP.globalSecurity(HTTPSecurity()) //see the SSL section for more info

//set global auth handler. See the Auth section for more info
HTTP.globalAuth { challenge in
    return NSURLCredential(user: "user", password: "passwd", persistence: .ForSession)
}

客户端/服务器示例

这是一个SwiftHTTP应用的全示例。首先是一个快速的Go语言Web服务器。

package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
		log.Println("got a web request")
		fmt.Println("header: ", r.Header.Get("someKey"))
		w.Write([]byte("{\"status\": \"ok\"}"))
	})

	log.Fatal(http.ListenAndServe(":8080", nil))
}

现在来请求

struct Response: Codable {
    let status: String
}

let decoder = JSONDecoder()
HTTP.GET("http://localhost:8080/bar") { response in
    if let error = response.error {
        print("got an error: \(error)")
        return
    }
    do {
        let resp = try decoder.decode(Response.self, from: response.data)
        print("completed: \(resp.status)")
    } catch let error {
        print("decode json error: \(error)")
    }
}

POST示例

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "os"
)

func main() {
    http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
        fmt.Println("header: ", r.Header.Get("Content-Type"))
        upload, header, err := r.FormFile("file")
        if err != nil {
            w.Write([]byte("{\"error\": \"bad file upload\"}")) //normally be a 500 status code
            return
        }
        file, err := os.Create(header.Filename) // we would normally need to generate unique filenames.
        if err != nil {
            w.Write([]byte("{\"error\": \"system error occured\"}")) //normally be a 500 status code
            return
        }
        io.Copy(file, upload) // write the uploaded file to disk.
        w.Write([]byte("{\"status\": \"ok\"}")) 
    })

    log.Fatal(http.ListenAndServe(":8080", nil))
}

现在是Swift

struct Response: Codable {
    let status: String?
    let error: String?
}

let decoder = JSONDecoder()
let url = URL(fileURLWithPath: "/Users/dalton/Desktop/picture.jpg")
HTTP.POST("http://localhost:8080/bar", parameters: ["test": "value", "file": Upload(fileUrl: url)]) { response in
    if let error = response.error {
        print("got an error: \(error)")
        return
    }
    do {
        let resp = try decoder.decode(Response.self, from: response.data)
        if let err = resp.error {
            print("got an error: \(err)")
        }
        if let status = resp.status {
            print("completed: \(status)")
        }
    } catch let error {
        print("decode json error: \(error)")
    }
}

要求

SwiftHTTP与iOS 7/OSX 10.10或更高版本兼容。建议使用iOS 8/10.10或更高版本以获得CocoaPods框架支持。
要使用针对iOS 7的项目中的SwiftHTTP,您必须将所有Swift文件直接包含在您的项目中。

安装

CocoaPods

查看入门标签页,请访问cocoapods.org

要使用SwiftHTTP在您的项目中,请将以下'Podfile'添加到您的项目中

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!

pod 'SwiftHTTP', '~> 3.0.1'

然后运行

pod install

Carthage

查看Carthage文档了解如何添加安装。已为SwiftHTTP框架设置了共享方案。

Carthage 安装

您可以使用以下命令通过Homebrew安装Carthage

$ brew update
$ brew install carthage

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

github "daltoniam/SwiftHTTP" >= 3.0.1

Rogue

首先查看安装文档了解如何安装Rogue。

要安装SwiftHTTP,在创建rogue文件的目录中运行以下命令

rogue add https://github.com/daltoniam/SwiftHTTP

接下来,打开libs文件夹,并将SwiftHTTP.xcodeproj添加到您的Xcode项目中。完成后,在“构建阶段”中添加SwiftHTTP.framework到“链接二进制库”阶段。请确保将libs文件夹添加到您的.gitignore文件。

其他

直接获取框架(通过git子模块或另一个包管理器)。

SwiftHTTP.xcodeproj添加到您的Xcode项目中。完成后,在“构建阶段”中添加SwiftHTTP.framework到“链接二进制库”阶段。

添加复制框架阶段

如果您在OSX应用程序或物理iOS设备上运行此应用程序,请确保将包含在您的应用程序包中的SwiftHTTP.framework添加到项目中。为此,在Xcode中,通过单击蓝色项目图标并选择侧边栏中的“目标”标题下的应用程序目标来转到目标配置窗口。在窗口顶部的标签栏中,打开“构建阶段”面板。展开“链接二进制库”组,并添加SwiftHTTP.framework。单击面板左上角的+按钮,选择“新建复制文件阶段”。将此新阶段重命名为“复制框架”,设置“目标”为“框架”,并添加SwiftHTTP.framework

待办事项

  • Linux支持?
  • 添加更多单元测试

许可证

SwiftHTTP采用Apache v2许可证。

联系

Dalton Cherry