Swiftで遊ぼう! - 704 - Table View 2
- Swiftで遊ぼう!の前書き-> Life-LOG OtherSide
- Swift2.1 & Xcode7.1対応の日本語版アップルチュートリアル!
- Table View実装チュートリアルをXcode7.3で解説
- Core Data シンプルチュートリアル
- 私の本業、オフィシャルなブログ-> Life-LOG
さて、TableViewの勉強をしっかりやろうと思っていたのですが...
Developing iOS 9 Apps with Swift - Free Course by Stanford on iTunes U
非常に重要なフレームワークが手に入らないんです(T_T)
「Twitter Framework」が何処を探してもありません。これが無いとプロジェクトを動かすことができないんです。
フレームワークの扱い方の勉強はできました。Xcodeを使ってワークプレスの扱いも分かったのですが、非力な私はTwitter frameワークを自力で再現することができません(T_T)
いくつかTwitterを扱うフレームワークが用意されていますが、それをパール先生の講義に使えるようにモディファイする力が無いため、Table Viewの講義はデモを実線することができず、眺めるだけになりました。
眺めていても重要な説明がいくつもあります。
まず、フレームワークで扱うメソッドをどのように実装されているのか理解できませんが、使い方は説明しているので、そこから説明を聞きます。
検索したいTweetを探すためのString型のsearchTextを用意します。
var searchText: String? { didSet { tweets.removeAll() searchForTweets() title = searchText } }
tweetsはTweetした内容をArray型の入れ籠のことです。「[Array
searchForTweets()メソッドは、フレームワークで重要なメソッドですが、これを利用するために、searchTextを使った「twitterRequest」変数を用意します。
private var twitterRequest: Twitter.Request? { if let query = searchText where !query.isEmpty { return Twitter.Request(search: query + " -filter:retweets", count: 100) } return nil }
Twitter.Requestも実装できないフレームワークです。このイニシャライザーを使ってリツイートは除外してツイートを100個ダウンロードするリクエストを作ります。
このリクエストを使ってフェッチするので、メインになるsearchForTweets()メソッドは次のようになります。
func searchForTweets() { if let request = twitterRequest { request.fetchTweets( handler: ([Tweet]) -> Void ) } }
「handler: ([Tweet]) -> Void」の所が青くなっています。ここをダブルクリックするとクロージャーに変化します。
func searchForTweets() { if let request = twitterRequest { request.fetchTweets({ ( [Tweet] ) in code }) } }
このように変化して[Tweet]とcodeが青くなります。そしてこれをトレーリングクロージャに変更してやります。
func searchForTweets() { if let request = twitterRequest { request.fetchTweets { ( [Tweet] ) in code } } }
[Tweet]に「newTweets」を与えて、コードを書きます。ここでsearchTweets()メソッドはマルチスレッドでバックグラウンドに入るasyncメソッドなので必ず結果が出るとメインキューに戻す必要があります。
func searchForTweets() { if let request = twitterRequest { request.fetchTweets { newTweets in dispatch_async(dispatch_get_main_queue()) { if !newTweets.isEmpty { self.tweets.insert(newTweets, atIndex: 0) } } } } }
func searchForTweets() { if let request = twitterRequest { request.fetchTweets { [ weak weakSelf = self ] newTweets in dispatch_async(dispatch_get_main_queue()) { if !newTweets.isEmpty { weakSelf?.tweets.insert(newTweets, atIndex: 0) } } } } }
これで完璧! いえいえこれだけじゃ駄目です。このリクエストの実行に時間がかかって、別のリクエストをしてしまっても、古い結果が表示されてしまうというマルチスレッドで基本的な問題の対処をする必要があります。
private var lastTwitterRequest: Twitter.Request? func searchForTweets() { if let request = twitterRequest { request.fetchTweets { [ weak weakSelf = self ] newTweets in dispatch_async(dispatch_get_main_queue()) { if request == weakSelf?.lastTwetterRequest { if !newTweets.isEmpty { weakSelf?.tweets.insert(newTweets, atIndex: 0) } } } } } }
ポール先生の説明は素晴らしいです。実際にデモで確認できないのが辛いのですが、滅茶苦茶重要な話題でした。
今日はここまで。