NSURLSession.sharedSession().dataTaskWithRequest runs slow in function - ios

My problem arises when I want to populate data from my mysql database into a class object. I am trying to return an array of objects and it returns nil and then it fills itself somehow. How can I make it fill before returning the blank array?
Here is my code and a screenshot of code output
import Foundation
class Research
{
var mainResearchImageURL:String = ""
var userProfileImageURL:String = ""
var caption:String = ""
var shortDescription:String = ""
init(mainResearchImageURL :String, userProfileImageURL:String, caption:String, shortDescription:String)
{
self.mainResearchImageURL = mainResearchImageURL
self.userProfileImageURL = userProfileImageURL
self.caption = caption
self.shortDescription = shortDescription
}
class func downloadAllResearches()->[Research]
{
var researches = [Research]()
let urlString = "http://localhost/test/index.php"
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
request.HTTPMethod = "POST"
let postString = "action=listresearches"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {data, response, error in
if (error == nil) {
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSArray
//let dictionary = json!.firstObject as? NSDictionary
var counter:Int = 0;
for line in json!{
let researchData = line as! NSDictionary
let researchLineFromData = Research(mainResearchImageURL: researchData["research_mainImageURL"] as! String, userProfileImageURL: researchData["research_creatorProfileImageURL"] as! String, caption: researchData["research_caption"] as! String, shortDescription: researchData["research_shortDescription"] as! String)
researches.append(researchLineFromData) //researches bir dizi ve elemanları Research türünde bir sınıftan oluşuyor.
counter += 1
print ("counter value \(counter)")
print("array count in loop is = \(researches.count)")
}
}catch let error as NSError{
print(error)
}
} else {
print(error)
}})
task.resume()
print("array count in return is = \(researches.count)")
return researches
}
}
And this is the output:

add this on you completionHandler ( it works if you update a view)
dispatch_async(dispatch_get_main_queue(), {
if (error == nil) { ...... }
})
Advice 1:
return the task and use a completion param in your method,
you can cancel the task if it's too slow.
Advice 2 :
Use alamofire and swiftyJson framework

What happen here is that you are returning the value before finish (remember that the call is Asynchronous), you can make something like this:
class func downloadAllResearches(success:([Research])->Void,failure:(String)->Void)
{
var researches = [Research]()
let urlString = "http://localhost/test/index.php"
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
request.HTTPMethod = "POST"
let postString = "action=listresearches"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {data, response, error in
if (error == nil) {
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSArray
//let dictionary = json!.firstObject as? NSDictionary
var counter:Int = 0;
for line in json!{
let researchData = line as! NSDictionary
let researchLineFromData = Research(mainResearchImageURL: researchData["research_mainImageURL"] as! String, userProfileImageURL: researchData["research_creatorProfileImageURL"] as! String, caption: researchData["research_caption"] as! String, shortDescription: researchData["research_shortDescription"] as! String)
researches.append(researchLineFromData) //researches bir dizi ve elemanları Research türünde bir sınıftan oluşuyor.
counter += 1
print ("counter value \(counter)")
print("array count in loop is = \(researches.count)")
}
success(researches)
}catch let error as NSError{
print(error)
failure("Can be extract from NSERROR")
}
} else {
print(error)
failure("Error - Can be extract for NSERROR")
}})
task.resume()
}
And for call this Fuction use something like this:
Research.downloadAllResearches({ (objects:[Research]) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
//Do whatever you like with the content
})
}) { (failureLiteral:String) -> Void in
}

Related

Duplicate array items getting appended in Response (Swift)

I am using two APIs, one for fetching the Cars added by the user and the second to (Adding new car) submit the car details into my backend. When I open the View of the car details, all 11 Car details are getting fetched properly.
But when I submit the car details (Add New Car) by clicking the add rounded button and the fetch the details of the added car it shows 22 car added in the frontend Table View but now in the backend of the API.
Here are some screenshots.
Before adding a new car
After adding a new car
Here is the code for the same.
Below function is getting used in Viewdidload to fetch the details:
func responsedatavehicle(){
let emailid = defaults.string(forKey: "email")
var request = URLRequest(url: URL(string: "http://www.example.com/getMyVehicleInfo?email=\(emailid!)")!)
print("Email in resposfunction \(emailid!)")
request.httpMethod = "GET"
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
do{
// let postString = "?mobile="+ph!
print("mobno is inside getdata \(emailid!)")
// //print(postString)
// request.httpBody = postString.data(using: .utf8)
APESuperHUD.show(style: .loadingIndicator(type: .standard), title: nil, message: "Loading...")
//self.activityIndicator("Please Wait")
}catch let error{
//print(error.localizedDescription)
return
}
// self.activityIndicator("Please Wait")
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil
{
return
}
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
do{
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json{
print(parseJSON)
if let mobile = parseJSON["error"] as! Int? {
let msg = parseJSON["message"] as! String?
if (mobile == 0){
//print(userId)
DispatchQueue.main.async {
// self.showGlobalAlertwithMessage(msg as! NSString)
if let heroeArray = json!.value(forKey: "content") as? Array<[String:Any]> {
//looping through all the elements
self.labelArray.append(contentsOf: heroeArray)
}
APESuperHUD.dismissAll(animated: true)
// self.effectView.removeFromSuperview()
//print(self.labelArray.count)
for i in 0..<self.labelArray.count{
if let heroeDict = self.labelArray[i] as? NSDictionary{
// let stationname = heroeDict.value(forKey: "charging_station") as! String
let brandname = heroeDict.value(forKey: "brand_name") as! String
let modelname = heroeDict.value(forKey: "car_name") as! String
let accharger = heroeDict.value(forKey: "ac_charger") as! String
let dccharger = heroeDict.value(forKey: "dc_charger") as! String
let vehiclenumber = heroeDict.value(forKey: "vehicle_registration_number") as! String
let imageurl = heroeDict.value(forKey: "vehicle_photo") as! String
self.brandnamearray.append(brandname)
self.modelnamearray.append(modelname)
self.acchargerarray.append(accharger)
self.dcchargerarray.append(dccharger)
self.imageurlarray.append(imageurl)
self.vehiclenoarray.append(vehiclenumber)
print(self.imageurlarray)
}
}
self.myTableView.reloadWithAnimation()
}
}else {
DispatchQueue.main.async {
//self.showGlobalAlertwithMessage(msg as! NSString)
DispatchQueue.main.async {
APESuperHUD.dismissAll(animated: true)
// self.effectView.removeFromSuperview()
}
}
}
}
} else{
print("ERROR IN ALERT")
}
}
catch{
// self.showGlobalAlertwithMessage("Could not successfully perform this request. Please try again later")
}
}
task.resume()
}
Cellforrowat Function
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyVehicleTableViewCell
cell.brandnamecell.text = brandnamearray[indexPath.row]
cell.modelnamecell.text = modelnamearray[indexPath.row]
cell.acchargercell.text = acchargerarray[indexPath.row]
cell.dcchargercell.text = dcchargerarray[indexPath.row]
cell.vehiclenumbercell.text = vehiclenoarray[indexPath.row]
cell.ImageView.sd_setImage(with: URL(string: imageurlarray[indexPath.row]), placeholderImage: UIImage(named: "placeholder.png"))
cell.aclabel.layer.borderColor = UIColor.darkGray.cgColor
cell.aclabel.layer.borderWidth = 1.0
cell.aclabel.layer.cornerRadius = 5
cell.aclabel.layer.masksToBounds = true
cell.dclabel.layer.borderColor = UIColor.darkGray.cgColor
cell.dclabel.layer.cornerRadius = 5
cell.dclabel.layer.masksToBounds = true
cell.dclabel.layer.borderWidth = 1.0
cell.aclabel.layer.shadowColor = UIColor.lightGray.cgColor
cell.aclabel.layer.shadowOpacity = 0.5
cell.aclabel.layer.shadowRadius = 10.0
cell.aclabel.layer.shadowOffset = .zero
cell.aclabel.layer.shadowPath = UIBezierPath(rect: cell.aclabel.bounds).cgPath
cell.aclabel.layer.shouldRasterize = true
cell.dclabel.layer.shadowColor = UIColor.lightGray.cgColor
cell.dclabel.layer.shadowOpacity = 0.5
cell.dclabel.layer.shadowRadius = 10.0
cell.dclabel.layer.shadowOffset = .zero
cell.dclabel.layer.shadowPath = UIBezierPath(rect: cell.dclabel.bounds).cgPath
cell.dclabel.layer.shouldRasterize = true
cell.backview.layer.borderColor = UIColor(red:0.92, green:0.92, blue:0.98, alpha:0.9).cgColor
cell.backview.layer.cornerRadius = 8
cell.backview.layer.masksToBounds = true
cell.backview.layer.borderWidth = 8.0
cell.shadowmodel.layer.cornerRadius = 13.0
cell.shadowmodel.layer.shadowColor = UIColor.lightGray.cgColor
cell.shadowmodel.layer.shadowOpacity = 0.5
cell.shadowmodel.layer.shadowRadius = 10.0
cell.shadowmodel.layer.shadowOffset = .zero
cell.shadowmodel.layer.shadowPath = UIBezierPath(rect: cell.shadowmodel.bounds).cgPath
cell.shadowmodel.layer.shouldRasterize = true
return cell
}
Below function is getting used to add a new car:
func submitcar(){
if vehiclenumberstring == ""{
SCLAlertView().showError("Error", subTitle: "Please enter vehicle number ") // Error
}
else {
let emailsubmit = defaults.string(forKey: "email")
print("email inside submit car is \(emailsubmit!)")
var request = URLRequest(url: URL(string: "http://www.example.com/apimobileapps/addVehicleInfo")!)
request.httpMethod = "POST"
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
do{
let postString = "brand_name="+brandname+"&car_name="+modelname+"&vehicle_registration_number="+vehiclenumberstring+"&email="+emailsubmit!
print(postString)
request.httpBody = postString.data(using: .utf8)
APESuperHUD.show(style: .loadingIndicator(type: .standard), title: nil, message: "Loading...")
// self.activityIndicator("Please Wait")
}catch let error{
//print(error.localizedDescription)
return
}
let task = URLSession.shared.dataTask(with: request){
(data, response, error) in
if (error != nil){
return
}
do{
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json{
//print(parseJSON)
if let userId = parseJSON["error"] as! Int? {
let msg = parseJSON["message"] as! String?
if (userId == 0){
//print(userId)
DispatchQueue.main.async {
// self.showGlobalAlertwithMessage(msg as! NSString)
DispatchQueue.main.async {
APESuperHUD.dismissAll(animated: true); self.effectView.removeFromSuperview()
}
}
}else {
DispatchQueue.main.async {
// self.showGlobalAlertwithMessage(msg as! NSString)
DispatchQueue.main.async {
APESuperHUD.dismissAll(animated: true)
// self.effectView.removeFromSuperview();
}
}
}
}
} else{
DispatchQueue.main.async {
APESuperHUD.dismissAll(animated: true)
// self.effectView.removeFromSuperview();
}
}
}catch{
DispatchQueue.main.async {
APESuperHUD.dismissAll(animated: true)
// self.effectView.removeFromSuperview();
}
//print(error)
}
}
task.resume()
}
responsedatavehicle()
}
My Array count is showing duplicate values in the table view on submit button action.

JSON Parsing Swift using JSONPlaceholder

I'm playing with Swift and JSONPlaceholder. I want to retrieve all the data contained in: https://jsonplaceholder.typicode.com/photos
I created a function that is acceding to the url, downloading the JSON but then I don't know how can I obtain the title and the thumbnailUrl to pass then for populate the tableView. In the past I used this code but now it's not working because on the JSONPlaceholder there are no array.
Any help for re-arrange the code for read and obtain the jsonplaceholder elements?
func loadList(){
let url = URL(string: urlReceived)
var myNews = NewInfo()
let task = URLSession.shared.dataTask(with: url!) {
(data, response, error) in
if error != nil{
print("ERROR")
}
else{
do {
if let content = data{
let myJson = try JSONSerialization.jsonObject(with: content, options: .mutableContainers)
//print(myJson)
if let jsonData = myJson as? [String : Any] {
if let myResults = jsonData["list"] as? [[String : Any]]{
//dump(myResults)
for value in myResults{
//Read time string from root
if let time = value ["dt_txt"] as? String{
myNews.time = time
}
//Read main container
if let main = value["main"]
as? [String : Any]{
if let temperature = main["temp"] as? Double {
myNews.temperature = String(temperature)
}
}
//Read from weather container
if let weather = value["weather"] as? [[String: Any]]{
for value in weather{
if let weatherContent = value["description"] as? String{
myNews.weatherDescription = weatherContent
}
}
}
self.myTableViewDataSource.append(myNews)
}
dump(self.myTableViewDataSource)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
}
catch{
}
}
}
task.resume()
}//End func
Okey, so with Alamofire + SwiftyJSON, you can do this:
func loadList(){
let url = "https://jsonplaceholder.typicode.com/photos"
AF.request(url).responseJSON { (response) in
switch response.result {
case .success(let value):
let json = JSON(value)
print(json)
for value in json.arrayValue {
let url = value.dictionaryValue["url"]!.stringValue
let albumId = value.dictionaryValue["albumId"]!.stringValue
let thumbnailUrl = value.dictionaryValue["thumbnailUrl"]!.stringValue
let id = value.dictionaryValue["id"]!.stringValue
let title = value.dictionaryValue["title"]!.stringValue
// Add this album to array.
let album = AlbumModel(id: id, albumId: albumId, title: title, thumbnailUrl: thumbnailUrl)
albums.append(album)
}
case .failure(let error):
print(error)
}
}
}
EDIT:
I made model for values
class AlbumModel {
var id: String?
var albumId: String?
var title: String?
var thumbnailUrl: String?
init(id: String?, albumId: String?, title: String?, thumbnailUrl: String?){
self.id = id
self.albumId = albumId
self.title = title
self.thumbnailUrl = thumbnailUrl
}
}
After that, just create an array like var albums = [AlbumModel]() and you can append all the albums to this. Easy to use after in tableViewcell (example: albums[indexPath.row].id)

How can I do an HTTP Post before reading the JSON?

I am reading JSON from a URL and that has been working correctly. This is my code:
#IBOutlet weak var ProfilesCell: UITableView!
let cellspacing: CGFloat = 50
var names = [String]()
var posts = [String]()
var locations = [String]()
var votes = [String]()
var comments = [String]()
override func viewDidLoad() {
super.viewDidLoad()
ProfilesCell.dataSource = self
let url:URL = URL(string: "http://"+Connection_String+":8000/profile_view")!
URLSession.shared.dataTask(with:url, completionHandler: {(data, response, error) in
if error != nil {
print(error)
} else {
do {
let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:Any]
if let Profile = parsedData["Profile"] as! [AnyObject]?
{
for Stream in Profile {
if let fullname = Stream["fullname"] as? String {
self.names.append(fullname)
}
if let post = Stream["post"] as? String {
self.posts.append(post)
}
if let location = Stream["location"] as? String {
self.locations.append(location)
}
if let vote = Stream["votes"] as? String {
self.votes.append(vote.appending(" Votes"))
}
if let comment = Stream["comments"] as? String {
self.comments.append(comment.appending(" Comments"))
}
DispatchQueue.main.async {
self.ProfilesCell.reloadData()
}
}
}
} catch let error as NSError {
print(error)
}
}
}).resume()
}
That code above correctly parses the JSON and the data is returned to the TableView. I now want to do an HTTP Post before reading that JSON and the parameter name is profile_id and I know that is something wrong in my code because if I do an HTML form with the parameter, things work correctly.
This is the new code that I now have:
#IBOutlet weak var ProfilesCell: UITableView!
let cellspacing: CGFloat = 50
var names = [String]()
var posts = [String]()
var locations = [String]()
var votes = [String]()
var comments = [String]()
override func viewDidLoad() {
super.viewDidLoad()
ProfilesCell.dataSource = self
let url:URL = URL(string: "http://"+Connection_String+":8000/profile_view")!
let ss = "32"
var request = URLRequest(url:url)
let paramString = "profile_id=\(ss)"
request.httpMethod = "POST"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
request.httpBody = paramString.data(using: .utf8)
URLSession.shared.dataTask(with:url, completionHandler: {(data, response, error) in
if error != nil {
print(error)
} else {
do {
let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:Any]
if let Profile = parsedData["Profile"] as! [AnyObject]?
{
for Stream in Profile {
if let fullname = Stream["fullname"] as? String {
self.names.append(fullname)
}
if let post = Stream["post"] as? String {
self.posts.append(post)
}
if let location = Stream["location"] as? String {
self.locations.append(location)
}
if let vote = Stream["votes"] as? String {
self.votes.append(vote.appending(" Votes"))
}
if let comment = Stream["comments"] as? String {
self.comments.append(comment.appending(" Comments"))
}
DispatchQueue.main.async {
self.ProfilesCell.reloadData()
}
}
}
} catch let error as NSError {
print(error)
}
}
}).resume()
}
Now with this extra code the URL is still being hit but profile_id is showing null even though I have hardcoded the number 32. I also get this message displayed:
Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}

Exception thrown if no data are received

I am using following Class to receive data from an external database:
import Foundation
protocol HomeModelProtocal: class {
func itemsDownloaded(items: NSArray)
}
class HomeModel: NSObject, NSURLSessionDataDelegate {
//properties
weak var delegate: HomeModelProtocal!
var data : NSMutableData = NSMutableData()
var mi_movil: String = ""
let misDatos:NSUserDefaults = NSUserDefaults.standardUserDefaults()
var urlPath: String = "http:...hidden here.."
let parametros = "?id="
func downloadItems() {
mi_movil = misDatos.stringForKey("ID_IPHONE")!
print ("mi_movil en HOMEMODEL:",mi_movil)
urlPath = urlPath + parametros + mi_movil
let url: NSURL = NSURL(string: urlPath)!
var session: NSURLSession!
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
print ("LA URL ES: ",url)
session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
let task = session.dataTaskWithURL(url)
task.resume()
}
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
self.data.appendData(data);
}
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
if error != nil {
print("Failed to download data")
}else {
print("Data downloaded")
self.parseJSON()
}
}
func parseJSON() {
var jsonResult: NSMutableArray = NSMutableArray()
do{
jsonResult = try NSJSONSerialization.JSONObjectWithData(self.data, options:NSJSONReadingOptions.AllowFragments) as! NSMutableArray
} catch let error as NSError {
print(error)
}
var jsonElement: NSDictionary = NSDictionary()
let locations: NSMutableArray = NSMutableArray()
for(var i = 0; i < jsonResult.count; i++)
{
jsonElement = jsonResult[i] as! NSDictionary
print (jsonElement)
let location = MiAutoModel()
//the following insures none of the JsonElement values are nil through optional binding
if let id_mis_autos = jsonElement["id_mis_autos"] as? String,
let modelo = jsonElement["modelo"] as? String,
let ano = jsonElement["ano"] as? String,
let id_movil = jsonElement["id_movil"] as? String
{
location.id_mis_autos = id_mis_autos
location.modelo = modelo
location.ano = ano
location.id_movil = id_movil
}
locations.addObject(location)
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.delegate.itemsDownloaded(locations)
})
}
}
If there are received data, it works fine but if there are no data an exception is thrown:
Could not cast value of type '__NSArray0' (0x1a0dd2978) to 'NSMutableArray' (0x1a0dd3490)
What should I change to detect if there are no data to avoid the exception?
Since you don't seem to be modifying jsonResult anywhere, the obvious choice is to make it an NSArray instead of an NSMutableArray, and change the downcasting to match that.
I'm not sure why you're using NSDictionary and NSMutableArray but this is how I would do it:
for result in jsonResult {
guard let jsonElement = result as? [String:AnyObject] else { return }
let locations: [MiAutoModel] = []
let location = MiAutoModel()
//the following insures none of the JsonElement values are nil through optional binding
let id_mis_autos = jsonElement["id_mis_autos"] as? String ?? ""
let modelo = jsonElement["modelo"] as? String ?? ""
let ano = jsonElement["ano"] as? String ?? ""
let id_movil = jsonElement["id_movil"] as? String ?? ""
location.id_mis_autos = id_mis_autos
location.modelo = modelo
location.ano = ano
location.id_movil = id_movil
locations.append(location)
}
You might have to change some of the code depending on your situation.

How to populate my tableview with a mutablearray from json

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.
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()
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)
}

Resources