(见下图)这段代码原来是用.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)")
}
}
试试这个:(如果你在一个函数中加载异步的东西,你应该使用完成块的解决方案。
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()
}
}