検索に入力するとムービーの結果をプルアップするアプリがあります。 (IMDbのように)themoviedb.orgの無料APIを使用して結果を読み込みます。私はそれらをTableViewControllerにロードします。 .dataTaskWithRequestメソッドのmodを使用して結果のポスターを読み込みます。それを同期させる。それ以外は、映画やテレビ番組のタイトル、ジャンル、年の基本的なAPIの送受信です。遅れのためTableViewControllerの検索結果が正しく読み込まれない
私は速すぎて入力すると遅くなりますが、は完全にではありません。同期ロードのために画像が読み込まれずに画像が読み込まれてもアプリが遅れます。今これは問題ですが、問題は、アプリが単語を画面に読み込んで遅れをとったときに、結果が画面上にある単語の一部の結果です。たとえば、「The Simpsons」と入力すると速すぎると「The Sim」の結果が表示されますが、一度バックスペースして「The Simpsons」を再入力すると結果が正しく読み込まれます。物事をさらに複雑にするものは、時にはトップ結果が古い、部分的な結果の1つになることがあり、残りは正常であり、下にロードされるということです。
Here is a video状況を説明します。私が初めて「シンプソンズ」を打つと、あなたは遅れを見ることができます。私はそれをすべて本当に速く入力しましたが、単語 "the"より遅れています。読み込みが完了すると、存在しないはずのベオウルフ結果が読み込まれます。何が起こっているのか分かりません。イメージをロードせずに入力が遅くならない場合でも、の結果はに更新されません。
ここに関連するコードスニペットがあります。ご希望の場合は、お気軽にお問い合わせください。私は一度にあまりにも多くのコードであなたを砲撃したくない:
テキストは検索バーに入力されているときに、検索結果を更新:
extension SearchTable : UISearchResultsUpdating {
func updateSearchResultsForSearchController(searchController: UISearchController) {
//To Handle nils
var searchBarText = searchController.searchBar.text
if (searchBarText == nil) {
searchBarText = ""
}
searchBarText! = searchBarText!.condenseWhitespace()
//To Handle Disallowed Characters
searchBarText = searchBarText!.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
//Find Results from themoviedb
let urlString = "https://api.themoviedb.org/3/search/multi?query=" + searchBarText! + "&api_key= (I can't post the api key publicly online, sorry)"
let results = NSURL(string: urlString)
if (results == nil) {
//Server Error
}
//Wire Up Results with matchingItems Array
let task = NSURLSession.sharedSession().dataTaskWithURL(results!) { (data, response, error) -> Void in
if let jsonData = data {
do {
let jsonData = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers)
if var results = jsonData["results"] as? [NSDictionary] {
if results.count > 0 {
//Clean out non-english results:
//I wrote the function, it shouldn't be the source of the lag, but I can still provide it.
self.cleanArray(&results)
self.matchingItems = results
} else {
self.matchingItems = []
}
}
} catch {
//JSON Serialization Error
}
}
}
task.resume()
self.tableView.reloadData()
}
}
その後、私は結果を取得した後、私はリロードTableViewDataSourceの2つの必要なメソッドを使用してテーブルを作成します。
//Table Data Source
extension SearchTable {
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return matchingItems.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell")! as! CustomCell
//Safe-Guard. This shouldn't be needed if I understood what I was doing
if (indexPath.row < matchingItems.count) {
cell.entry = matchingItems[indexPath.row] //404
//Name & Type & Year
//This is only for TV Shows, I removed the rest for simplicity
cell.title.text = matchingItems[indexPath.row]["name"] as? String
cell.icon.image = UIImage(named: "tv.png")
let date = (matchingItems[indexPath.row]["first_air_date"] as? String)
cell.year.text = date == nil ? "" : "(" + date!.substringToIndex(date!.startIndex.advancedBy(4)) + ")"
//Genre
//Code here removed for simplicity
//Poster
cell.poster.image = UIImage(named: "Placeholder.jpg")
if let imagePath = matchingItems[indexPath.row]["poster_path"] as? String {
let url = NSURL(string: "http://image.tmdb.org/t/p/w185" + imagePath)
let urlRequest = NSURLRequest(URL: url!)
let session = NSURLSession.sharedSession()
//Synchronous Request
let semaphore = dispatch_semaphore_create(0)
let task = session.dataTaskWithRequest(urlRequest) { data, response, error in
if let poster = UIImage(data: data!) {
cell.poster.image = poster
}
dispatch_semaphore_signal(semaphore)
}
task.resume()
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
}
}
return cell
}
}
ありがとう!
これは完璧です!検索の絞り込みはまさに私が望んでいたものです!どうもありがとうございます!! また、画像を読み込まなくても検索結果がまだバグだった理由がわかりました。私が検索するたびに、非同期に行われたので、検索が完了する前にテーブルがリロードされることがありました。 [これは私の多くを助けた](http://stackoverflow.com/questions/35421631/in-swift-tableview-data-loaded-from-json-only-loads-80-of-the-time) 両方を使用するこれらのうち、私はこれを解決することにかなり自信があります。ありがとうありがとう!これは3日間私を困らせている! – QuantumHoneybees
ちょうど質問ですが、BondとRxSwiftは正確に何をしていますか?私はドキュメントを開き、彼らが私を助けるためにできることを本当に理解できませんでした... – QuantumHoneybees
Well Bondはデータバインディングを行うライブラリに過ぎず、例えばAppleが提案したデフォルトのクラシックMVCの代わりにMVVMパターンを採用することができます。ボンドではスロットルを操作できます。 RxSwiftはReactive Programmingと呼ばれる別のコンセプトを採用するライブラリですが、RxSwiftの紹介が本当にうまくいけば、この記事をお勧めします。http://www.thedroidsonroids.com/blog/ios/rxswift-by-examples -1-the-basics/ –