如何知道HTTPRequest(Swift)之后所有任务何时完成

时间:2019-03-24 22:42:42

标签: ios swift uitableview asynchronous httprequest

我目前面临困扰我数日的问题。我尝试了几种解决方案,但似乎无法解决该问题。让我说明发生了什么。

我有一个供稿,其中的帖子位于UITableView中。用户选择一个单元格后,就会在新的UIViewController中为他显示该帖子的详细视图。在其中,我设置了所有视图,并在loadPostDetails()方法中调用了函数viewDidLoad()。该视图一出现,就会显示一个自定义的加载指示器,该指示器设置为在加载详细信息后消失(隐藏),然后UITableView的{​​{1}}(我们将其称为{{1} })。

在我的UIViewController函数中,我做了一个HTTPRequest,它获取了我需要的JSON数据。这将返回三种信息:帖子详细说明自己,喜欢和评论。在重新加载PostController并显示它之前,我需要处理这三个元素中的每一个。目前,我是这样的:

loadPostDetails()

注意:我向UITableView添加了更多文本,例如用户的日期和个人资料图片,但是我删除了几行以使其更易读,并且因为多余的代码无关紧要对于这个问题。

现在,正如您可能已经看到的那样,我在1秒钟后调用了重载程序,因此在95%的情况下,它工作正常(但仍然不完美,因为它是“ hack”)。在另外5%的情况下,布局无法找出正确的约束条件,从而导致布局非常糟糕。

最近几天,我尝试与HTTP.retrievePostDetails(postID: postID, authRequired: true) { (error, postDetails) in if(error != nil) { self.navigationController?.popViewController(animated: true) } else { if let postDetails = postDetails, let postInfo = postDetails["postInfoRows"] as? [[String: Any]], let postLikesCount = postDetails["postLikesCount"] as? Int, let postLikesRows = postDetails["postLikesRows"] as? [[String: Any]], let postCommentsRows = postDetails["postCommentsRows"] as? [[String: Any]] { DispatchQueue.main.async { let tableFooterView = self.postTableView.tableFooterView as! tableFooterView if let postTitle = postInfo[0]["postTitle"] as? String, let postText = postInfo[0]["postText"] as? String { self.postTitleLabel.text = postTitle self.postTextLabel.text = postText } for (index, postCommentRow) in postCommentsRows.enumerated() { tableFooterView.postComments.append(Comment(userID: postCommentRow["userID"] as! Int, userProfilePicURL: postCommentRow["userProfilePicURL"] as! String, userDisplayName: postCommentRow["userDisplayName"] as! String, commentTimeStamp: postCommentRow["commentTimeStamp"] as! TimeInterval, commentText: postCommentRow["commentText"] as! String)) } var likeDisplayNames = [String]() for postLikeRow in postLikesRows { likeDisplayNames.insert(postLikeRow["userDisplayName"] as! String, at: 0) } if(postLikesCount > 2) { tableFooterView.likesLabel.text = "\(likeDisplayNames[0]), \(likeDisplayNames[1]) and \(postLikesCount - 2) others" } else { tableFooterView.likesLabel.text = "\(postLikesCount) likes" } } DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: { self.screenDotsLoader.isHidden = true self.screenDotsLoader.stopAnimating() self.postTableView.isHidden = false self.postTableView.reloadData() }) } } } 一起玩,但是我不知道该怎么做。我实际上是想知道何时已执行所有任务,因此,当所有UILabels已更新,所有DispatchGroups()已更新等时,只有这样,我才想重新加载UILabels

我希望有人可以指出正确的方向,以便我可以进一步提高用户体验。谢谢!

1 个答案:

答案 0 :(得分:1)

DispatchGroups用于一起执行一堆异步任务,并且需要在所有任务完成时得到通知,但是当前您不执行此操作,因为当您收到响应时,它们都在内部同步线程(串行),这意味着重新加载表之前的所有工作都会在重新加载之前发生,因此,如果这对您的UX有意义,那么您可以自由使用dispatch