UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

json decoding from project 7, someone help me understand why Paul uses two different structs?

Forums > 100 Days of Swift

This is the first struct, it's a a custom swift file(Petition)


import Foundation
struct Petition: Codable{
    var title: String
    var body: String
    var signatureCount: Int
}

and this is the second one(Petitions)

import Foundation
struct Petitions: Codable{
    var results: [Petition]
}

and this is the whole code

import UIKit

class ViewController: UITableViewController {
    var petitions = [Petition]()

    override func viewDidLoad() {
        super.viewDidLoad()
        let urlString = "https://www.hackingwithswift.com/samples/petitions-1.json"
        if let url = URL(string: urlString){
            if let data = try? Data(contentsOf: url){
                parse(json: data)
            }
        }
    }

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

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = "Title Goes Here"
        cell.detailTextLabel?.text = "Subtitle Goes Here"
        return cell
    }

    func parse(json: Data) {
        let decoder = JSONDecoder()

        if let jsonPetitions = try? decoder.decode(Petitions.self, from: json) {
            petitions = jsonPetitions.results
            tableView.reloadData()
        }
    }

}

I am having hard time understanding when the Petition file is actually used in the code? it seems the parse(json: Data) function is decoding into the Petitions file, rather than the Petition file. Also, the petitions property at the top of the class is being created as an instance of the Petitions file. So why is the Petition file there? and when is it used in the code?

3      

Petition is used right here:

var petitions = [Petition]()

petitions is an array of Petition items decoded from the JSON.

And it's also used here:

petitions = jsonPetitions.results

This takes the results property of the Petitions struct (which is an array of Petition items) and assigns it to the petitions property of the ViewController.

And it looks like you may not have gotten that far yet, but Petition will be used when you populate the UITableView cells using its properties.

4      

@roosterboy, thanks for clarifying. However, when we passed the variable data into the parse(json: Data) function, aren't we decoding our files inside Petition struct? if so, wouldn't that mean the Petition struct gets the files first, it then passes it onto the Petitions struct? If so, the Petition array is never used directly in the code, but the Petition struct is.
by the way, I was talking about the Petitions struct, not petitions(the array at the top of the class).

I don't see how the Petitions struct is playing any role in this code.

3      

@Geeljira petitions the forum for clarification:

it seems the parse(json: Data) function is decoding into the Petitions file, rather than the Petition file.

@rooster has the right answer. But to further clarify @twoStraw's intentions.

A Petition is the definition of one petition, all by itself.

The Petitions struct is a collection of zero or many Petition objects. It's defined as an array of Petition objects.

You're correct. The parse JSON function is decoding into a Petitions file object. But there may be many, many objects returned after parsing the JSON. Each of those objects is defined by the one Petition struct.

Example:

petitions = [ petition1, petition2, petition3, petition4 ] <- A collection of Petition objects.

pets = [dog1, dog2, dog3, cat1, hampster1, cat2] <- A collection of Pet objects.


Keep coding!

3      

Some math here, say we are doing some linear algebra and we have to find values of x, y and given 2 equations

9x + 3y = 6

2x - 7y = 9

Now we sove it, if we multiply eqiation one by 2 and equation 2 by 9 we get

18x + 6y = 12

18x - 63y = 81

Now we subtract

18x + 6y = 12

18x -63y = 81

we get

69y = -69

y =  -1

now we substitute y in to equation one

9x + 3y = 6

we get

9x -3 = 6

x = 1

In short coding is like maths, we can do substitution and make changes as per our requirements , you and i will come across many situations where such substitutions are made , just understand its for our own understanding and if you can find another way to solve it , most welcome, just do not over think , every thing is maths based in coding , feel free to do as you wish do not feel constrained in your approach to solve,

paul and other author make changes to make code easier to solve as per their way , you can have your way to solve as well

3      

Thought I might try a way. If You look at the json that Paul uses (Think it was taken from a web site)

{ //<- This show that you have a single element (struct Petitions)
  // some other data
  "results":[ //<- this will show that you now have array
      { //<- This show you have a single element (struct Petition) 
          "id": "......" // a Int inside the array (not used but usefully in SwiftUI)
          // other element not used
          "title": "....." // a String inside the array
          "body": "....."  // a String inside the array
          // more data not used
      },
       { //<- Repeat above
          "id": "......" 
          // other element not used
          "title": "....."
          "body": "....."
          // more data not used
      },
       { // <- etc
          "id": "......" 
          // other element not used
          "title": "....." 
          "body": "....."
          // more data not used
      }
    ] //<- end of array
} //<- end of struct Petitions

So to get the array from "results" you have to have a Petitions struct that hold an array of Petition

You could also show as a nested struct!

struct Petitions: Codable {

    var results: [Petition]

    struct Petition: Codable {
        var title: String
        var body: String
        var signatureCount: Int
    }
}

3      

Thank you @Obelix and @NigelGee. I am currently working on the milestone that covers projects 13-15, and Paul recommends we use a mix of project1 and project7 to accomplish that. I get the big picture, but this little detail was throwing me off. I'll continue to read your responses again and again until I get it. I created you a json file and I will be loading it from disc. Idk how I'll show all three properties since there's only textLabel and detailTexlabel in the prototype cell, but I'll cross that bridge once I get there.

here's my json file.

{
    "Facts About Countries": {
        "USA": [{
            "population": 33433855,
            "Capital": "Washington DC",
            "GDP": "23.32 T"
        }],

        "UK": [{
            "population": 67000000,
            "Capital": "London",
            "GDP": "3.2 T"
        }],

        "Egypt": [{
            "population": 109000000,
            "Capital": "Cairo",
            "GDP": "404 B"

        }],

        "India": [{
                "population": 1415125754,
                "Capital": "New Delhi",
                "GDP": "3.2 T"
            }

        ]

    }
}

I appreciate you guys for your help.

3      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.