Swift 3.0使用URLSession写一个网络请求类

2017-01-11 16:04:48来源:http://www.jianshu.com/p/0d937de9f752作者:KK先森人点击

第七城市

一个hearder,一个httpBody,加上dataTask方法就能搞定,和几个处理请求参数的函数,下面上代码


类方法写的请求方法,参数,闭包


 static func request(method: String, url: String, params: Dictionary<String, AnyObject> = Dictionary<String, AnyObject>(), callback: @escaping (_ data: NSData?, _ response: URLResponse?, _ error: NSError?) -> Void) {
let session = URLSession.shared
var newURL = url
if method == "GET" {
newURL += "?" + Network().buildParams(params)
}
let request = NSMutableURLRequest(url: NSURL(string: newURL)! as URL)
request.httpMethod = method

if method == "POST" {
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpBody = Network().buildParams(params).data(using: String.Encoding.utf8)
}

let task = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
callback(data as NSData?, response , error as NSError?)
})
task.resume()
}

处理参数的方法:


    //请求体,并处理特殊字符串 !$&'()*+,;= :#[]@
private func buildParams(_ parameters: [String: Any]) -> String {
var components: [(String, String)] = []
for key in parameters.keys.sorted(by: <) {
let value = parameters[key]!
components += queryComponents(fromKey: key, value: value)
}
return components.map { "/($0)=/($1)" }.joined(separator: "&")
}
public func queryComponents(fromKey key: String, value: Any) -> [(String, String)] {
var components: [(String, String)] = []
if let dictionary = value as? [String: Any] {
for (nestedKey, value) in dictionary {
components += queryComponents(fromKey: "/(key)[/(nestedKey)]", value: value)
}
} else if let array = value as? [Any] {
for value in array {
components += queryComponents(fromKey: "/(key)[]", value: value)
}
} else if let value = value as? NSNumber {
if value.isBool {
components.append((escape(key), escape((value.boolValue ? "1" : "0"))))
} else {
components.append((escape(key), escape("/(value)")))
}
} else if let bool = value as? Bool {
components.append((escape(key), escape((bool ? "1" : "0"))))
} else {
components.append((escape(key), escape("/(value)")))
}
return components
}

public func escape(_ string: String) -> String {
let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
let subDelimitersToEncode = "!$&'()*+,;="
var allowedCharacterSet = CharacterSet.urlQueryAllowed
allowedCharacterSet.remove(charactersIn: "/(generalDelimitersToEncode)/(subDelimitersToEncode)")
return string.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? string
}

外面加一个NSNumber的扩展


extension NSNumber {
fileprivate var isBool: Bool { return CFBooleanGetTypeID() == CFGetTypeID(self) }
}



第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台