我试图从JSON文件加载数据以在我的tableview中使用。然而,当我在viewdidload中调用此函数时,我想要填充数据,不包含任何数据,并返回一个空数组。
class CompanyModel {
func getJSON() -> NSMutableArray() {
let companyArray: NSMutableArray = NSMutableArray()
let requestURL: NSURL = NSURL(string: "http://localhost/Companies/JSON.php")!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(urlRequest) { <- does not enter bracket?
(data, response, error) -> Void in
let httpResponse = response as! NSHTTPURLResponse
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
print("Everyone is fine, file downloaded successfully.")
do{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)
if let companies = json["companies"] as? [[String: AnyObject]] {
for company in companies {
if let name = company["name"] as? String,
let phoneNumber = company["phone_number"] as? String,
let website = company["website"] as? String,
let email = company["email"] as? String,
let address = company["address"] as? String
{
let company = CompanyModel()
company.name = name
company.phoneNumber = phoneNumber
company.website = website
company.email = email
company.address = address
}
companyArray.addObject(company)
print(companyArray)
}
}
} catch {
print("Error with Json: \(error)")
}
}
print(companyArray) <- array is populated
}
print(companyArray) <- array is empty
task.resume()
return companyArray
}
}
当我运行调试会话时,它似乎没有进入我上面所述的括号。相反,它直接跳转到返回函数,然后返回一个空数组。我相信没有从JSON文件中获取数据,但我不太清楚为什么。
答案 0 :(得分:0)
您的第二个print(companyArray)
代码在调用可以返回来自服务器的数据之前运行,因为请求是作为后台任务完成的。您应该在成功代码中写return companyArray
,否则return
在发生故障时清空数组。
答案 1 :(得分:0)
在您的代码中,您创建了一个在不同线程上运行的数据任务。
print(companyArray) <- this one is after request returns a response
}
print(companyArray) <- this comes before the array is populated
task.resume() <- And here is where you start the data task
return companyArray
您可以在完成方法时更改逻辑以返回companyArray。
print(companyArray) <- and for the love of God, don't put return here!
}
print(companyArray) <- this comes before the array is populated
task.resume() <- And here is where you start the data task
return companyArray
答案 2 :(得分:0)
在您的代码localhost
中创建了一个问题,您将response
作为nil
。因此,在检查任何内容之前,最好print(data)
,print(response)
,print(error)
。要检查使用此网址:https://httpbin.org/get
以及稍后的网址,请将您的localhost
替换为您的网址中的IP
或domain
。
以下是上述更新代码:
func getWebServiceWithURL(strUrl: String, completionHandler: (NSDictionary?, NSError?) -> ()) -> (){
let getTask = NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: strUrl)!) { (responseData, _, error) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
do{
if responseData != nil{
let json = try NSJSONSerialization.JSONObjectWithData(responseData!, options: NSJSONReadingOptions.AllowFragments) as? NSDictionary
if let parseJSON = json {
// Parsed JSON
completionHandler(parseJSON, nil)
}
else {
// Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
let jsonStr = NSString(data: responseData!, encoding: NSUTF8StringEncoding)
#if DEBUG
print("Error could not parse JSON: \(jsonStr)")
#endif
}
}else{
completionHandler(nil, error)
}
}catch let error as NSError{
print(error.localizedDescription)
completionHandler(nil, error)
}
})
}
getTask.resume()
}
答案 3 :(得分:0)
doc of NSURLSession的一部分:
与大多数网络API一样,NSURLSession API非常高 的异步即可。它以两种方式之一将数据返回到您的应用程序, 取决于您调用的方法:
To a completion handler block that is called when a transfer finishes successfully or with an error. By calling methods on the session’s delegate as data is received and when the transfer is complete.
和代码中的一部分:
print(companyArray) <- array is populated
}
print(companyArray) <- array is empty
异步过程完成后,您的完成处理程序中会填充companyArray
,并且在完成处理程序之外它是空的,因为代码:
print(companyArray) <- array is empty
紧接着这一行:
let task = session.dataTaskWithRequest(urlRequest) {
并且尚未评估完成处理程序。使用完成处理程序来获得实际结果。
答案 4 :(得分:0)
您的return companyArray
在响应来自服务器之前被调用。所以你不应该像数组那样创建一个返回类型的方法!您应该将companyArray
作为公共变量或实例变量,并且可以从webservice调用的完成块设置它的值,并且可以在需要的地方使用。
希望这会有所帮助:)