问题
So I'm fetching data from a url which is in a json format. I'm trying to display the data in my tableview but, even though it feels simple, I can't figure out how to do it.
class CompanyModel {
func getJSON() {
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) {
(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()
}
}
I know i've done it before....I'm guessing in viewDidLoad()
I'd call CompanyModel().getJSON()
which would fetch the data, then store it in an empty array but my mind feels blank on how to do it.
I can't declare a variable of NSarray and store the data of it the variable directly for me to then populate the tableview. Nevertheless, I hope this explains what I'm trying to acheive.
回答1:
Well first change the function to return your company array :
func getJSON() -> NSMutableArray {
}
By the end of the for loop return the company array
for company in companies {
}
After your array is populated, return the array inside this block:
dispatch_async(dispatch_get_main_queue(), {
return companyArray
})
And after task.resume()
return the array:
return companyArray
From anywhere you wanna call this class and get the array :
Get a reference of the class
Let companyModal = CompanyModel()
And in anywhere you have your table view and the class let's say in viewDidLoad
, you should first have NSMutableArray
.
var arraySource = NSMutableArray()
And in viewDidLoad
:
arraySource = companyModal.getJSON()
And to show the data in tableView do :
Mytableview.reloadData()
回答2:
You can't use return
within the closure of an asynchronous network request, you have to use a callback instead.
You need a NSMutableArray from the request, so first, let's make a callback for this:
completion: (array: NSMutableArray)->()
We add this callback to the method signature:
func getJSON(completion: (array: NSMutableArray)->())
And then at the location where the array will be available, we place this completion handler:
class CompanyModel {
func getJSON(completion: (array: 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) {
(data, response, error) -> Void in
let httpResponse = response as! NSHTTPURLResponse
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
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)
}
}
// CALLBACK HERE
completion(array: companyArray)
}
} catch {
print("Error with Json: \(error)")
}
}
}
task.resume()
}
}
Now to get the array from the network we use a trailing closure like this:
getJSON { (array) in
print(array)
}
来源:https://stackoverflow.com/questions/37445069/how-to-populate-my-tableview-with-a-mutablearray-from-json