我正在创建一个tableview,它可以监控来自几个账户的前20条tweet,并按时间顺序显示它们。 它调用Twitter API,然后遍历tweets并将它们添加到TableView中。 我的问题是,当我试图刷新tableview中的数据时,什么也不会发生。 我尝试再次调用getTwitterInfo(),但它不做任何事情,即使有新的tweet要显示。 我试过所有我能在网上找到的东西,但似乎没有什么能解决它。 如有任何帮助,我们将不胜感激--这里是我的视图控制器的代码。
class TwitterViewController: UIViewController {
var tableView = UITableView()
var tweets = [Tweet]()
let cellID = "cellID"
var accounts: [String:String] = [
//this is just a dictionary of the accounts I'm monitoring and their corresponding profile picture
]
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.setNavigationBarHidden(true, animated: false)
configureTableView()
getTwitterInfo()
}
func configureTableView(){
view.addSubview(tableView)
tableView.delegate = self
tableView.dataSource = self
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 150
tableView.register(TweetCell.self, forCellReuseIdentifier: cellID)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
func getTwitterInfo(){
print("getting new info...")
tweets = [Tweet]()
var counter = 1
for (name, pfpLink) in accounts{
let imageURL = URL(string:pfpLink)!
var image = UIImage()
let imageDataTask = URLSession.shared.dataTask(with: imageURL) { (data,response,error) in
image = UIImage(data:data!)!
}
imageDataTask.resume()
let url = URL(string: "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=\(name)&count=20&tweet_mode=extended")!
var request = URLRequest(url: url)
request.allHTTPHeaderFields = ["Authorization": Constants.bearer]
let dataTask = URLSession.shared.dataTask(with: request){ (data,response,error) in
do{
let data = try JSONSerialization.jsonObject(with: data!, options: []) as? [[String:Any]]
let _ = data!.map{
let htmlEncodedString = $0["full_text"] as! String
let message: String
if let newDict = $0["retweeted_status"] as? Dictionary<String,Any>{
let newEncodedString = newDict["full_text"] as! String
message = Constants.decodeTwitterString(newEncodedString)
}else{
message = Constants.decodeTwitterString(htmlEncodedString)
}
let userInfo = $0["user"] as! Dictionary<String,Any>
let screenName = userInfo["screen_name"] as! String
let username = userInfo["name"] as! String
let twitterID = userInfo["id_str"] as! String
let dateString = $0["created_at"] as! String
let tweet = Tweet(name: username, username: screenName, message: message, twitterID: twitterID, image:image, dateString: dateString)
self.tweets.append(tweet)
}
if (counter == self.accounts.keys.count) {
let formatter = DateFormatter()
formatter.dateFormat = "EE LLL dd HH:mm:ss Z yyyy"
self.tweets = self.tweets.sorted{
formatter.date(from: $0.dateString)! > formatter.date(from: $1.dateString)!
}
DispatchQueue.main.async{
self.tableView.reloadData()
}
}
counter += 1
}catch let err{
print(err)
}
}
dataTask.resume()
}
}
}
extension TwitterViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tweets.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) as! TweetCell
let tweet = tweets[indexPath.row]
cell.set(tweet:tweet)
cell.selectionStyle = .none
return cell
}
}
我假设您已经验证了没有从尝试中抛出异常,也没有从强制解包中崩溃。 我认为你应该做的是搬家
DispatchQueue.main.async{
self.tableView.reloadData()
}
到它所在的if块的外部和后面。 我怀疑TableView.reloadData()没有被调用是因为它所在的if块中的条件检查失败。 试试看,如果对你有帮助就告诉我。 如果没有,你可以给我一个链接到你的项目最好是从GitHub。
如果你不想与运行iOS13更低版本的设备向下兼容,谷歌UITableViewDiffableDataSource。 用新的方法做要容易得多,节省了大量的麻烦,特别是当项目变得更加复杂,需要管理许多tableview状态更改时。 如果您想要查看它,这里有一个很好的起点:[https://developer.apple.com/videos/play/wwdc2019/220/][1]