ios - Swift 3/iOS UIView 在检索远程 JSON 数据后不更新

标签 ios json swift uiview reload

我有一个带有用户列表的UITableView。当您点击一行时,用户的 uid 会传递到 UIViewController 详细信息 View 。 URLRequest 用于检索用户的 JSON 数据(用户名、头像等)。但是,详细信息 View 不一致地更新信息。有时它会显示用户的姓名、头像等,但有时它不会显示任何内容,或者仅显示用户名或仅显示头像等。

fetchUser() 方法中,我有一个 print("Username:\(self.user.username)") 显示正在检索正确的数据100% 的时间,但不会 100% 的时间在 View 中显示。

任何帮助将不胜感激。

谢谢!

class ProfileViewController: UIViewController {

    @IBOutlet weak var avatarImageView: UIImageView!
    @IBOutlet weak var usernameLabel: UILabel!
    @IBOutlet weak var networthLabel: UILabel!

    var user: User!
    var uid: Int?

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        fetchUser()
    }

    func reloadView() {
        self.usernameLabel.text = user.username
        self.networthLabel.text = "$" + NumberFormatter.localizedString(from: Int((user.networth)!)! as NSNumber, number: NumberFormatter.Style.decimal)
        self.avatarImageView.downloadImage(from: user.avatar!)
        circularImage(photoImageView: self.avatarImageView)
    }

    func fetchUser() {
        // Post user data to server
        let myUrl = NSURL(string: "http://localhost/test/profile")
        let urlRequest = NSMutableURLRequest(url: myUrl! as URL);
        urlRequest.httpMethod = "POST"

        let postString = "uid=\(uid!)"

        urlRequest.httpBody = postString.data(using: String.Encoding.utf8)

        let task = URLSession.shared.dataTask(with: urlRequest as URLRequest) { (data, response, error) in

            if (error != nil) {
                print("error=\(String(describing: error))")
                return
            } // end if

            self.user = User()

            do {

                let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String : AnyObject]

                if let parseJSON = json?["data"] as? [[String : AnyObject]] {

                    for userFromJson in parseJSON {

                        let userData = User()

                        if let uid = userFromJson["uid"] as? String,
                            let username = userFromJson["username"] as? String,
                            let networth = userFromJson["networth"] as? String,
                            let avatar = userFromJson["avatar"] as? String {

                            userData.uid = Int(uid)
                            userData.username = username
                            userData.networth = networth
                            userData.avatar = avatar

                            self.usernameLabel.text = username
                            self.networthLabel.text = networth
                            self.avatarImageView.downloadImage(from: avatar)
                            circularImage(photoImageView: self.avatarImageView)

                        } // end if

                        self.user = userData

                    } // end for

                } // end if

                DispatchQueue.main.async {
                    print("Username: \(self.user.username)")
                    self.reloadView()
                }

            } catch let error {
                print(error)
            }
        }
        task.resume()

    }

最佳答案

首先,在 viewWillAppear 中调用 fetch user,如下所示:

覆盖 func viewWillAppear(_animated: Bool) { super.viewWillAppear(动画) 获取用户() }

然后,像我一样更改这里的代码,不要使用您拥有的 reloadView 函数,而是在 fetchUser< 末尾更新主线程上的 UI 元素 功能。我还更改了它,这样您就不会更新 UI 两次,因为 fetchUser 中的 if let uid = ... 语句底部有 4 行更新了 UI不在主线程中的元素,这就是为什么在我的版本中我删除了这 4 行代码。让我知道这是否对您有用。

let task = URLSession.shared.dataTask(with: urlRequest as URLRequest) { (data, response, error) in

        if (error != nil) {
            print("error=\(String(describing: error))")
            return
        } // end if

        self.user = User()

        do {

            let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String : AnyObject]

            if let parseJSON = json?["data"] as? [[String : AnyObject]] {

                for userFromJson in parseJSON {

                    let userData = User()

                    if let uid = userFromJson["uid"] as? String,
                        let username = userFromJson["username"] as? String,
                        let networth = userFromJson["networth"] as? String,
                        let avatar = userFromJson["avatar"] as? String {

                        userData.uid = Int(uid)
                        userData.username = username
                        userData.networth = networth
                        userData.avatar = avatar

                    } // end if

                    self.user = userData

                } // end for

            } // end if

            DispatchQueue.main.async {
                self.usernameLabel.text = user.username
                self.networthLabel.text = "$" + NumberFormatter.localizedString(from: Int((user.networth)!)! as NSNumber, number: NumberFormatter.Style.decimal)
                self.avatarImageView.downloadImage(from: user.avatar!)
                circularImage(photoImageView: self.avatarImageView)
            }

        } catch let error {
            print(error)
        }
    }
    task.resume()

关于ios - Swift 3/iOS UIView 在检索远程 JSON 数据后不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45361454/

相关文章:

ios - 点击后如何更改 SwiftUI TextField 样式?

ios - iTunes Connect 提交审核错误

ios - 位图 CGContext 绘图不断增加内存使用量

ios - 找不到图书馆 |链接器命令失败

c# - 将 JSON 转换为类会更改字符串值。 JSON.NET 中的错误?

sql - 如何在 CTE 或子查询中引用 DISTINCT 列名称?

swift - 无法快速打开 CSV 文件

ios - iPad,类似 App Store 的界面,管理项目的建议

ios - 为什么允许播放 YouTube 视频,而 iOS 禁止播放 flash 内容?

android - java.lang.IllegalArgumentException : Illegal character in query 异常