У меня есть два фрагмента кода для декодирования данных JSON (локальный и удаленный). Оба работают. Я также могу визуализировать свои локальные данные, но не удаленные данные. Они абсолютно одинаковы (отличается только расположение файла json и imageUrl). В моем коде TestView.swift, который используется в обоих случаях, я дал два комментария, которые указывают на мою проблему.
Моя проблема: Как мне определить testData: [Test] для удаленного случая,что хорошо определено для локального случая?
Чего не хватает? Пожалуйста помоги. Я новичок в Xcode и SwiftUI, поэтому любая помощь будет принята с благодарностью.
PS В основном я пытаюсь использовать два Swift Tutorials (на YouTube), то есть создать сложный интерфейс с SwiftUI от Start до Finish, SwiftUIИзвлечение данных JSON и изображений с помощью BindableObject.
// Data.swift
import SwiftUI
import Combine
// 1.) Этот первый фрагмент кода декодирует локальные данные json и правильно визуализирует их
let testData:[Test] = load("test.json")
func load<T:Decodable>(_ filename:String, as type:T.Type = T.self) -> 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 Test_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
// 2.) Этот второй фрагмент кода декодирует удаленные данные JSON, но не отображает их
class testDatas: ObservableObject {
@Published var tests:[Test] = [Test]()
func getAllTests() {
let file = URLRequest(url: URL(string: "https://myurl/test.json")!)
let task = URLSession.shared.dataTask(with: file) { (data, _, error) in
guard error == nil else { return }
do {
let tests = try JSONDecoder().decode([Test].self, from: data!)
DispatchQueue.main.async {
self.tests = tests
print(tests)
}
} catch {
print("Failed To decode: ", error)
}
}
task.resume()
}
init() {
getAllTests()
}
init(tests: [Test]) {
self.tests = tests
}
}
struct Test_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
// TestView.swift (используется в обоих случаях декодирования)
import SwiftUI
// testData needed here only for the remote case, but this might be wrong and the problem?
let testData:[Test] = [Test]()
struct TestView: View {
// testDatas needed here only for the remote case to decode json data)
@ObservedObject var fixer: testDatas = testDatas()
@EnvironmentObject var loader: ImageLoader
var categories:[String:[Test]] {
.init(
grouping: testData,
by: {$0.category.rawValue}
)
}
var body: some View {
NavigationView{
List (categories.keys.sorted(), id: \String.self) {key in TestRow(categoryName: "\(key).environmentObject(ImageLoader(with: key.imageUrl)) Tests".uppercased(), tests: self.categories[key]!)
.frame(height: 320)
.padding(.top)
.padding(.bottom)
}
.navigationBarTitle(Text("TEST"))
}
}
}
class ImageLoader:ObservableObject
{
@Published var data:Data = Data()
func getImage(imageURL:String) {
guard let test = URL(string: imageURL) else { return }
URLSession.shared.dataTask(with: test) { (data, response, error) in
DispatchQueue.main.async {
if let data = data {
self.data = data
}
}
print(data as Any)
}.resume()
}
init(imageURL:String) {
getImage(imageURL: imageURL)
}
}
struct TestView_Previews: PreviewProvider {
@ObservedObject var imageLoader: ImageLoader
init(test:String)
{
imageLoader = ImageLoader(imageURL: test)
}
static var previews: some View {
TestView()
}
}