Swift 3 / iOS UIView在检索远程JSON数据后没有更新

时间:2017-07-27 21:39:29

标签: ios json swift uiview reload

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

fetchUser()方法中,我有一个print("Username: \(self.user.username)"),显示正在100%的时间内检索到正确的数据,但它不会在视图中100%显示。< / p>

非常感谢任何帮助。

谢谢!

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()

    }

2 个答案:

答案 0 :(得分:1)

两个建议:

  1. 严格来说,对UIView对象的所有访问都应该在主线程上。您已调度到主线程以致电reloadView,但也可能在您设置&#34;用户名&#34;和#34;净资产&#34;标签上的值
  2. 确定标签是空白的吗?这可能是一个自动布局问题吗? (尝试将标签的背景颜色设置为黄色,以检查它们是否具有正确的大小。如果存在冲突的约束,有时自动布局可以将视图压缩为空)

答案 1 :(得分:1)

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

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

然后,像我一样更改代码,不要使用您拥有的reloadView函数,而是更新fetchUser函数末尾主线程上的UI元素。我也改了它,所以你没有更新UI两次,因为你在if let uid = ... fetchUser语句底部有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()