SwiftUI JSON извлекает данные из API Wordpress

Мне нужна помощь по моим структурам (og_image Link-> url)

Моя структура на данный момент

struct UpcomingGames: Codable,Identifiable {
    var id: Int
    let link: String
    let title: Rendered
    let yoastHeadJSON: Title
    
    enum CodingKeys: String, CodingKey {
        case id
        case link
        case title
        case yoastHeadJSON = "yoast_head_json"
    }
}

struct Rendered: Codable {
     var rendered: String
}

struct Title: Codable {
    let title: String
    let description: String
    let author: String
    let ogimage: [OgImage]
    
    enum CodingKeys: String, CodingKey {
        case title
        case description
        case author
        case ogimage = "og_image"
    }
}

struct OgImage: Codable {
    let width, height: Int
    let url: String
    let type: String
}

все работает нормально, но я не могу получить доступ к og_image-> URL

мой код

struct ContentView: View {
    
    @State var upcominggames = [UpcomingGames]()
    @State private var queryString = ""
    @State var showSidebar = false
    @State var showSettings = false

    var body: some View {
        NavigationView {
            List {
                ForEach(upcominggames, id: \.id) { item in
                    NavigationLink(destination: details(item: item)){
                        HStack {
                                Text(item.yoastHeadJSON.title)
                                    .font(.headline)
                                    .bold()
                                    .lineLimit(2)
                                Text(item.yoastHeadJSON.description)
                                    .font(.subheadline)
                                    .lineLimit(2)
                                    .padding(.bottom,10)
                                HStack {
                                    Image("icon_comment.png.pagespeed.ce.PPGg0gnQ7a")
                                    Text("12")
                                        .font(.caption)
                                    Spacer()
                                    Text("Weiterlesen")
                                        .padding(4)
                                        .font(.caption)
                                        .background(Color.gray)
                                        .foregroundColor(Color.white)
                                        .padding(.bottom,5)
                    
                                    //Text(item.yoastHeadJSON.ogimage)
                                    //Text(item.yoast_head_json.og_image)
                                    //Text(item.yoast_head_json.og_image.)
                                }
                            }
                        }
                    }
                }
            }
            .listStyle(.grouped)
            .onAppear(perform: loadData)
            .navigationTitle("Xbox News")
            .navigationBarTitleDisplayMode(.automatic)
            
            /*
             Toolbar
             */
            .toolbar {
                ToolbarItem(placement: .principal) {
                    HStack {
                        Button("",systemImage: "line.3.horizontal", action: { showSidebar = true })
                            .sheet(isPresented: $showSidebar, content: { Einstellungen() })
                        Spacer()
                        Image("logo")
                            .resizable()
                            .frame(width: 60, height: 40,alignment: .center)
                            .padding(.top,-5)
                        Spacer()
                        Button("",systemImage: "gearshape", action: { showSettings = true })
                            .sheet(isPresented: $showSettings, content: { Einstellungen() })
                    }
                }
            }
            /*
             Toolbar Ende
             */
        }

        
        
        
        
       
        
        
        
        /*.searchable(text: $queryString, prompt: "Suche...") {
            
        }*/
        
        
    }

    
    
    
    func loadData() {
        guard let url = URL(string: "https://xboxdynasty.de/wp-json/wp/v2/posts/") else {
            print("Invalid URL")
            return
        }
        let request = URLRequest(url: url)
        URLSession.shared.dataTask(with: request) {data, response, error in
            if let data = data {
                let decoder = JSONDecoder()
                decoder.dataDecodingStrategy = .base64
                
                if let decodedResponse = try?
                    decoder.decode([UpcomingGames].self, from: data) {
                    DispatchQueue.main.async {
                        self.upcominggames = decodedResponse
                    }
                    return
                }
            }
            print("Fetch failed: \(error?.localizedDescription ?? "Uknown error")")
        }.resume()
    } // Ende func loadData
    
    
    
    
        
}

Что-то не так с моей структурой

Вот ссылка на API

https://xboxdynasty.de/wp-json/wp/v2/posts/

я пробовал QuickType для структуры, но ничего не помогает

я новичок в Swift

И снова: не используйте try? при декодировании, вы игнорируете важную информацию, если декодирование выдаст ошибку.

Joakim Danielson 16.08.2024 12:57

Как говорит Йоаким, реализуйте свою попытку? декодирование на основе do { try<decode> } catch {<log errors>} и запишите ошибки, которые вы получаете в catch.

Duncan C 16.08.2024 15:07
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
0
2
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Попробуйте этот подход к ...access to og_image-> url, сделав OgImage идентифицируемым и используя ForEach(item.yoastHeadJSON.ogimage) как показано в примере кода.

Также обратите внимание на обновленный func loadData().

struct OgImage: Codable, Identifiable {  // <--- here
    let id = UUID()  // <--- here
    
    let width, height: Int
    let url: String
    let type: String
    
    enum CodingKeys: String, CodingKey {  // <--- here
        case width, height, url, type
    }
}

struct ContentView: View {
    
    @State private var upcominggames = [UpcomingGames]()
    @State private var queryString = ""
    @State private var showSidebar = false
    @State private var showSettings = false
    
    var body: some View {
        NavigationView {
            List {
                ForEach(upcominggames, id: \.id) { item in
                    NavigationLink(destination: Text(item.title.rendered)){  // <--- for my testing
                        HStack {
                            Text(item.yoastHeadJSON.title)
                                .font(.headline)
                                .bold()
                                .lineLimit(2)
                            Text(item.yoastHeadJSON.description)
                                .font(.subheadline)
                                .lineLimit(2)
                                .padding(.bottom,10)
                            HStack {
                                Image(systemName: "globe")
                                Text("12")
                                    .font(.caption)
                                Spacer()
                                Text("Weiterlesen")
                                    .padding(4)
                                    .font(.caption)
                                    .background(Color.gray)
                                    .foregroundColor(Color.white)
                                    .padding(.bottom,5)

                            }
                        }
                    }
                    
                    // --- here, ogimage is an array of OgImage
                    // ForEach(item.yoastHeadJSON.ogimage) { img in
                        // Text(img.url).foregroundColor(Color.red)
                   // }

                // --- for the actual images
                ForEach(item.yoastHeadJSON.ogimage) { img in
                    AsyncImage(url: URL(string: img.url)) { image in
                        image.resizable().frame(width: 123, height: 123)
                    } placeholder: {
                        ProgressView()
                    }
                }


                }
            }
        }
        .listStyle(.grouped)
        .onAppear(perform: loadData)
        .navigationTitle("Xbox News")
        .navigationBarTitleDisplayMode(.automatic)

        .toolbar {
            ToolbarItem(placement: .principal) {
                HStack {
                    Button("",systemImage: "line.3.horizontal", action: { showSidebar = true })
                        .sheet(isPresented: $showSidebar, content: { Text("sheet") })
                    Spacer()
                    Image("logo")
                        .resizable()
                        .frame(width: 60, height: 40,alignment: .center)
                        .padding(.top,-5)
                    Spacer()
                    Button("",systemImage: "gearshape", action: { showSettings = true })
                        .sheet(isPresented: $showSettings, content: { Text("sheet") })
                }
            }
        }
    }
    
func loadData() {
        guard let url = URL(string: "https://xboxdynasty.de/wp-json/wp/v2/posts/") else {
            print("Invalid URL")
            return
        }
        let request = URLRequest(url: url)
        
        URLSession.shared.dataTask(with: request) { data, response, error in
            if let data = data {
                // --- here
                do {
                    upcominggames = try JSONDecoder().decode([UpcomingGames].self, from: data)
                } catch {
                    print("error: \(error)")
                }
            } else {
                print("Fetch failed: \(error?.localizedDescription ?? "Uknown error")")
            }
        }.resume()
        
    } // Ende func loadData
}

Большое спасибо, МУЖЧИНА :-* я играю с этим уже 2 дня... Теперь все работает, и я могу продолжать

Patrick Egger 16.08.2024 15:24

Если мой ответ помог, примите его, отметив галочку рядом с ним, она станет зеленой.

workingdog support Ukraine 16.08.2024 15:33

Другие вопросы по теме