Passion+Action+Sincerely=Success!

週末にのみ趣味でコーディングするおやじの備忘録

Swift版 AFNetworkingのAlamofireを使ってみたぜ!

毎週末のジョギングを終えて、ビール片手に、前回以下で投稿した生NSURLSessionを使って実装したサーチプログラムを、Alamofireフレームワークを使って、書き換えてみた。

iTuneStoreのWeb serviceであるSearch APIを使ってみた - Passion+Action+Sincerely=Success!

まず、Alamofireフレームワークを以下からダウンロードする。

Alamofire/Alamofire · GitHub


プロジェクトへの組み込み方は、以下のエントリーを参考にしたよ。

Beginning Alamofire Tutorial - Ray Wenderlich


このサーチプログラムでは、大きく2箇所で、NSURLSessionを使っているので、これらをAlamofireを使って書き換えるよ。


(1) 検索バーに入力されたテキストをもとに実際のサーチ処理を実行するperformSearch()関数を以下のように書き換えた。

ここで何気に重要なのが、dataRequestこれは、Alamofire.Requestクラスのオブジェクトだ。サーチ中に、別のサーチが実行された場合は、dataRequest?.cancel()で、実行中の処理をキャンセルすることができる。

    func performSearch() {
       
        if !searchBar.text.isEmpty {
            
            searchBar.resignFirstResponder()
            dataRequest?.cancel()
            
            //ダウンロード中は、ActivityIndicatorを表示する
            isLoading = true
            tableView.reloadData()
            
            hasSearched = true
            searchResults = [SearchResult]()
            
            //検索バーに入力されたテキストから、SearchAPIコール用のurlを作成する
            let url = self.urlWithSearchText(searchBar.text, category: segmentedControl.selectedSegmentIndex)
            
            dataRequest = Alamofire.request(.GET, url, parameters: nil).responseJSON() { _, response, data, error in
                
      //SearchAPIのレスポンスが返ってきたらここが呼ばれる。
                if error == nil {
                    if let response = response {
                        if response.statusCode == 200 {
                            if let dictionary = data as? [String: AnyObject] {
                                
                                self.searchResults = self.parseDictionary(dictionary)
                                self.searchResults.sort(<)
                                //メインスレッドで、サーチ結果を表示する。
         // ActivityIndicatorを非表示にすることも忘れずにね!
                                dispatch_async(dispatch_get_main_queue()) {
                                    self.isLoading = false
                                    self.tableView.reloadData()
                                }
                                return
                            }
                            
                        }
                    }
                }
                
                dispatch_async(dispatch_get_main_queue()) {
                    self.hasSearched = false
                    self.isLoading = false
                    self.tableView.reloadData()
                    self.showNetworkError()
                }
            
            }
        }
    }

(2) もう一箇所は、Search結果で入手したImageデータが置いてあるURLからImageデータをダウンロードする部分だ。これはUIImageViewのextensionとして実装してあり、以下のように書き換えた。

import Foundation
import UIKit
import Alamofire

extension UIImageView {
    
    func loadImageWithURL(url: NSURL) -> Request {
        var fileName: String?
        var finalPath: NSURL?
        
        let request = Alamofire.download(.GET, url, { (temporaryURL, response) in
            
     /*この部分で、ダウンロードされたファイルが格納されたローカルファイルのフルパスをreturnするコードを書く。*/

            if let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as? NSURL {
                fileName = response.suggestedFilename!
                finalPath = directoryURL.URLByAppendingPathComponent(fileName!)
               
                return finalPath!
            }
            return temporaryURL
            
        }).response { (request,response, data, error) in
                        
    /* この部分で、ローカルファイルからImageデータを取り込むコードを書く*/
            if let response = response {
                if response.statusCode == 200 && finalPath != nil {
                    if let data = NSData(contentsOfURL: finalPath!) {
                            
                        if let image = UIImage(data: data) {
                            dispatch_async(dispatch_get_main_queue()) {
                                self.image = image
                            }
                        }
                    }
                }
            }
        }

        return request
        
    }
}

上記では、loadImageWithURL関数の中で、Alamofire.Requestオブジェクトを返却している。これも重要だ。例えば、スクロールして、現在のダウンロード処理が不要になった場合は、キャンセルが必要になる。そのために、requestオブジェクトをreturnしている。

Alamofireは、なんか直感的に書けて、とってもモダンで、なんかとってもいい感じだ。俺もビール片手に酔っ払って、なんかとってもいい感じになってきたぜ!

Swiftで検索すると、やっぱり、テイラースイフトだらけになった(前と同じ結果)よ。

f:id:diinosimple:20141214183602p:plain
f:id:diinosimple:20141214183616p:plain

今後も積極的にAlamofireを使って通信周りのコードを書いてみようと思う。