如何在swift 5中解析一个json url api到全局变量数组?

问题描述 投票:0回答:1

(见下图)这段代码原来是用.json文本文件实现的,但现在我想把它改成用一个活的url实现,我不知道如何把它变成一个全局变量,因为一旦你切换到url,它就有URLSession任务,你必须用task.resume()让它持续更新,但我又不知道如何才能把可解密的T作为一个void函数返回到catData数组中。请大家帮忙谢谢!

开始我的新实现。

import UIKit
import SwiftUI
import CoreLocation

let catData: [Cat] = load("https://tmha-backend.herokuapp.com/api/cats/")

func load<T: Decodable>(_ linkname: String) -> T {
    let url = URL(string: "https://tmha-backend.herokuapp.com/api/cats/")
    guard let requestUrl = url else {fatalError("Couldn't find \(linkname)")}
    var request = URLRequest(url: requestUrl)
    // Specify HTTP Method to use
    request.httpMethod = "GET"
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    // Send HTTP Request
    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
         guard let data = data else { return }
        do {
            var returnValue: Cat?
            let decoder = JSONDecoder()
            returnValue = try decoder.decode(Cat.self, from: data)
        } catch {
            fatalError("Couldn't parse \(linkname) as \(T.self):\n\(error)")
        }
    }
    task.resume()
}

原代码:

import UIKit
import SwiftUI
import CoreLocation

let catData: [Cat] = load("catData.json")

func load<T: Decodable>(_ filename: String) -> T {
    let data: Data
    guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
        else {
            fatalError("Couldn't find \(filename) in main bundle.")
    }
    do {
        data = try Data(contentsOf: file)
    } catch {
        fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
    }
    do {
        let decoder = JSONDecoder()
        return try decoder.decode(T.self, from: data)
    } catch {
        fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
    }
}

json decode swift5 urlsession jsondecoder
1个回答
0
投票

试试这个:(如果你在一个函数中加载异步的东西,你应该使用完成块的解决方案。

struct Cat: Codable {
    let name, gender, age, welcomeDescription: String
    let breed, itype, status, arrivalDate: String
    let arrivalDetails, medicalHistory, vaccinations: String
    let isMicrochipped: Bool
    let fleaControlDate, dewormingDate, fivFelvDate, specialNeeds: String
    let personality: [Int]
    let morePersonality, comments, personalExp: String

    enum CodingKeys: String, CodingKey {
        case name, gender, age
        case welcomeDescription = "description"
        case breed, itype, status
        case arrivalDate = "arrival_date"
        case arrivalDetails = "arrival_details"
        case medicalHistory = "medical_history"
        case vaccinations
        case isMicrochipped = "is_microchipped"
        case fleaControlDate = "flea_control_date"
        case dewormingDate = "deworming_date"
        case fivFelvDate = "fiv_felv_date"
        case specialNeeds = "special_needs"
        case personality
        case morePersonality = "more_personality"
        case comments
        case personalExp = "personal_exp"
    }
}

typealias Cats  = [Cat]

struct ContentView : View {

    @State var cats: Cats = []

  //  @State var myTask

    func load(_ linkname: String, completion:@escaping (Cats)->())  {
    let url = URL(string: "https://tmha-backend.herokuapp.com/api/cats/")
    guard let requestUrl = url else {fatalError("Couldn't find \(linkname)")}
    var request = URLRequest(url: requestUrl)
    // Specify HTTP Method to use
    request.httpMethod = "GET"
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    // Send HTTP Request
    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
         guard let data = data else { return }
        do {
            var returnValue: Cats?
            let decoder = JSONDecoder()
            returnValue = try decoder.decode(Cats.self, from: data)
            completion(returnValue!)
        } catch {
            fatalError("Couldn't parse \(linkname) as \(Cat.self):\n\(error)")
        }
    }
    task.resume()

    return
}


    var body : some View {

        List(cats, id: \.name) { cat in
            Text(cat.name)
        }.onAppear() {
            self.load("https://tmha-backend.herokuapp.com/api/cats/") { cats in
                self.cats = cats
            }

        }
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.