I’m a noob and I’m puzzled about my downside. My understanding may be restricted, I appeared up some similiar questions and I discover completely different issues, like my lacking init (I’ve no clue how init works).
So! I attempt to use an exterior API through JSON. You may discover it right here (https://www.abgeordnetenwatch.de/api/v2/politicians). My Code was working fantastic, until i needed so as to add an inner construction “occasion” (in my code “partei”), subsequent to my working “Politician” construction. After analysis, I believed I have to construct the code construction like in my code. I used completely different names for id and label, to make it work through codingkeys.
I expertise these bugs at the moment
“58:28 Generic parameter ‘T’ couldn’t be inferred
->In name to operate ‘decode(_:from:)’ (Basis.JSONDecoder)58:43 Can not convert worth of sort ‘module’ to anticipated argument sort ‘T.Sort’
108:88 Lacking argument for parameter ‘partei’ in name
->’init(politician:partei:)’ declared right here
My plan was so as to add one other Textual content from the interior construction Partei to my PoliticanDetailView
Record(viewModel.parteien, id: .parteiID) { partei in
Textual content("Partei: (partei.namePartei)")
My complete messy code, I’m sorry if it may be not etiquette conform
import SwiftUI
struct Partei: Decodable {
let parteiID: Int
let namePartei: String
non-public enum CodingKeys: String, CodingKey {
case parteiID = "id"
case namePartei = "label"
}
}
struct Politician: Decodable {
let id: Int
let firstName: String
let lastName: String
let birthYear: Int?
let beruf: String?
let geschlecht: String?
let partei: Partei
enum CodingKeys: String, CodingKey {
case id
case firstName = "first_name"
case lastName = "last_name"
case birthYear = "year_of_birth"
case beruf = "occupation"
case geschlecht = "intercourse"
case partei
}
}
struct Politicians: Decodable {
let knowledge: [Politician]
}
actor PoliticianDataService {
func fetchPoliticians() async throws -> [Politician] {
guard let url = URL(string: "https://www.abgeordnetenwatch.de/api/v2/politicians") else { return [] }
let (knowledge, _) = attempt await URLSession.shared.knowledge(from: url)
let decoder = JSONDecoder()
let politicians = attempt decoder.decode(Politicians.self, from: knowledge)
return politicians.knowledge
}
}
actor ParteiDataService {
func fetchParteien() async throws -> [Partei] {
guard let url = URL(string: "https://www.abgeordnetenwatch.de/api/v2/events") else { return [] }
let (knowledge, _) = attempt await URLSession.shared.knowledge(from: url)
let decoder = JSONDecoder()
let parteien = attempt decoder.decode(Parteien.self, from: knowledge)
return parteien.knowledge
}
}
@MainActor
class PoliticianListViewModel: ObservableObject {
@Revealed var politicians = [Politician]()
non-public var dataService = PoliticianDataService()
init() {
// Extra setup may very well be executed right here if wanted
}
func fetchPoliticians() {
Job {
do {
let fetchedPoliticians = attempt await dataService.fetchPoliticians()
politicians = fetchedPoliticians
} catch {
print(error)
}
}
}
}
class PoliticianDetailViewModel: ObservableObject {
@Revealed var parteien = [Partei]()
non-public var dataService = ParteiDataService()
func fetchParteien() {
Job {
do {
let fetchedParteien = attempt await dataService.fetchParteien()
parteien = fetchedParteien
} catch {
print(error)
}
}
}
}
struct ContentView: View {
@StateObject var viewModel = PoliticianListViewModel()
var physique: some View {
NavigationView {
Record(viewModel.politicians, id: .id) { politician in
NavigationLink(vacation spot: PoliticianDetailView(politician: politician)) {
Textual content("(politician.firstName) (politician.lastName)")
}
}
.navigationTitle("Politiker in Deutschland")
}
.onAppear {
viewModel.fetchPoliticians()
}
}
}
struct PoliticianDetailView: View {
let politician: Politician
let partei: Partei
@StateObject non-public var viewModel = PoliticianDetailViewModel() // Create a ViewModel
var physique: some View {
VStack {
Textual content("Identify: (politician.firstName) (politician.lastName)")
Textual content("Geburtsjahr (politician.birthYear ?? 0)")
Textual content("Alter: (calculateAge(birthYear: politician.birthYear ?? 0)) Jahre")
Textual content("Beschäftigt als (politician.beruf ?? "Unbekannt")")
Textual content("Geschlecht: (politician.geschlecht ?? "Unbekannt")")
Record(viewModel.parteien, id: .parteiID) { partei in
Textual content("Partei: (partei.namePartei)")
}
.onAppear {
viewModel.fetchParteien()
}
}
.navigationTitle("(politician.firstName) (politician.lastName)")
}
func calculateAge(birthYear: Int) -> Int {
let currentYear = Calendar.present.part(.12 months, from: Date())
return currentYear - birthYear
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}