JSONparsingswift,数组在NSURLSession之外没有任何值
我想在swift中调用一个json webservice,使用下面的代码,并在swift IOS中的tableview
中显示它。
/*declared as global*/ var IdDEc = [String]() // string array declared globally //inside viewdidload let url = NSURL(string: "http://192.1.2.3/PhpProject1/getFullJson.php") let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in let json1 = NSString(data: data!, encoding: NSUTF8StringEncoding) print("json string is = ",json1) // i am getting response here let data = json1!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) do { let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as! NSArray for arrayData in json { let notId = arrayData["ID"] as! String self.IdDEc.append(notId) } print(" id = ",IdDEc) //here i am getting values } catch let error as NSError { print("Failed to load: \(error.localizedDescription)") } print(" id out count = ",self.IdDEc.count) //here also } print(" id out count = ",self.IdDEc.count) // not here task.resume()
我把数组Iddec声明为全局的,但是这个数组的范围只存在于NSURLSession中,
另外我想用这个数组填充tableview。 这里是示例json输出文件
[ {"ID":"123" , "USER":"philip","AGE":"23"}, {"ID":"344","USER":"taylor","AGE":"29"}, {"ID":"5464","USER":"baker","AGE":"45"}, {"ID":"456","USER":"Catherine","AGE":"34"} ]
我很快就请你帮忙
这个想法是使用“callback”。
在这里,我已经为你想要得到的NSArray做了一个:
completion: (dataArray: NSArray)->()
我们创build一个函数来获取数组,我们将这个callback添加到函数的签名中:
func getDataArray(urlString: String, completion: (dataArray: NSArray)->())
只要数组准备就绪,我们将使用callback:
completion(dataArray: theNSArray)
以下是完整function的外观:
func getDataArray(urlString: String, completion: (dataArray: NSArray)->()) { if let url = NSURL(string: urlString) { NSURLSession.sharedSession().dataTaskWithURL(url) {(data, response, error) in if error == nil { if let data = data, json1 = NSString(data: data, encoding: NSUTF8StringEncoding), data1 = json1.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) { do { let json = try NSJSONSerialization.JSONObjectWithData(data1, options: []) if let jsonArray = json as? NSArray { completion(dataArray: jsonArray) } } catch let error as NSError { print(error.localizedDescription) } } else { print("Error: no data") } } else { print(error!.localizedDescription) } }.resume() } }
现在我们使用这个函数,不再有asynchronous问题:
getDataArray("http://192.1.2.3/PhpProject1/getFullJson.php") { (dataArray) in for dataDictionary in dataArray { if let notId = dataDictionary["ID"] as? String { self.IdDEc.append(notId) } } print("id out count = ", self.IdDEc.count) }
Swift 3更新+修复和改进。
func getContent(from url: String, completion: @escaping ([[String: Any]])->()) { if let url = URL(string: url) { URLSession.shared.dataTask(with: url) { (data, response, error) in if error == nil { if let data = data { do { let json = try JSONSerialization.jsonObject(with: data, options: []) if let content = json as? [[String: Any]] { // array of dictionaries completion(content) } } catch { // error while decoding JSON print(error.localizedDescription) } } else { print("Error: no data") } } else { // network-related error print(error!.localizedDescription) } }.resume() } } getContent(from: "http://192.1.2.3/PhpProject1/getFullJson.php") { (result) in // 'result' is what was given to 'completion', an array of dictionaries for dataDictionary in result { if let notId = dataDictionary["ID"] as? String { // ... } } }