jsonswiftuidecoder

JSON decoding struct has a key, but Xcode calls that there is no member with that key in SwiftUI


I would like to get the text value of the repo name from GitHub. The structs are decoded successfully, but I can't seem to get one value that is important to me (name).

Can someone help, please?

Swift files with code:

DECODER

class NetworkingManager: ObservableObject{
    @Published var repos = [Repository]()
    
    init() {
        loadData()
    }
    
    func loadData() {
        guard let url = URL(string: "https://api.github.com/users/jacobtoye/repos") else { return }
        URLSession.shared.dataTask(with: url) {(data, _, _) in
            guard let data = data else { return }
            DispatchQueue.main.async {
                do {
                    self.repos = try JSONDecoder().decode([Repository].self, from: data)
                } catch {
                    fatalError("Failed to decode given URL")
                }
            }
        }.resume()
    }
}

APIKEYS

import Foundation

struct Repository: Decodable, Identifiable {
    let id: Int
    let name: String
    let owner: Owner
    
    enum CodingKeys: String, CodingKey {
        case id, owner
        case name
    }
}

struct Owner : Decodable, Identifiable {
    let id: Int
    let reposUrl : String

    enum CodingKeys: String, CodingKey, CaseIterable {
        case id
        case reposUrl = "repos_url"
    }
}

CONTENT VIEW

import SwiftUI

struct ContentView: View {
    @StateObject var netManager = NetworkingManager()
    
    var body: some View {
        Text("\(netManager.repos.name)")
        }
    }

The error I get is: value of type [Repository] has no member 'name'.

In the final project I want to use this value as a navigationTitle, so ForEach solution from here: SwiftUI value of type [x] has no member [y], but the struct has the member doesn't seem to be viable for me.


Solution

  • netManager.repos is an array of Repository, it does not have a name, as the error tells you. You must select a single repo and get the name from that.

    For example

    Text("\(netManager.repos.first?.name ?? "no name")")