SwiftUI:列表中的数据有时出现有时不出现
Posted
技术标签:
【中文标题】SwiftUI:列表中的数据有时出现有时不出现【英文标题】:SwiftUI: Data in list appears sometimes and sometimes not 【发布时间】:2020-01-02 18:40:30 【问题描述】:我有问题。在我的应用程序中,我有带有设备的 CoreData 和设备的 IP。我想发出一个 API 请求以从选定的设备获取 JSON 数据并将它们显示在列表中。我的问题是有时它有效,有时它不工作,并且当我更改数据时列表不会更新。我希望有人可以帮助我。
BouquetAPIModel.swift
struct BouquetAPIModel: Codable
let success: String
let data: DataClass
// MARK: - DataClass
struct DataClass: Codable
let bouquets: [Bouquet]
// MARK: - Bouquet
struct Bouquet: Codable
var number, name: String
Device.swift
public class Device: NSManagedObject, Identifiable
@Published var bouquets : [Bouquet] = [Bouquet]()
func fetchBouquetList()
fetchAPIRequest(apiPath: "/control/getbouquets?format=json") (res: Result<BouquetAPIModel, Error>) in
switch res
case .success(let bouquets):
self.bouquets = bouquets.data.bouquets
case .failure(let err):
print("Fail to fetch bouquets: ", err)
fileprivate func fetchAPIRequest<T: Decodable>(apiPath: String, completion: @escaping (Result<T, Error>) -> ())
let urlString = getApiUrl(apiPath: apiPath)
guard let url = URL(string: urlString) else return
URLSession.shared.dataTask(with: url) (data,resp, err) in
if let err = err
completion(.failure(err))
return
do
let welcome = try JSONDecoder().decode(T.self, from: data!)
completion(.success(welcome))
catch let jsonError
completion(.failure(jsonError))
.resume()
BouquetView.swift
import SwiftUI
struct BouquetView: View
@Binding var device : Device?
@State var bouquets: [Bouquet] = [Bouquet]()
var body: some View
VStack
Text(String(device?.deviceName ?? "fehler")).onTapGesture
self.device?.bouquets.removeFirst()
print("Touch")
List (self.bouquets, id: \Bouquet.name) bouquet in
VStack(alignment: .leading)
Text(bouquet.name)
.onAppear(perform: loadBouquets)
func loadBouquets()
if device == nil
//TODO jumo to settings
else
device?.fetchBouquetList()
self.bouquets = device!.bouquets
struct BouquetView_Previews: PreviewProvider
static var previews: some View
BouquetView(device: .constant(nil))
【问题讨论】:
【参考方案1】:你能像下面这样更新你的设备吗?
public class Device: ObservableObject, Identifiable
...
并确保在传递给BouquetView
之前使用注释@ObservedObject
声明您的设备
【讨论】:
带来错误:“设备”与协议“ObservableObject”的冗余一致性 请尝试新的更新,ObserverableObject
符合类型NSManagedObject
所以摆脱NSManagedObject
然后我在另一个视图中得到类型“设备”不符合协议“NSFetchRequestResult”,我使用 Fetchrequest 获取核心数据
处理核心数据是不同的场景。您可以尝试使用这种情况来确保从服务器加载数据并在您的视图中更新。
您可以创建一个新类来处理从服务器获取数据。【参考方案2】:
获取可能会很长,所以您已经开始参加比赛了。为避免这种情况,可以使用以下方法
1) 删除以下行,因为此时数据可能尚未准备好
self.bouquets = device!.bouquets
2) 为数据集添加显式监听器
if device == nil
//TODO jumo to settings
device!.$bouquets
.assign(to: \.bouquets, on: self)
.store(in: &cancellables) // << you will need to create this store var
【讨论】:
在 if 或 else 中? 在if
中,因为loadBouquets
可以像我假设的那样被多次调用,但订阅者只能被分配一次。
但设备永远不会为零
这是你的代码……它是可选的。如果它从不为零,那为什么它是可选的?如果不是,那么您可以将订阅者分配放入init
,类似于here
如果在另一个视图中没有选择潜水,它可能为零,但我选择了一个。我尝试使用 init以上是关于SwiftUI:列表中的数据有时出现有时不出现的主要内容,如果未能解决你的问题,请参考以下文章