我正在进行网络呼叫,获取数据,并希望通过向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后出现此问题
这是一个理想的行为,api调用是异步的,它不会立即返回任何内容。因此,在Web服务返回结果之前,数组计数将为零。
更改您的init方法,如:
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()
}