BothamNetworking 4.0.2

BothamNetworking 4.0.2

测试已测试
语言语言 SwiftSwift
许可证 Apache-2.0
发布最后发布2019年1月
SPM支持 SPM

Karumi 维护。



Karumi logo BothamNetworking Build Status CocoaPods

BothamNetworking 是用 Swift 编写的网络框架。

此项目将帮助您轻松设置所有 API 客户端并实现您的网络层。BothamNetworking 提供了类来发送 HTTP 请求并获取等待解析的 HTTP 响应,只需几行代码即可。

此外,

##使用方法

此框架包含实现您的网络层所需的所有类,并通过名为 BothamAPIClient 的易于使用的界面来实现。如果您喜欢 Swift Playgrounds,则可以克隆此项目并查看我们创建的 playgrounds,以了解如何使用此框架。

###使用不同的 HTTP 方法发送请求

let apiClient = BothamAPIClient(baseEndpoint: "https://api.github.com/repos/Karumi/BothamNetworking")

apiClient.GET("/issues")

apiClient.POST("/issues")

apiClient.PUT("/issues")

apiClient.DELETE("/issues/1")

###向请求添加头信息

apiClient.GET("/issues", headers: ["User-Agent": "BothamNetworking Headers", "Accept": "application/json; q=0.5"]) 

###向请求添加参数

apiClient.DELETE("/issues", parameters: ["id": "1"])

###向请求添加正文

apiClient.POST("/authorizations", body: ["scopes": ["repo_status", "user:email"]]) 

正文编码将由使用的 HTTP 头信息确定。要使用 json 编码您的正文,请向请求添加一个 "ContentType: application/json" 头信息

###请求执行结果

BothamNetworking 使用由 HTTPResponseBothamAPIClientError 实例组成的 Result 返回类型。我们添加了一个 ResultType 扩展,以便能够通过使用 SwiftyJSON 作为解析库来提供一个易于使用的机制来解析您的响应信息。

apiClient.GET("/repos") { result in
	result.mapJSON { json in
       for result in json["results"].arrayValue {
			let id = result["id"].stringValue
			let name = result["name"].stringValue
		}
    }
}

这是在 HTTPResponse 结构中可用的信息

public struct HTTPResponse {

    public let statusCode: Int
    public let headers: CaseInsensitiveDictionary<String>?
    public let body: NSData
    
    ...
    
}

BothamNetworking 可以返回的错误有

public enum BothamAPIClientError: ErrorType, Equatable {

    case HTTPResponseError(statusCode: Int, body: NSData)
    case NetworkError
    case HTTPClientError(error: NSError)
    case ParsingError(error: NSError)
    case UnsupportedURLScheme
    case Retry

}

###拦截器

BothamRequestInterceptorBothamResponseInterceptor 是两个协议,您可以用它们在发送之前修改 HTTPRequest 实例,或者在接收之前修改 HTTPResponse。这个机制可以用来实现认证策略,向请求中添加默认信息,添加日志跟踪或重试请求。一个例子可以是 NSLogInterceptorJSONHeadersRequestInterceptorBasicAuthentication

class JSONHeadersRequestInterceptor: BothamRequestInterceptor {

	func intercept(request: HTTPRequest) -> HTTPRequest {
        return request.appendingHeaders(["Content-Type": "application/json", "Accept": "application:json"])
    }
}
public protocol BasicAuthentication: BothamRequestInterceptor, BothamResponseInterceptor {
    var credentials: (username: String, password: String) { get }
    func onAuthenticationError(realm: String) -> Void
}

extension BasicAuthentication {
    public func intercept(request: HTTPRequest) -> HTTPRequest {

        let userPass = "\(credentials.username):\(credentials.password)"

        let userPassData = userPass.dataUsingEncoding(NSUTF8StringEncoding)!
        let base64UserPass = userPassData.base64EncodedStringWithOptions([])

        let header = ["Authorization" : "Basic \(base64UserPass)"]

        return request.appendingHeaders(header)
    }

    public func intercept(response: HTTPResponse,
        completion: (Result<HTTPResponse, BothamAPIClientError>) -> Void) {
        if response.statusCode == 401, let unauthorizedHeader = response.headers?["WWW-Authenticate"] {
            let regex = try! NSRegularExpression(pattern: "Basic realm=\"(.*)\"", options: [])
            let range = NSMakeRange(0, unauthorizedHeader.utf8.count)
            if let match = regex.firstMatchInString(unauthorizedHeader, options: [], range: range) {
                let realm = (unauthorizedHeader as NSString).substringWithRange(match.rangeAtIndex(1))
                onAuthenticationError(realm)
            }
        }
        completion(Result.Success(response))
    }
}

拦截器可以添加到 BothamAPIClient 实例,或者同时添加到所有的 BothamAPIClient 实例。添加到全局的拦截器将在每个请求之前和之后独立于 BothamAPIClient 实例进行评估。添加到本地的拦截器将仅应用于添加那些拦截器的 BothamAPIClient 实例。

let apiClient = BothamAPIClient(baseEndpoint: "https://api.github.com/repos/Karumi/")

//Add interceptors locally
apiClient.requestInterceptors.append(NSLogInterceptor())
apiClient.responseInterceptors.append(NSLogInterceptor())

//Add interceptors globally
BothamAPIClient.globalRequestInterceptors.append(NSLogInterceptor())
BothamAPIClient.globalResponseInterceptors.append(NSLogInterceptor())

###重试请求

为了能够重试请求,添加一个 BothamResponseInterceptor,并在需要时返回 BothamAPIClientError.RetryErrorBothamAPIClient 将自动重试您发送的原始请求。

class RetryInterceptor: BothamResponseInterceptor {

	func intercept(response: HTTPResponse, completion: (Result<HTTPResponse, BothamAPIClientError>) -> Void) {
            if response.statusCode == 401 {
                completion(Result.Failure(.RetryError))
            } else {
                completion(Result.Success(response))
            }
    }

}

使用此机制时要小心,因为它可以创建无限循环或导致 DDoS 攻击。请记住,您应该始终调用完成回调,以避免破坏 BothamResponseInterceptor 链。

许可协议

版权所有 2016 Karumi

此软件依据 Apache License 2.0(以下简称“协议”)许可;除非在协议许可范围内许可,否则不得使用本软件。您可以在以下地址获取协议副本:

https://apache.ac.cn/licenses/LICENSE-2.0

除非根据适用的法律或书面同意进行分发,否则在协议下分发的软件是基于“现状”和“按原始状态”的,并不提供任何明示或暗示的保证或条件。有关许可协议的权限和限制的具体语言,请参阅该许可。