【swift】ちょい足しレシピ⑥!非同期通信で画像を取得し表示させるUIImageViewを作ってみる

もくじ

どうもこんにちは。iOSをメインに開発しているロッキーカナイです。

今日はUIImageViewを継承して、非同期通信で画像を取得し表示してみたいと思います。テーブルセルなんかでよくある、クルクルしてから画像を表示するアレです。といってもAlamofireやAFNetworkingなんかのライブラリを使って簡単に実装できるのですが、標準フレームワークで作ってみたので紹介します。

コード

class UriImageView: UIImageView {
    // タイムアウトの設定
    let TIME_OUT: TimeInterval = 1 * 60
    // インジケータの初期化
    let indicator: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        createIndicator()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        createIndicator()
    }
    
    /// クルクルするインジケータの生成
    func createIndicator() {
        indicator.center = CGPoint(x: self.bounds.midX, y: self.bounds.midY)
        indicator.hidesWhenStopped = true
        self.addSubview(indicator)
    }
    
    /// urlImage
    /// - parameter urlString: 画像url
    /// - returns: nil
    func urlImage(urlString: String){
        // インジケータアニメーションの開始
        indicator.startAnimating()
        
        // URLRequestの生成
        let req = URLRequest(url: NSURL(string:urlString)! as URL,
                             cachePolicy: .returnCacheDataElseLoad,
                             timeoutInterval: TIME_OUT)
        let conf =  URLSessionConfiguration.default
        // URLSessionの生成
        let session = URLSession(configuration: conf, delegate: nil, delegateQueue: OperationQueue.main)
        session.dataTask(with: req, completionHandler:
            { data, resp, err in
                // 通信結果
                if err == nil {
                    // Success
                    let image = UIImage(data:data!)
                    self.image = image
                }else{
                    // Error
                    self.image = UIImage(named: "error")
                }
                // インジケータアニメーションの終了
                self.indicator.stopAnimating()
        }).resume()
    }
}

呼び出し

image.urlImage(urlString: "http://~~~.png")

取得urlがhttpsであればよいのですが、httpで始まるurlの場合はinfo.plistにhttpを使う旨の登録が必要です。


App Transport Security Settings – Dictionary
Allow Arbitrary Loads – Boolean – YES

解説

組み込みたかった動作としては3点です。

  1. 通信中はインジケータ(クルクル)を表示させる
  2. 非同期通信する
  3. 通信エラー時は分かり易いようにエラー画像を表示させる

今回画像を非同期取得をする必要があったので、UIImageViewクラスを継承させて、そこに非同期通信させる制御を追加しました。

サンプル動画

取得成功時の動画です。

エラー時です。

おわり

非同期で取得というと、なんだか難しく感じるかもしれませんが、このように簡単に出来ました。今日のちょい足しは「非同期通信で画像を取得し表示させるUIImageViewを作ってみる」でした。

関連する記事

もっと見る