我正在进行网络呼叫,取回数据,并想通过向tableVC中的var提供数据来将该数据放入tableVC中。我遇到的问题是我的回调返回数据太迟了。下面是我的代码。我真的很感谢任何建议
网络管理员提供的代码
func getArticles(completion: @escaping PListCompletion) {
guard let url = plistUrlString else { return }
let urlRequest = URLRequest(url: url)
let defaultConfig = URLSessionConfiguration.default
let session = URLSession(configuration: defaultConfig)
let task = session.dataTask(with: urlRequest) { (data, response, error) in
do {
if let data = data {
let articles = try PropertyListDecoder().decode([Articles].self, from: data)
self.callBackOnMainThread(completion: completion, response: .success(response: PlistResponseData(results: articles)))
}
} catch {
print(error)
completion(.failure(error: error))
}
}
task.resume()
}
private func callBackOnMainThread(completion: @escaping PListCompletion, response: PlistResponse) {
DispatchQueue.main.async {
completion(response)
}
}
final class ArticleListProvider {
var articles: [Articles]
convenience init() {
self.init(articles: [])
self.provideArticles { (article) in
self.articles.append(contentsOf: article)
}
}
init(articles: [Articles]) {
self.articles = articles
}
func articleCount() -> Int {
//used for tableVC cells but returning 0
return self.articles.count
}
func articleAtIndex(_ index: Int) -> Articles? {
return articles[index]
}
func provideArticles(completion: @escaping ([Articles]) -> Void) {
ArticleDetailsNetworkManager.sharedInstance.getArticles { [weak self] (response) in
guard let weakSelf = self else { return}
switch response {
case .success(let plistData):
weakSelf.articles = plistData.results
case .failure(let error):
print(error.localizedDescription)
}
completion(weakSelf.articles)
}
}
}
tableVC
final class ArticleListController: UITableViewController {
fileprivate let CellIdentifier = "Cell"
fileprivate let articleListProvider: ArticleListProvider
override init(style: UITableViewStyle) {
self.articleListProvider = ArticleListProvider()
super.init(style:style)
}
required init?(coder: NSCoder) {
self.articleListProvider = ArticleListProvider()
super.init(coder: coder)
}
override func viewDidLoad() {
super.viewDidLoad()
setupTableViewCell()
tableView.reloadData()
}
}
extension ArticleListController {
func setupTableViewCell() {
tableView.register(ArticleTableViewCell.self, forCellReuseIdentifier: CellIdentifier)
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//this is returning 0 when it should be returning the amount of articles from the articleProvider, where the networking call is being made
return articleListProvider.articleCount()
}
我不知道这是否重要,但这在Xcode 9.4上有效,(尽管没有回调),升级到10.1后会出现此问题
答案 0 :(得分:3)
这是一种理想的行为,api调用是异步的,不会立即返回任何内容。因此,在该Web服务返回结果之前,数组计数将为零。
更改您的初始化方法,例如:
convenience init(callback: @escaping () -> Void) {
self.init(articles: [])
self.provideArticles { (article) in
self.articles.append(contentsOf: article)
callback()
}
}
并通过以下方式在视图控制器中使用它:
self.articleListProvider = ArticleListProvider{ [weak self]
guard let weakSelf = self else { return}
weakSelf.yourTableView.reloadData()
}