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

Stuck on challenge Day 60 (making a class codable)

Forums > 100 Days of SwiftUI

This is what i have:

class Users: ObservableObject, Codable {
    @Published var users =  [User]()

}

struct User: Codable, Identifiable {
    var name: String
    var id: String
    var age: Int
    var company: String
    var about: String
    var friends: [Friend]
}

struct Friend: Codable {
    var id: String
    var name: String
}

How do i make the class Users codable? I lost track of all the ways with init, requered init and so on.

My first version was to leave away the class Users and use an array [User] to make the app work. But now I want to show the friends on the details view and pass a class to that view. I tried to pass [User] as an observedObject but that did not work (as expected) as it would have been an array of classes [Class]. (Of course i changed the User struct to a class for that.)

This is the rest of my current code:

struct ContentView: View {

    //Local demo data for designing
    @State var listOfUsers: [User] = Bundle.main.decode("friendface.json")
    //@State private var users = [User]()

    var body: some View {
        NavigationView {
            VStack {
                List(listOfUsers) { user in
                    NavigationLink(destination: DetailView(user: user)) {
                        VStack(alignment: .leading) {
                            Text(user.name)
                            HStack {
                                Text("Age: \(user.age)")
                                    .font(.subheadline)
                                Spacer()
                                Text("\(user.friends.count) Friends")
                                    .font(.subheadline)
                            }
                        }
                    }

                }
            }
            .navigationTitle("Friends")
            .onAppear(perform: loadData)
        }

    }

    func loadData() {
        guard let url = URL(string: "https://www.hackingwithswift.com/samples/friendface.json") else {
            fatalError("Invalid URL")
        }
        let request = URLRequest(url: url)
        URLSession.shared.dataTask(with: request) { data, response, error in
            if let data = data {
                guard let loaded = try? JSONDecoder().decode([User].self, from: data) else {
                    print("Failed to decode from bundle")
                    return
                }
                DispatchQueue.main.async {
                    self.listOfUsers = loaded
                }
            }
        }.resume()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct DetailView: View {
    let user: User
    var body: some View {
        VStack {
            Text(user.company)
            Text("Age: \(user.age)")

        }
        .navigationBarTitle(user.name)
    }
}

3      

Hi @JEK587

You are doing well (better then I was when I did it!). Just a few pointer

You do not need this as you are not passing it around the whole app so keep it simple. So you can delete it

class Users: ObservableObject, Codable {
    @Published var users =  [User]()

}

Next you better of putting struct Friend: Codable inside struct User: Codable, Identifiable this keeps it so cant be called without the User struct eg

struct User: Codable, Identifiable {
    struct Friend: Codable {
        var id: String
        var name: String
    }

    var name: String
    var id: String
    var age: Int
    var company: String
    var about: String
    var friends: [Friend]
}

lastly

Do you have a file called friendface.json in the project(Bundle)? If not then this will not work and deleted, however the commented code is correct @State private var listOfUsers = [User]()

3      

Thank you for your help, yes i added a .json to the project to see how it looks like without running it.

3      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

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.