rob rob - 1 month ago 27
Swift Question

Nothing showing in app from JSON url with Swift 3 and Alamofire

I have an app that is using Swift 3 and Alamofire. The data is connected to two

cell?.viewWithTag(2)
and
cell?.viewWithTag(1)
which is an image (from url) and text. So when I run the project nothing is showing in my App. I have tested the JSON with
print(readableJSON)
and the JSON is getting printed into the console. So I am a little confused really. My swift looks like this:

SWIFT

import UIKit
import Alamofire

struct postinput {
let mainImage : UIImage!
let name : String!

}


class TableViewController: UITableViewController {

var postsinput = [postinput]()

var mainURL = "https://www.example.api.com"

typealias JSONstandard = [String : AnyObject]

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
callAlamo(url: mainURL)
}

func callAlamo(url : String){
Alamofire.request(url).responseJSON(completionHandler: {
response in

self.parseData(JSONData: response.data!)


})

}

func parseData(JSONData : Data) {
do {
var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONstandard
print(readableJSON)

if let posts = readableJSON["posts"] as? [JSONstandard] {
for post in posts {
let title = post["title"] as! String
print(title)

if let imageUrl = post["image"] as? JSONstandard {
let mainImageURL = URL(string: imageUrl["url"] as! String)
let mainImageData = NSData(contentsOf: mainImageURL!)


let mainImage = UIImage(data: mainImageData as! Data)
postsinput.append(postinput.init(mainImage: mainImage, name: title))
self.tableView.reloadData()

}


}

}

}


catch {
print(error)
}


}




override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postsinput.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")

// cell?.textLabel?.text = titles[indexPath.row]

let mainImageView = cell?.viewWithTag(2) as! UIImageView

mainImageView.image = postsinput[indexPath.row].mainImage

let mainLabel = cell?.viewWithTag(1) as! UILabel

mainLabel.text = postsinput[indexPath.row].name


return cell!
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}


}


JSON

{
"posts" : [{
"id": "000000",
"url": "/content/interview2",
"date": "2016-11-03 09:01:41",
"modified": "2016-11-03 09:03:47",
"title": "An interview",
"image": "https://www.example.com/sites/default/files/oregood.jpeg",
"summary": {
"value": "<p>Latin text here</p>",
"format": "filtered_html"
}
}]
}

Answer

From your JSON response image key contains String not Dictionary also you need to reload your tableView outside for loop not every time inside the loop, so try like this.

if let posts = readableJSON["posts"] as? [JSONstandard] {
    for post in posts {
        let title = post["title"] as! String            
        if let imageUrl = post["image"] as? String {
            let mainImageURL = URL(string: imageUrl as! String)
            let mainImageData = NSData(contentsOf: mainImageURL!)
            let mainImage = UIImage(data: mainImageData as! Data)
            postsinput.append(postinput.init(mainImage: mainImage, name: title))                
        }
    }
    DispatchQueue.main.async {
        self.tableView.reloadData()
    }
}

Suggestion : Instead of downloading image using NSData(contentsOf:) on main thread batter to use library like SDWebImages or you can create your own async image downloader.