0

我是一个菜鸟(我的代码/模型目前会显示它,所以请放轻松!)。

我正在尝试创建一个食谱风格(cenotes)应用程序。

这样我就可以更新数据,我有一个远程 json 文件,因此用户无需重新安装即可获取更新的数据。

该应用程序成功检索和解析数据(这是一个胜利!),但仅在首次安装时

当它在线更改时,它不会随后刷新数据。我尝试使用 .onAppear 和 .refreshable 均未成功。我需要删除应用程序并重新安装它才能获取更新的数据。

以下是我文件的一些编辑版本:有人可以帮忙吗?我认为我只有一个 @StateObject/@EnvironmentObject 或类似的不正确的东西,但无法发现错误。

Locations.swift

import Foundation

class Locations: ObservableObject {
    @Published var locations = [Location]()
        
    init() {
        load()
    }
    
    func load() {
        let url = URL(string: "https://www.i-love-tulum.com/cenotes/locations.json")!
               URLSession.shared.dataTask(with: url) {(data,response,error) in
                   do {
                       if let d = data {
                           let data = try JSONDecoder().decode([Location].self, from: d)
                           DispatchQueue.main.async {
                               self.locations = data
                           }
                       } else {
                           print("No Data")
                       }
                   } catch {
                       print ("Error")
                   }
               }.resume()
    } }

Location.swift - 虚拟机

import Foundation

struct Location: Codable, Identifiable {
    var id: String
    let heroPicture: String
    }

App.swift - 应用程序打开此选项卡视图

import SwiftUI

@main struct App: App {
    @StateObject var locations = Locations()
    @State private var selection = 1
        
    var body: some Scene {
        WindowGroup {
            TabView (selection:$selection) {
                NavigationView {
                    ListView()
                }
                .tabItem {
                    Image(systemName: "drop.circle")
                    Text("Cenotes")
                } .tag(1)
            }
            .environmentObject(locations)
        }
    } }

ListView.swift - 第一个选择的选项卡是这个视图 - 这些位置在初始安装后不会更新:

import SwiftUI import MapKit

struct ListView: View {
    @EnvironmentObject var locations: Locations
          
    var body: some View {
        VStack {         
            GeometryReader { geo in
                ScrollView {
                    LazyVStack (alignment: .leading) {
                        ForEach (locations: locations.locations) { location in
                               NavigationLink (
                                    destination: ContentView(location: location),
                                    label: { 
                    Image(location.heroPicture)
                    }
            .navigationTitle("Cenotes")
            .navigationBarTitleDisplayMode(.inline)
    } }
4

2 回答 2

0

尝试每次重新加载并跳过所有缓存:

更新,现在工作:)

func load() {
    let url = URL(string: "https://www.i-love-tulum.com/cenotes/locations.json")!
    
    let config = URLSessionConfiguration.default
    config.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData
    
    let session = URLSession.init(configuration: config)
    session.dataTask(with: url) {(data,response,error) in
        do {
            if let d = data {
                let data = try JSONDecoder().decode([Location].self, from: d)
                DispatchQueue.main.async {
                    self.locations = data
                }
            } else {
                print("No Data")
            }
        } catch {
            print ("Error")
        }
    }.resume()
于 2022-02-10T23:27:35.443 回答
0

一切都设置得很好并且工作正常。这里将两个按钮添加到列表中,以删除所有条目并再次重新加载。也许这有帮助。

struct ListView: View {
    @EnvironmentObject var locations: Locations
    
    var body: some View {
        List {
            ForEach (locations.locations) { location in
                NavigationLink {
                    Text("Content View here ...")
                } label: {
                    VStack(alignment: .leading) {
                        Text(location.name).font(.title)
                        Text(location.aka).foregroundColor(.secondary)
                    }
                }
                .navigationTitle("Cenotes")
                .navigationBarTitleDisplayMode(.inline)
            }
        }
        
        .toolbar {
            ToolbarItem(placement: .navigationBarLeading) {
                Button("Delete all") {
                    locations.locations = []
                }
            }
            ToolbarItem(placement: .navigationBarTrailing) {
                Button("Reload") {
                    locations.load()  
                }
            }
        }
    }
}

在此处输入图像描述

于 2022-02-10T23:00:45.993 回答