Datsik
Datsik

Reputation: 14824

How can I load tableView data from JSON

Just trying to learn Swift, and I have this bit of code:

import UIKit

class ViewController: UIViewController, UITableViewDataSource {
    @IBOutlet weak var tableView: UITableView!
    var cellData: [String: Any] = [:]
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let request = URLRequest(url: URL(string: "https://reddit.com/r/globaloffensive/new/.json")!)
        let session = URLSession.shared

        session.dataTask(with: request) { data, response, err in
            do {
                if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any] {
                    self.cellData = json
                    DispatchQueue.main.async{
                        self.tableView.reloadData()
                    }
                }
            } catch {
                print("json error: \(error)")
            }
        }.resume()
    }

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

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        var cellData = self.cellData[indexPath.row] // Error Ambiguous reference to member subscript
        cell.textLabel?.text = "Here"

        return cell
    }


}

I'm just not sure how to load my JSON data from the JSON response.

Example json data:

{
  "kind": "Listing",
  "data": {
    "modhash": "",
    "children": [
      {
        "kind": "t3",
        "data": {
          "contest_mode": false,
          "banned_by": null,
          "domain": "self.GlobalOffensive",
          "subreddit": "GlobalOffensive",
          "selftext_html": "<!-- SC_OFF --><div class=\"md\"><p>I played a match the other night with two players that actively started faking defuses and blocking teammates in houses/corners on InferNEW. They also started throwing grenades at our feet to either mess us up or kill us via "suicide" (which is rich that something like that can happen). It was a comp match as well.</p>\n\n<p>What puzzles me is that we actively blocked comms and they got no reaction whatsoever out of us. This is the first time something like this has happened to me in a really long time, but they were ever persistent on jumping in front of us so we might accidentally kill them.</p>\n\n<p>What grinds my gears is once the pubbie got kicked (who was just trying to play a legitimate game) and my friend not so long after, I abandoned and had to eat a thirty minute cooldown. I was fine with taking the loss, but the fact that I just wanted to play the new Inferno map before I called it a night and had to take that cooldown pisses me off. What other bullshit like this am I overlooking? Why can't there be some sort of forgiveness for abandoning one match for isolated incidents like this? One really cheeky tactic was the griefers in question DC'ing to give the other team (who we were actually doing well against despite the situation) more cash and then just reconnecting.</p>\n\n<p>Idk, Im still mad about it. I guess I'm just blowing off some steam.</p>\n</div><!-- SC_ON -->",
          "selftext": "I played a match the other night with two players that actively started faking defuses and blocking teammates in houses/corners on InferNEW. They also started throwing grenades at our feet to either mess us up or kill us via \"suicide\" (which is rich that something like that can happen). It was a comp match as well.\n\nWhat puzzles me is that we actively blocked comms and they got no reaction whatsoever out of us. This is the first time something like this has happened to me in a really long time, but they were ever persistent on jumping in front of us so we might accidentally kill them.\n\nWhat grinds my gears is once the pubbie got kicked (who was just trying to play a legitimate game) and my friend not so long after, I abandoned and had to eat a thirty minute cooldown. I was fine with taking the loss, but the fact that I just wanted to play the new Inferno map before I called it a night and had to take that cooldown pisses me off. What other bullshit like this am I overlooking? Why can't there be some sort of forgiveness for abandoning one match for isolated incidents like this? One really cheeky tactic was the griefers in question DC'ing to give the other team (who we were actually doing well against despite the situation) more cash and then just reconnecting.\n\nIdk, Im still mad about it. I guess I'm just blowing off some steam.",
          "likes": null,
          "suggested_sort": null,
          "user_reports": [],
          "secure_media": null,
          "saved": false,
          "id": "57okbh",
          "gilded": 0,
          "secure_media_embed": {},
          "clicked": false,
          "report_reasons": null,
          "author": "dozIR",
          "media": null,
          "name": "t3_57okbh",
          "score": 1,
          "approved_by": null,
          "over_18": false,
          "removal_reason": null,
          "hidden": false,
          "thumbnail": "self",
          "subreddit_id": "t5_2sqho",
          "edited": false,
          "link_flair_css_class": null,
          "author_flair_css_class": "fan liquid",
          "downs": 0,
          "mod_reports": [],
          "archived": false,
          "media_embed": {},
          "is_self": true,
          "hide_score": true,
          "permalink": "/r/GlobalOffensive/comments/57okbh/is_griefing_still_a_thing/",
          "locked": false,
          "stickied": false,
          "created": 1476600416,
          "url": "https://www.reddit.com/r/GlobalOffensive/comments/57okbh/is_griefing_still_a_thing/",
          "author_flair_text": "Team Liquid Fan",
          "quarantine": false,
          "title": "Is griefing still a thing?",
          "created_utc": 1476571616,
          "link_flair_text": null,
          "distinguished": null,
          "num_comments": 0,
          "visited": false,
          "num_reports": null,
          "ups": 1
        }
      },
      {
        "kind": "t3",
        "data": {
          "contest_mode": false,
          "banned_by": null,
          "domain": "gfycat.com",
          "subreddit": "GlobalOffensive",
          "selftext_html": null,
          "selftext": "",
          "likes": null,
          "suggested_sort": null,
          "user_reports": [],
          "secure_media": {
            "oembed": {
              "provider_url": "http://gfycat.com",
              "description": "Watch 10 New Inferno Smokes For Terrorists GIF on Gfycat. Discover more inferno GIFs, smokes GIFs, tutorial GIFs on Gfycat.",
              "title": "10 New Inferno Smokes For Terrorists - Create, Discover and Share GIFs on Gfycat",
              "type": "video",
              "thumbnail_width": 445,
              "height": 338,
              "width": 600,
              "html": "<iframe class=\"embedly-embed\" src=\"https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgfycat.com%2Fifr%2FUnconsciousEminentIchthyostega&url=https%3A%2F%2Fgfycat.com%2FUnconsciousEminentIchthyostega&image=https%3A%2F%2Fthumbs.gfycat.com%2FUnconsciousEminentIchthyostega-size_restricted.gif&key=2aa3c4d5f3de4f5b9120b660ad850dc9&type=text%2Fhtml&schema=gfycat\" width=\"600\" height=\"338\" scrolling=\"no\" frameborder=\"0\" allowfullscreen></iframe>",
              "version": "1.0",
              "provider_name": "gfycat",
              "thumbnail_url": "https://i.embed.ly/1/image?url=https%3A%2F%2Fthumbs.gfycat.com%2FUnconsciousEminentIchthyostega-size_restricted.gif&key=b1e305db91cf4aa5a86b732cc9fffceb",
              "thumbnail_height": 250
            },
            "type": "gfycat.com"
          },
          "saved": false,
          "id": "57ojyq",
          "gilded": 0,
          "secure_media_embed": {
            "content": "<iframe class=\"embedly-embed\" src=\"https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgfycat.com%2Fifr%2FUnconsciousEminentIchthyostega&url=https%3A%2F%2Fgfycat.com%2FUnconsciousEminentIchthyostega&image=https%3A%2F%2Fthumbs.gfycat.com%2FUnconsciousEminentIchthyostega-size_restricted.gif&key=2aa3c4d5f3de4f5b9120b660ad850dc9&type=text%2Fhtml&schema=gfycat\" width=\"600\" height=\"338\" scrolling=\"no\" frameborder=\"0\" allowfullscreen></iframe>",
            "width": 600,
            "scrolling": false,
            "height": 338
          },
          "clicked": false,
          "report_reasons": null,
          "author": "H00D1N1",
          "media": {
            "oembed": {
              "provider_url": "http://gfycat.com",
              "description": "Watch 10 New Inferno Smokes For Terrorists GIF on Gfycat. Discover more inferno GIFs, smokes GIFs, tutorial GIFs on Gfycat.",
              "title": "10 New Inferno Smokes For Terrorists - Create, Discover and Share GIFs on Gfycat",
              "type": "video",
              "thumbnail_width": 445,
              "height": 338,
              "width": 600,
              "html": "<iframe class=\"embedly-embed\" src=\"//cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgfycat.com%2Fifr%2FUnconsciousEminentIchthyostega&url=https%3A%2F%2Fgfycat.com%2FUnconsciousEminentIchthyostega&image=https%3A%2F%2Fthumbs.gfycat.com%2FUnconsciousEminentIchthyostega-size_restricted.gif&key=2aa3c4d5f3de4f5b9120b660ad850dc9&type=text%2Fhtml&schema=gfycat\" width=\"600\" height=\"338\" scrolling=\"no\" frameborder=\"0\" allowfullscreen></iframe>",
              "version": "1.0",
              "provider_name": "gfycat",
              "thumbnail_url": "https://thumbs.gfycat.com/UnconsciousEminentIchthyostega-size_restricted.gif",
              "thumbnail_height": 250
            },
            "type": "gfycat.com"
          },
          "name": "t3_57ojyq",
          "score": 1,
          "approved_by": null,
          "over_18": false,
          "removal_reason": null,
          "hidden": false,
          "preview": {
            "images": [
              {
                "source": {
                  "url": "https://i.redditmedia.com/7BGZhitKhjTOlbyK079J09nfU7m6bV9Y5GRhNnpEBkU.jpg?s=4f3bd301d0faa9302cc3ae5950099c3a",
                  "width": 445,
                  "height": 250
                },
                "resolutions": [
                  {
                    "url": "https://i.redditmedia.com/7BGZhitKhjTOlbyK079J09nfU7m6bV9Y5GRhNnpEBkU.jpg?fit=crop&crop=faces%2Centropy&arh=2&w=108&s=b15551a87884493e4d317e874cef84da",
                    "width": 108,
                    "height": 60
                  },
                  {
                    "url": "https://i.redditmedia.com/7BGZhitKhjTOlbyK079J09nfU7m6bV9Y5GRhNnpEBkU.jpg?fit=crop&crop=faces%2Centropy&arh=2&w=216&s=c13b18af23c9838bb3f381cece3ec93f",
                    "width": 216,
                    "height": 121
                  },
                  {
                    "url": "https://i.redditmedia.com/7BGZhitKhjTOlbyK079J09nfU7m6bV9Y5GRhNnpEBkU.jpg?fit=crop&crop=faces%2Centropy&arh=2&w=320&s=aa08f13f175103697febf1498ad29ebe",
                    "width": 320,
                    "height": 179
                  }
                ],
                "variants": {},
                "id": "IwONta3AQfFDGDmO6eGpbgsq0QABfwi1YhKi63X34gg"
              }
            ]
          },
          "thumbnail": "http://b.thumbs.redditmedia.com/Ft-9rqYiKbpaXEPEa9VlxF5cHenHWWz48cRcTYlZJCk.jpg",
          "subreddit_id": "t5_2sqho",
          "edited": false,
          "link_flair_css_class": null,
          "author_flair_css_class": "fan navi",
          "downs": 0,
          "mod_reports": [],
          "archived": false,
          "media_embed": {
            "content": "<iframe class=\"embedly-embed\" src=\"//cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgfycat.com%2Fifr%2FUnconsciousEminentIchthyostega&url=https%3A%2F%2Fgfycat.com%2FUnconsciousEminentIchthyostega&image=https%3A%2F%2Fthumbs.gfycat.com%2FUnconsciousEminentIchthyostega-size_restricted.gif&key=2aa3c4d5f3de4f5b9120b660ad850dc9&type=text%2Fhtml&schema=gfycat\" width=\"600\" height=\"338\" scrolling=\"no\" frameborder=\"0\" allowfullscreen></iframe>",
            "width": 600,
            "scrolling": false,
            "height": 338
          },
          "post_hint": "rich:video",
          "is_self": false,
          "hide_score": true,
          "permalink": "/r/GlobalOffensive/comments/57ojyq/infernew_arch_smoke/",
          "locked": false,
          "stickied": false,
          "created": 1476600302,
          "url": "https://gfycat.com/UnconsciousEminentIchthyostega",
          "author_flair_text": "Natus Vincere Fan",
          "quarantine": false,
          "title": "Infernew Arch Smoke",
          "created_utc": 1476571502,
          "link_flair_text": null,
          "distinguished": null,
          "num_comments": 1,
          "visited": false,
          "num_reports": null,
          "ups": 1
        }
      },
      {
        "kind": "t3",
        "data": {
          "contest_mode": false,
          "banned_by": null,
          "domain": "self.GlobalOffensive",
          "subreddit": "GlobalOffensive",
          "selftext_html": "<!-- SC_OFF --><div class=\"md\"><p>If you have a teammate that is bad or made a mistake in the match and your first thing to do is insult them. Then you seem to be the problem. The best response in every mistake is "nice try" not "Are you throwing?, Why are you so bad". </p>\n\n<p>Maybe you shouldn't be an asshole if you want someone to play better. You're not helping him or her. You're just making it worst for the player trying to do well but you just made him feel like shit.\nI can not stand these people. Including those that think it's a good idea to go on your profile or in any way make fun of you for your speech impediment and just hurt the person more. You're just making it worst and you're making yourself look like a bully in front of 9 other people. Instead of telling someone how bad they are. Just tell them what they should of done so they can learn more.\nI bet this has been posted before but this needs another read for many people</p>\n\n<p>TL;DR: You're giving the player a bad experience in csgo. How will people try their best if you just insult them for their current skill. You're not helping.</p>\n</div><!-- SC_ON -->",
          "selftext": "If you have a teammate that is bad or made a mistake in the match and your first thing to do is insult them. Then you seem to be the problem. The best response in every mistake is \"nice try\" not \"Are you throwing?, Why are you so bad\". \n\nMaybe you shouldn't be an asshole if you want someone to play better. You're not helping him or her. You're just making it worst for the player trying to do well but you just made him feel like shit.\nI can not stand these people. Including those that think it's a good idea to go on your profile or in any way make fun of you for your speech impediment and just hurt the person more. You're just making it worst and you're making yourself look like a bully in front of 9 other people. Instead of telling someone how bad they are. Just tell them what they should of done so they can learn more.\nI bet this has been posted before but this needs another read for many people\n\nTL;DR: You're giving the player a bad experience in csgo. How will people try their best if you just insult them for their current skill. You're not helping.",
          "likes": null,
          "suggested_sort": null,
          "user_reports": [],
          "secure_media": null,
          "saved": false,
          "id": "57ojqy",
          "gilded": 0,
          "secure_media_embed": {},
          "clicked": false,
          "report_reasons": null,
          "author": "Mikalton",
          "media": null,
          "name": "t3_57ojqy",
          "score": 1,
          "approved_by": null,
          "over_18": false,
          "removal_reason": null,
          "hidden": false,
          "thumbnail": "self",
          "subreddit_id": "t5_2sqho",
          "edited": false,
          "link_flair_css_class": null,
          "author_flair_css_class": "fan liquid",
          "downs": 0,
          "mod_reports": [],
          "archived": false,
          "media_embed": {},
          "is_self": true,
          "hide_score": true,
          "permalink": "/r/GlobalOffensive/comments/57ojqy/message_to_the_toxic_of_cs_competitive/",
          "locked": false,
          "stickied": false,
          "created": 1476600223,
          "url": "https://www.reddit.com/r/GlobalOffensive/comments/57ojqy/message_to_the_toxic_of_cs_competitive/",
          "author_flair_text": "Team Liquid Fan",
          "quarantine": false,
          "title": "Message to the toxic of cs competitive",
          "created_utc": 1476571423,
          "link_flair_text": null,
          "distinguished": null,
          "num_comments": 1,
          "visited": false,
          "num_reports": null,
          "ups": 1
        }
      },
      {
        "kind": "t3",
        "data": {
          "contest_mode": false,
          "banned_by": null,
          "domain": "youtube.com",
          "subreddit": "GlobalOffensive",
          "selftext_html": null,
          "selftext": "",
          "likes": null,
          "suggested_sort": null,
          "user_reports": [],
          "secure_media": {
            "type": "youtube.com",
            "oembed": {
              "provider_url": "https://www.youtube.com/",
              "title": "Pro Player Unbanned! My Drake Moon Offer, Korean CS Changes, Renegades Choice, SK Forfeits, ESL Pro",
              "type": "video",
              "html": "<iframe width=\"600\" height=\"338\" src=\"https://www.youtube.com/embed/ck8JpaxJqIE?feature=oembed\" frameborder=\"0\" allowfullscreen></iframe>",
              "author_name": "CSGO News",
              "height": 338,
              "width": 600,
              "version": "1.0",
              "thumbnail_width": 480,
              "provider_name": "YouTube",
              "thumbnail_url": "https://i.ytimg.com/vi/ck8JpaxJqIE/hqdefault.jpg",
              "thumbnail_height": 360,
              "author_url": "https://www.youtube.com/user/legitrsgiving"
            }
          },
          "saved": false,
          "id": "57namw",
          "gilded": 0,
          "secure_media_embed": {
            "content": "<iframe width=\"600\" height=\"338\" src=\"https://www.youtube.com/embed/ck8JpaxJqIE?feature=oembed\" frameborder=\"0\" allowfullscreen></iframe>",
            "width": 600,
            "scrolling": false,
            "height": 338
          },
          "clicked": false,
          "report_reasons": null,
          "author": "WhipedCream",
          "media": {
            "type": "youtube.com",
            "oembed": {
              "provider_url": "https://www.youtube.com/",
              "title": "Pro Player Unbanned! My Drake Moon Offer, Korean CS Changes, Renegades Choice, SK Forfeits, ESL Pro",
              "type": "video",
              "html": "<iframe width=\"600\" height=\"338\" src=\"https://www.youtube.com/embed/ck8JpaxJqIE?feature=oembed\" frameborder=\"0\" allowfullscreen></iframe>",
              "author_name": "CSGO News",
              "height": 338,
              "width": 600,
              "version": "1.0",
              "thumbnail_width": 480,
              "provider_name": "YouTube",
              "thumbnail_url": "https://i.ytimg.com/vi/ck8JpaxJqIE/hqdefault.jpg",
              "thumbnail_height": 360,
              "author_url": "https://www.youtube.com/user/legitrsgiving"
            }
          },
          "name": "t3_57namw",
          "score": 0,
          "approved_by": null,
          "over_18": false,
          "removal_reason": null,
          "hidden": false,
          "preview": {
            "images": [
              {
                "source": {
                  "url": "https://i.redditmedia.com/3C3e67st7c0R3hcoCD2YGSPUnkRSN6O1HXezE6TVkXo.jpg?s=ee70eb0c9470baa538f3cc24b8e04431",
                  "width": 480,
                  "height": 360
                },
                "resolutions": [
                  {
                    "url": "https://i.redditmedia.com/3C3e67st7c0R3hcoCD2YGSPUnkRSN6O1HXezE6TVkXo.jpg?fit=crop&crop=faces%2Centropy&arh=2&w=108&s=964c9c93123ab26bab00b45ab45e48f0",
                    "width": 108,
                    "height": 81
                  },
                  {
                    "url": "https://i.redditmedia.com/3C3e67st7c0R3hcoCD2YGSPUnkRSN6O1HXezE6TVkXo.jpg?fit=crop&crop=faces%2Centropy&arh=2&w=216&s=8a4593ab27bc56139bde8af41a53c6f4",
                    "width": 216,
                    "height": 162
                  },
                  {
                    "url": "https://i.redditmedia.com/3C3e67st7c0R3hcoCD2YGSPUnkRSN6O1HXezE6TVkXo.jpg?fit=crop&crop=faces%2Centropy&arh=2&w=320&s=04ea04d99e933d3317a60516a234046e",
                    "width": 320,
                    "height": 240
                  }
                ],
                "variants": {},
                "id": "TEe3XKE_fwyEHR7w-VBKSAn3kw7CcKg8bqDNKcdzCdk"
              }
            ]
          },
          "thumbnail": "http://b.thumbs.redditmedia.com/QxCMRqdykPrG3bQofDlLvtRsqZBl0fHs3JwuWr4PnGs.jpg",
          "subreddit_id": "t5_2sqho",
          "edited": false,
          "link_flair_css_class": null,
          "author_flair_css_class": "pin mirage",
          "downs": 0,
          "mod_reports": [],
          "archived": false,
          "media_embed": {
            "content": "<iframe width=\"600\" height=\"338\" src=\"https://www.youtube.com/embed/ck8JpaxJqIE?feature=oembed\" frameborder=\"0\" allowfullscreen></iframe>",
            "width": 600,
            "scrolling": false,
            "height": 338
          },
          "post_hint": "rich:video",
          "is_self": false,
          "hide_score": false,
          "permalink": "/r/GlobalOffensive/comments/57namw/csgo_news_pro_player_unbanned_my_drake_moon_offer/",
          "locked": false,
          "stickied": false,
          "created": 1476583922,
          "url": "https://www.youtube.com/watch?v=ck8JpaxJqIE",
          "author_flair_text": "Mirage Veteran",
          "quarantine": false,
          "title": "CSGO News - Pro Player Unbanned! My Drake Moon Offer, Korean CS Changes, Renegades Choice, SK Forfeits, ESL Pro",
          "created_utc": 1476555122,
          "link_flair_text": null,
          "distinguished": null,
          "num_comments": 0,
          "visited": false,
          "num_reports": null,
          "ups": 0
        }
      },
      {
        "kind": "t3",
        "data": {
          "contest_mode": false,
          "banned_by": null,
          "domain": "self.GlobalOffensive",
          "subreddit": "GlobalOffensive",
          "selftext_html": "<!-- SC_OFF --><div class=\"md\"><p>Hi everyone, first time posting here. \nI was wondering if this is an ongoing issue due to the recent updates.\nI searched for a while online unable to find anything helpful. About a day ago, I tried to look up the float value of one of my items, and so I copied the inspect in game link to csgoAnalyst. Anyway, later I tried to view community market items in the game and found out I couldn't. I was able to view them not 30 minutes before so I believe it had something to do with CSGO Analyst but I have no idea why that would cause an issue. I've restarted steam with no luck and ran the exe as admin. Anyone else have experience with this problem?</p>\n</div><!-- SC_ON -->",
          "selftext": "Hi everyone, first time posting here. \nI was wondering if this is an ongoing issue due to the recent updates.\nI searched for a while online unable to find anything helpful. About a day ago, I tried to look up the float value of one of my items, and so I copied the inspect in game link to csgoAnalyst. Anyway, later I tried to view community market items in the game and found out I couldn't. I was able to view them not 30 minutes before so I believe it had something to do with CSGO Analyst but I have no idea why that would cause an issue. I've restarted steam with no luck and ran the exe as admin. Anyone else have experience with this problem?",
          "likes": null,
          "suggested_sort": null,
          "user_reports": [],
          "secure_media": null,
          "saved": false,
          "id": "57o42j",
          "gilded": 0,
          "secure_media_embed": {},
          "clicked": false,
          "report_reasons": null,
          "author": "ChefPepperonni",
          "media": null,
          "name": "t3_57o42j",
          "score": 2,
          "approved_by": null,
          "over_18": false,
          "removal_reason": null,
          "hidden": false,
          "thumbnail": "self",
          "subreddit_id": "t5_2sqho",
          "edited": false,
          "link_flair_css_class": "help",
          "author_flair_css_class": null,
          "downs": 0,
          "mod_reports": [],
          "archived": false,
          "media_embed": {},
          "is_self": true,
          "hide_score": true,
          "permalink": "/r/GlobalOffensive/comments/57o42j/unable_to_inspect_items_from_community_market/",
          "locked": false,
          "stickied": false,
          "created": 1476594415,
          "url": "https://www.reddit.com/r/GlobalOffensive/comments/57o42j/unable_to_inspect_items_from_community_market/",
          "author_flair_text": null,
          "quarantine": false,
          "title": "Unable to Inspect Items from Community Market",
          "created_utc": 1476565615,
          "link_flair_text": "Help",
          "distinguished": null,
          "num_comments": 2,
          "visited": false,
          "num_reports": null,
          "ups": 2
        }
      },

Upvotes: 0

Views: 149

Answers (2)

David Seek
David Seek

Reputation: 17132

I have decided to create a Struct to fill models for each of your desired NSDictionaries. To ease the Code and for you to understand, what is going on, I only took the "title" that got delivered in the JSON for every child.

I've put detailed explanation of what's going on into the code.

import UIKit

// here we are creating a struct with the var title and we're instantiating it
struct Reddit {
    var title: String = ""
}

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    // here we create an array of Reddit and we're instantiating it
    var reddits: [Reddit] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        // here we call our func that will load the content and reload the tableView
        loadData()

    }
}

//MARK: Download Content
extension ViewController {

    func loadData() {
        let request = URLRequest(url: URL(string: "https://reddit.com/r/globaloffensive/new/.json")!)
        let session = URLSession.shared

        session.dataTask(with: request) { data, response, err in

            do {
                if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary {

                    // here we take the json object and filter for the value of data
                    let dataChild = json.value(forKeyPath: "data") as! NSDictionary

                    // here we loop through the dictionary to get a single element for every elements in the dict
                    for element in dataChild.value(forKeyPath: "children") as! [NSDictionary] {

                        // here we get the value for data and then the value for title and create a title object
                        let title = (element.value(forKeyPath: "data") as! NSDictionary).value(forKeyPath: "title")

                        // here we store the title as String into our Reddit model and create an instance of it
                        let r = Reddit(title: title as! String)

                        // here we store every single model into our Reddit array
                        self.reddits.append(r)
                    }

                    DispatchQueue.main.async{
                        self.tableView.reloadData()
                    }
                }
            } catch {
                print("json error: \(error)")
            }
            }.resume()
    }
}

//MARK: TableView
extension ViewController: UITableViewDelegate, UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        // here we set the number of rows equals the number of reddits.count
        return reddits.count
    }

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

        // here we take one model out of our array per indexPath.row
        let reddit = reddits[indexPath.row]

        // here we set the reddit.title as titleLabel.text
        cell.titleLabel.text = reddit.title
        return cell
    }
}

//done

Result:

enter image description here

To your question in the comments: You need to create a subclass of UITableViewCell for the cell, that you have created as part of your UITableView. And link the cell as well as the UILabel.

import UIKit

class Cell: UITableViewCell {

    @IBOutlet weak var titleLabel: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }

}

You need to set the subclass of Cell as the class of your UITableViewCell in the attribute inspector of the Interface Builder.

enter image description here

And set the reuseIdentifier.

enter image description here

And then you need to set an outlet of the Label you have created inside that Cell at the Interface Builder.

Upvotes: 1

Pak Ho Cheung
Pak Ho Cheung

Reputation: 1426

json result is not a array of data. It is a dictionary of data. You have to convert the data from dictionary to an array first. Then reload the table view.

The way to get data from dictionary:

if let kind = json.value(forKey: "kind") as? String {
    // kind should be "Listing"
}

Upvotes: 1

Related Questions