我也是一个初学者,我不能说我所做的是最佳实践,但这是我使用 NSURLSession 和闭包处理 GET 请求的方式。
首先,我定义了一个 NetworkOperation 类,它将处理 NSURLSession。它具有以下属性:
lazy var config: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
lazy var session: NSURLSession = NSURLSession(configuration: self.config)
let queryURL: NSURL
在初始化程序中,我设置了 queryURL。配置和会话变量是lazy因为我希望它们仅在使用我的网络操作时才被初始化。
然后我有一个执行 GET 请求并检索 JSON 的方法。此方法接受一个闭包作为参数。这个闭包将由调用者提供,并允许我将我的 dataTask 响应捕获到调用上下文中。
func downloadJSONFromURl(completion: ([String:AnyObject]?) -> ()) {
let request = NSURLRequest(URL: queryURL)
let dataTask = session.dataTaskWithRequest(request) {
(let data: NSData?, let response: NSURLResponse?, let error: NSError?) -> Void in
// 1: Check HTTP Response for successful GET request
guard let httpResponse = response as? NSHTTPURLResponse, receivedData = data
else {
print("error: not a valid http response")
return
}
switch (httpResponse.statusCode) {
case 200:
// 2: Create JSON object with data
do {
let jsonDictionary = try NSJSONSerialization.JSONObjectWithData(receivedData, options: NSJSONReadingOptions.AllowFragments)
as? [String:AnyObject]
// 3: Pass the json back to the completion handler
completion(jsonDictionary)
} catch {
print("error parsing json data")
}
default:
print("GET request got response \(httpResponse.statusCode)")
}
}
dataTask.resume()
}
这个例子很简单,不处理错误,但是你可以看看我是如何将 JSON 解析成 [String:AnyObject] 成 try catch 块的。
之后,我将字典发送回名为 completion 的闭包,该闭包将对 JSON 执行必要的验证,然后将其转换为 Swift 对象。
在那个闭包中,我使用可选绑定来安全地构建我的对象。
例如,假设我正在检索一本书,JSON 看起来像这样:
{title: "Some book", author:"J. Doe"}
if let title = json["author"] as? String, author = json["author"] as? String {
let book = Book(title: title, author: author)
serviceCompletion(book)
}
因为我喜欢闭包,所以我将转换后的 JSON 发送到另一个提供给服务的闭包中。您可以在我的 github 上查看完整示例。它来自树屋教程。
我希望这会有所帮助。