概要
UITableView の UITableViewCell 内に ImageView がありテーブルをスクロールするたびに画像をダウンロードするアプリがありました
Android と同様でセルが表示されるたびに画像をダウンロードしてしまう仕様でかなりいけていませんでした
そんなとき Kingfisher という素晴らしいライブラリに出会いこれがやりたいことを完璧にやってくれたので使い方を紹介します
環境
- macOS 10.12.5
- Xcode 8.3.3 (8E3004b)
- Kingfisher 3.3.3
インストール
Podfile に以下を追記して install するだけです
pod 'Kingfisher'
使いたい .swift ファイルの先頭で import しましょう
import Kingfisher
画像を読み込む
今まで以下のようなコードで UITableViewCell 内の ImageView に画像をダウンロードして設定していました
let imageURL: NSURL? = NSURL(string: img["src"]!)
let req = NSURLRequest(url: imageURL! as URL)
NSURLConnection.sendAsynchronousRequest(req as URLRequest, queue: OperationQueue.main) { (res, data, err) in
let image = UIImage(data: data!)
imageView.image = image
}
これが cellForRowAt メソッドで実装されているためセルが表示されるたびに sendAsynchronousRequest が使われるため無駄に通信を行っていました
これを Kingfisher を使って以下のように書き換えます
imageView.kf.indicatorType = .activity
imageView.kf.setImage(with: URL(string: img["src"]!),
// キャッシュがある場合はキャッシュを使用する
completionHandler: {
(image, error, cacheType, imageURL) in
imageView.image = image
})
まだ画像がダウンロードできていない場合には URL から画像をダウンロードします
そして、ダウンロード中はインジケータを表示します
画像がダウンロードできているセルにスクロールした場合には completionHandler 側がコールされすでにキャッシュされている image を imageView に設定するだけでキャッシュが利用できます
動作確認
アプリをビルドして確認してみましょう
改修前はスクロールするたびに画像をダウンロードするため、回線状況の悪い場合だとセルに正しい画像が表示されなかたり、画像の表示が追いつかなかったりします
Kingfisher を使った改修後はセルをスクロールしまくってもダウンロード中にインジケータが表示されるし、ダウンロードが完了した画像はキャッシュから表示してくれるため、画像の表示が遅れたりすることが一切ありません
比較のスクリーンショットがないのが残念ですがかなり快適な感じになると思います
またアプリを kill して再度立ち上げてもキャッシュが残っている状態だったのですでにダウンロード済みの画像に関してはすぐに表示されました
最後に
Swift で Kingfisher を使ってみました
かなり良い感じのライブラリでビックリしました
Swift には他にも同じようなライブラリがあるようで Moa や Vincent, MapleBacon などあるようです
今回 Kingfisher を使ったのは単純に一番人気そうだったので使いましたが他のやつも代用可能だと思います
画像ダウンロード系はもう全部 Kingfisher を使っていこうと思います
0 件のコメント:
コメントを投稿