Swift 2 异步执行后的回调
Swift 2 Callback after async execution
我正在尝试从 Swift 2
中的服务获取 JSON
https://someapidomain.com/entries.json
[
1212,
1234,
2934,
....
]
https://someapidomain.com/entry/entry_id.json
{
"key1": "value1",
"key2": 23,
"key3": "value3,
...
}
Service must return:
[
{
"key1": "value1",
"key2": 23,
"key3": "value3,
...
},
{
"key1": "value1",
"key2": 23,
"key3": "value3,
...
},
....
]
struct ExampleService {
private static let baseURL = "https://someapidomain.com/"
private static let entries_per_page = 10
private static func getJSONResponse(url: String, callback: (AnyObject) -> () ){
let request = NSMutableURLRequest(URL: NSURL(string: url)!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = session.dataTaskWithRequest(request, completionHandler: {
data, response, err -> Void in
do {
let jsonResponse = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
callback(jsonResponse)
}catch {
print("Error processing json")
}
})
task.resume()
}
static func getEntries(url: String, callback: ([[String: AnyObject]]) -> ()) {
var entries: [[String:AnyObject]] = []
let apiURL = baseURL + url
getJSONResponse(apiUrl) { (response) in
if let entryIds = response as? Array<Int> {
for entryId in storyIds[0..<entries_per_page] {
let entryURL = baseURL + "/entry/\(entryId).json"
getJSONResponse(entryURL) { (response) in
if let entry = response as? [String: AnyObject] {
print(entry)
entries.append(entry)
}
}
}
callback(entries)
}
}
}
}
}
现在当我调用服务时我得到空数组
ExampleService.getEntries("/entries.json") { (response) in
print(response) // prints []
}
而循环内的各个条目打印 json。我认为这是因为在 for 循环执行完成之前调用了回调。
我该如何解决这个问题?
创建、进入和离开的示例如下
let jsonGroup = dispatch_group_create()
for x in json{
dispatch_group_enter(getDeparturesGroup)
// Some code...
}
dispatch_group_wait(jsonGroup, DISPATCH_TIME_FOREVER)
修改后的函数 getEntries
概述了如何使用 dispatch_group 完成此操作。
此外,您必须确保您的函数 getJSONResponse
始终调用完成处理程序,即使它失败了。这是因为,您必须确保函数调用 dispatch_enter
和 dispatch_leave
是平衡的。
从这个意义上说,我也建议修改 getEntries
函数,即即使在失败时也始终调用完成处理程序。相应地修改完成处理程序的签名。
static func getEntries(url: String, callback: ([[String: AnyObject]]) -> ()) {
var entries: [[String:AnyObject]] = []
getJSONResponse(url) { (response) in
let queue = dispatch_queue_create("myqueue", nil)
let group = dispatch_group_create()
if let entryIds = response as? Array<Int> {
for entryId in entryIds {
dispatch_group_enter(group)
let entryURL = baseURL + "/entry/\(entryId).json"
getJSONResponse(entryURL) { (response) in
if let entry = response as? [String: AnyObject] {
print(entry)
entries.append(entry)
}
dispatch_group_leave(group)
}
}
}
dispatch_group_notify(group, queue) {
callback(entries)
}
}
}
我正在尝试从 Swift 2
中的服务获取 JSONhttps://someapidomain.com/entries.json
[
1212,
1234,
2934,
....
]
https://someapidomain.com/entry/entry_id.json
{
"key1": "value1",
"key2": 23,
"key3": "value3,
...
}
Service must return:
[
{
"key1": "value1",
"key2": 23,
"key3": "value3,
...
},
{
"key1": "value1",
"key2": 23,
"key3": "value3,
...
},
....
]
struct ExampleService {
private static let baseURL = "https://someapidomain.com/"
private static let entries_per_page = 10
private static func getJSONResponse(url: String, callback: (AnyObject) -> () ){
let request = NSMutableURLRequest(URL: NSURL(string: url)!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = session.dataTaskWithRequest(request, completionHandler: {
data, response, err -> Void in
do {
let jsonResponse = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
callback(jsonResponse)
}catch {
print("Error processing json")
}
})
task.resume()
}
static func getEntries(url: String, callback: ([[String: AnyObject]]) -> ()) {
var entries: [[String:AnyObject]] = []
let apiURL = baseURL + url
getJSONResponse(apiUrl) { (response) in
if let entryIds = response as? Array<Int> {
for entryId in storyIds[0..<entries_per_page] {
let entryURL = baseURL + "/entry/\(entryId).json"
getJSONResponse(entryURL) { (response) in
if let entry = response as? [String: AnyObject] {
print(entry)
entries.append(entry)
}
}
}
callback(entries)
}
}
}
}
}
现在当我调用服务时我得到空数组
ExampleService.getEntries("/entries.json") { (response) in
print(response) // prints []
}
而循环内的各个条目打印 json。我认为这是因为在 for 循环执行完成之前调用了回调。
我该如何解决这个问题?
创建、进入和离开的示例如下
let jsonGroup = dispatch_group_create()
for x in json{
dispatch_group_enter(getDeparturesGroup)
// Some code...
}
dispatch_group_wait(jsonGroup, DISPATCH_TIME_FOREVER)
修改后的函数 getEntries
概述了如何使用 dispatch_group 完成此操作。
此外,您必须确保您的函数 getJSONResponse
始终调用完成处理程序,即使它失败了。这是因为,您必须确保函数调用 dispatch_enter
和 dispatch_leave
是平衡的。
从这个意义上说,我也建议修改 getEntries
函数,即即使在失败时也始终调用完成处理程序。相应地修改完成处理程序的签名。
static func getEntries(url: String, callback: ([[String: AnyObject]]) -> ()) {
var entries: [[String:AnyObject]] = []
getJSONResponse(url) { (response) in
let queue = dispatch_queue_create("myqueue", nil)
let group = dispatch_group_create()
if let entryIds = response as? Array<Int> {
for entryId in entryIds {
dispatch_group_enter(group)
let entryURL = baseURL + "/entry/\(entryId).json"
getJSONResponse(entryURL) { (response) in
if let entry = response as? [String: AnyObject] {
print(entry)
entries.append(entry)
}
dispatch_group_leave(group)
}
}
}
dispatch_group_notify(group, queue) {
callback(entries)
}
}
}