【问题标题】:Why is my data not returning to my UI but it’s being decoded fine in SwiftUI?为什么我的数据没有返回到我的 UI,但它在 SwiftUI 中被很好地解码?
【发布时间】:2021-06-26 18:01:18
【问题描述】:

我在 here 之前已经发布过这个问题,并且我根据 this 文章对我的代码进行了一些更改,但现在我的数据甚至像以前一样在 .onAppear {…} 中不可用。基本上,我无法从 reddit API 中获取数据并将其存储在变量 theUser 中。

这是我的代码,感谢您抽出宝贵时间 :)

struct ContentView: View {
    @State var didAppear = false
    @State var theUser = getNilUser()
    var body: some View {
        VStack{
            Text(theUser.data.subreddit.display_name_prefixed ?? "No name found")
            Text(theUser.data.subreddit.public_description ?? "No description found")
        }
        .onAppear(perform: {
            getUser(withName: "markregg")
            print(theUser)
        })
    }
    func getUser(withName username: String) {
        if !didAppear {
            guard let url = URL(string: "https://www.reddit.com/user/\(username)/about.json") else {
                print("Whoops")
                return
            }
            URLSession.shared.dataTask(with: url) { data, response, error in
                if let data = data {
                    do {
                        if let decodedUser = try? JSONDecoder().decode(user.self, from: data) {
                            DispatchQueue.main.async {
                                self.theUser = decodedUser
                            }
                            return
                        }
                    } catch {
                        print(error)
                    }
                } else if let error = error {
                    print(error)
                } else {
                    print("Request failed")
                }
            }.resume()
            didAppear = true
        } 
    }
}

【问题讨论】:

  • 什么时候叫print(theUser)什么时候叫self.theUser = decodedUser?如果需要,请添加print。并替换 print(theUser)`with print("onAppear() theUser (theUser)")`,以免与您将在`self.theUser = decodedUser. Also, dont use try?, you use a do/catch`中打印它的位置混淆,你没有错误吗?
  • 以上评论很重要。此外,在您链接到的最后一个问题中,回答者解释说网络调用是 异步 并且不会立即返回。在开始异步调用后,您仍在尝试print,此时数据实际上还没有。一旦您确定您的 JSON 正确解码,请尝试在设置 self.theUser 后立即打印。我还建议将所有网络代码移动到单独的 ObservableObject 中。

标签: json swift swiftui jsondecoder


【解决方案1】:

我对您的代码进行了一些快速更改(很晚了,抱歉)。一些cmets:(1)你应该使用try吗? (带问号)您不需要捕获错误(永远不会生成),(2)为什么不使用可选的用户类型?,(3)您设置了“传出连接(客户端)”功能,不是吗? ?

struct ContentView: View {
    @State var didAppear = false
    @State var theUser: User? // = getNilUser()
    var body: some View {
        VStack{
            Text("Display name: \(theUser?.data.subreddit.display_name_prefixed ?? "No name found")")
            Text("Public description: \(theUser?.data.subreddit.public_description ?? "No description found")")
        }
        .frame(width:200, height: 200)
        .onAppear(perform: {
            getUser(withName: "markregg")
        })
    }
    func getUser(withName username: String) {
        if !didAppear {
            guard let url = URL(string: "https://www.reddit.com/user/\(username)/about.json") else {
                print("Whoops")
                return
            }
            URLSession.shared.dataTask(with: url) { data, response, error in
                if let data = data {
                    if let decodedUser = try? JSONDecoder().decode(User.self, from: data) {
                        DispatchQueue.main.async {
                            self.theUser = decodedUser
                        }
                        return
                    }
                } else if let error = error {
                    print(error)
                } else {
                    print("Request failed")
                }
            }.resume()
            didAppear = true
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    相关资源
    最近更新 更多