Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/108.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift-JSON中的列表仅在视图调用时出现_Ios_Swift_Swiftui - Fatal编程技术网

Ios Swift-JSON中的列表仅在视图调用时出现

Ios Swift-JSON中的列表仅在视图调用时出现,ios,swift,swiftui,Ios,Swift,Swiftui,我的应用程序中有一部分是通过调用外部API构建的,该API返回一个JSON对象,然后通过应用程序中的列表显示该对象。下面可以看到这方面的代码、请求函数以及数据的实际SwiftUI显示 struct ImportantBrokenView: View { @ObservedObject var fetcher = Fetcher() @EnvironmentObject var user: UserFetcher var body: some

我的应用程序中有一部分是通过调用外部API构建的,该API返回一个JSON对象,然后通过应用程序中的列表显示该对象。下面可以看到这方面的代码、请求函数以及数据的实际SwiftUI显示

struct ImportantBrokenView: View {
    
    @ObservedObject var fetcher = Fetcher()
    
    @EnvironmentObject var user: UserFetcher
    
    var body: some View {
        ZStack {
            GeometryReader { metrics in
                if (self.fetcher.hasFinished == true) {
            VStack(alignment: .leading) {
                        HStack(alignment: .top){
                        VStack(alignment: .leading) {
                            NavigationView {
                                VStack(alignment:.center) {
                                    Text("JSON List").font(.largeTitle).fontWeight(.bold).padding(.bottom, 0).padding(.top, 10)
                                    Divider()
                                    Spacer()
                                    List{
                                        ForEach(self.fetcher.fetched ?? []) { result in
                                            VStack(alignment: .leading) {
                                                    VStack(alignment: .leading) {
                                                        Text(result.name).font(.system(size: 26)).fontWeight(.semibold).padding([.horizontal, .top])
                                                      
                                                    
                                                    }
                                            }.listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0))
                                        }
                                    }.frame(width: metrics.size.width * 1.0)
                                }
                            }
                        }
                }
            }
                } else {
                    HStack(alignment: .center) {
                        VStack(alignment: .center) {
                            Text("Loading...")
                        }.frame(width: metrics.size.width * 1.0)
                    }.frame(width: metrics.size.width * 1.0, height: metrics.size.height * 1.0)
                }
            }.onAppear { self.fetcher.request(authToken: self.user.user!.accessToken) }
        }
    }
}

public struct Model2: Codable, Identifiable {
    public let id: Int
    public let name: String
}

public struct Model: Codable {
    public let fetched: Model2
    
    enum CodingKeys: String, CodingKey {
        case fetched = "return"
    }
}

public class Fetcher: ObservableObject {
    @Published var fetched: Model?
    public let objectWillChange = PassthroughSubject<Fetcher,Never>()
        
        @Published var hasFinished: Bool = false {
            didSet {
                objectWillChange.send(self)
            }
        }
        
        func request(authToken: String) {
            guard let url = URL(string: "https://mywebsite.com/api/getdata") else { return }
            
            var urlRequest = URLRequest(url: url)
            urlRequest.httpMethod = "POST"
            
            let APIauthToken = "Bearer " + authToken
            urlRequest.addValue(APIauthToken, forHTTPHeaderField: "Authorization")
            urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
            urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
            
            URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
                
                do {
                    if let d = data {
                        let decodedLists = try JSONDecoder().decode(Model.self, from: d)
                        DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
                            guard let _weakSelf = self else {return}
                            _weakSelf.fetched = decodedLists
                        }
                    } else {
                        print("No Data")
                    }
                } catch {
                    print(error)
                }
                
            }.resume()
            
            DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
                guard let _weakSelf = self else {return}
                _weakSelf.hasFinished = true
            }
        }
    }
struct ImportantBrokenView:视图{
@ObservedObject var fetcher=fetcher()
@EnvironmentObject变量用户:UserFetcher
var body:一些观点{
ZStack{
GeometryReader{中的度量
if(self.fetcher.hasFinished==true){
VStack(对齐:。前导){
HStack(对齐:。顶部){
VStack(对齐:。前导){
导航视图{
VStack(对齐:。中心){
文本(“JSON列表”).font(.largeTitle).fontwweight(.bold).padding(.bottom,0).padding(.top,10)
分隔器()
垫片()
名单{
ForEach(self.fetcher.fetched???[]){结果为
VStack(对齐:。前导){
VStack(对齐:。前导){
Text(result.name).font(.system(size:26)).fontwweight(.semibold).padding([.horizontal,.top])
}
}.listRowInsets(.init(顶部:0,前导:0,底部:0,尾随:0))
}
}.frame(宽度:metrics.size.width*1.0)
}
}
}
}
}
}否则{
HStack(对齐:。中心){
VStack(对齐:。中心){
文本(“加载…”)
}.frame(宽度:metrics.size.width*1.0)
}.frame(宽度:metrics.size.width*1.0,高度:metrics.size.height*1.0)
}
}.onAppear{self.fetcher.request(authToken:self.user.user!.accessToken)}
}
}
}
公共结构模型2:可编码、可识别{
公共出租id:Int
公共let名称:String
}
公共结构模型:可编码{
获取公共let:Model2
枚举编码键:字符串,编码键{
case fetched=“return”
}
}
公共类获取程序:ObservieObject{
@获取的已发布变量:模型?
public let objectWillChange=PassthroughSubject()
@已发布的变量hasFinished:Bool=false{
迪塞特{
objectWillChange.send(self)
}
}
func请求(authToken:String){
guard let url=url(字符串:https://mywebsite.com/api/getdata)否则{return}
var urlRequest=urlRequest(url:url)
urlRequest.httpMethod=“POST”
让APIauthToken=“承载人”+authToken
urlRequest.addValue(APIauthToken,forHTTPHeaderField:“授权”)
URL请求.addValue(“应用程序/json”,用于HttpHeaderField:“接受”)
urlRequest.addValue(“应用程序/json”,forHTTPHeaderField:“内容类型”)
URLSession.shared.dataTask(带:urlRequest){(数据、响应、错误)在
做{
如果设d=数据{
让decodedLists=try JSONDecoder().decode(Model.self,from:d)
DispatchQueue.main.asyncAfter(截止日期:.now()+1){[weak self]在中
guard let_weakSelf=self-else{return}
_weakSelf.fetched=解码列表
}
}否则{
打印(“无数据”)
}
}抓住{
打印(错误)
}
}1.简历()
DispatchQueue.main.asyncAfter(截止日期:.now()+1){[weak self]在中
guard let_weakSelf=self-else{return}
_weakSelf.hasFinished=true
}
}
}
当我运行这段代码时,它包含了生成JSON的所有代码,JSON用于派生Swift列表。当我运行这个时,我的列表是空的。当我返回导航堆栈,然后重新进入视图时,列表被占用。为什么?


如果非要我猜一猜,我会说这与DispatchQueue中包含的截止日期有关,请求和hasFinished响应的截止日期相同。

不相关,但
弱自我->强自我
舞蹈毫无意义<代码>调度队列闭包不会导致保留周期<代码>数据任务异步工作,稍后执行完成处理程序。而不是奇怪的
asyncAfter
表达式调用完成处理程序中的
objectWillChange.send(self)
。不相关但
弱自我->强自我
舞蹈是胡说八道<代码>调度队列闭包不会导致保留周期<代码>数据任务异步工作,稍后执行完成处理程序。而不是在完成处理程序中调用异常的
asyncAfter
表达式
objectWillChange.send(self)