iOS
Swift
Firebase
FirebaseStorage
FirebaseUI

FirebaseStorageの画像をSDWebImageで表示しようとして詰まった話

目次

  • 自己紹介
  • 最近作ったアプリ Lily
  • Firebase StorageのTips
  • まとめ

自己紹介

  • 筋肉エンジニアとしてSpajamで頭角を表す
  • JX通信社でNewsDigestというニュースアプリを作っています
  • 個人でもアプリ作ります

スクリーンショット 2017-08-28 17.18.25.png


最近作ったアプリ(個人)

ダイエット動画で継続できる!習慣化アプリ-Lily

FullSizeRender 4.jpg

https://itunes.apple.com/jp/app/id1261813918?mt=8


Firebase


Firebaseを使う理由

  • 個人開発なのでmBaas
  • RealtimeDatabaseなのでFirebase
  • Cloud Functionでプッシュ通知打てそうなのでFirebase

しかし、画像の処理で少し詰まる。。。


いつもやる画像処理

imageView.sd_setImage(with: thumbnailUrl)

FirebaseStorageではこれができなかった


理由

  • ファイルのダウンロードURLしかわからない

Firebase Console

スクリーンショット 2017-08-28 17.34.10.png


スクリーンショット 2017-08-28 17.34.55.png


ダウンロードURLを叩いてみると

スクリーンショット 2017-08-28 17.37.17.png

https://firebasestorage.googleapis.com/v0/b/lily-ios-debug.appspot.com/o/profile%2FazUN6bPT6DwWyq1BIybPsDzE0fd52.jpeg?alt=media&token=0686826a-6c62-4886-92d7-86d2425d51c9

jpgファイルがダウンロードされてしまった。

ちなみにこのURLをSDWebImageの以下でいう thumbnailUrl にセットしても画像が表示されませんでした。。

imageView.sd_setImage(with: thumbnailUrl)

_人人人人人人人人人_
SDWebImageが使えない
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y ̄


しかし、FirebaseUIがあった


FirebaseUI

スクリーンショット 2017-08-28 17.51.08.png

https://github.com/firebase/FirebaseUI-iOS


  • cocoapods
pod 'Firebase/Storage'
pod 'FirebaseUI/Storage'

import Firebase
import FirebaseStorage

static func setImage(uid: String, imageView: UIImageView?){
        let storageRef = Storage.storage().reference()
        let ref = storageRef.child("profile/\(uid).jpg")
        imageView?.sd_setImage(with: ref, placeholderImage: nil)
    }
  • SDWebImageが拡張されていて、firebaseStorageの参照を引数にあげたら、よしなにやってくれる
imageView?.sd_setImage(with: ref, placeholderImage: nil)

ここまでのまとめ

  • SDWebImageネイティブなので、画像の処理方法、それしかない僕
  • FirebaseStorageだとファイルをダウンロードしちゃうURLしかないからいい感じでキャッシュするのは無理かと思ったけど
  • FirebaseUIというライブラリがなんとかしてくれた

追記(ここで急展開)


Twitterの様子


なんやて!?


downloadURLがダメなのではなかった


原因

  • ファイルのタイプが application/octet-stream だったこと

スクリーンショット 2017-08-30 12.38.35.png

この場合のdownloadURLは飛んでみるとわかりますが、ファイルをダウンロードしちゃいます。

https://firebasestorage.googleapis.com/v0/b/lily-ios-debug.appspot.com/o/profile%2FazUN6bPT6DwWyq1BIybPsDzE0fd52.jpeg?alt=media&token=0686826a-6c62-4886-92d7-86d2425d51c9

→ これが image/jpeg になってれば、downloadURLはSDWebImageで使える形になる。


アップロードするときのTips

アップロードするときにやることがあった!

meta.contentTypeを指定する

let ref = storageRef.child(key)
let meta = StorageMetadata()
meta.contentType = "image/jpeg" // <- これ!!
ref.putData(data, metadata: meta) { metadata, error in
    metadata!.downloadURL()! // このURL
}

タイプが image/jpeg になるとFirebase StorageのConsoleに以下のように表示されます。ここで画像も見れるようになるんですね!

スクリーンショット 2017-08-30 20.13.41.png

リンクを押すとダウンロードされずに、そのままブラウザで見れます。

https://firebasestorage.googleapis.com/v0/b/lily-ios-debug.appspot.com/o/profile%2FzUN6bPT6DwWyq1BIybPsDzE0fd52.jpeg?alt=media&token=c9682120-051f-4fac-9a31-81c077f2d08d


ということで

ブラウザでURL叩いても見れた!

これでSDWebImageにurlをセットしていつも通りに画像が見れました!

みなさんご指摘ありがとうございます。Tipsが得られました!


結論

  • firebaseUIを使ってRefで画像を表示してもいいし、
  • アップロード時の指定に注意していつも通りSDWebImageを使って表示することもできる

知って入れば後者の方が簡単な気がします。