[ios] FirebaseStorageの使い方・Singleを使って実装する。
現在、firebaseのstorageを使ってProfile画像を作っています。
主な使い方は、Firebaseのドキュメントを使って知ることができます。
はじめに
CocoaPodsでFirebase/Storageをインストールします。
use_frameworks! pod "Firebase" pod "Firebase/Storage"
次にFirebase Storageの設定を修正します。 今はAuthorizeしたユーザーしかファイルの読み書きをできないので、誰でもできるように変更します。
FirebaseはStorageは、Pathを Storage.storage().reference()
にchildを使って指定します。
child("a").child("b")
と書くとaの中のbに画像が保存されます。
今回は、UserProfileを保存したいので、pathは .child("users").child("profile")
とします。
let ref = Storage.storage().reference().child("users").child("profile")
と変数を持たせれば、画像の取得を楽にすることができます。
画像のアップロード
画像のアップロードは、setData
と言う関数を用いることで使用することができます。
setDataの引数には、保存したい画像のData型とmetaDataを渡します。
metadataは、以下のURLで確認してください。
https://firebase.google.com/docs/storage/ios/file-metadata?hl=ja
基本は、nilで大丈夫です。
以下で、UIImageからData型に直すことができます。
0.3と言う数字は、画質に関する情報なのですが、容量の重い画像だとアップロードに時間がかかるので比較的小さい数字でいい気がします。
let imageData = myProfile.jpegData(compressionQuality: 0.3)
戻り値は、metadataとerrorが帰ってくるので、ハンドリングすれば終わりです。
つい数ヶ月前までは、metadata?.downloadURL()
で保存先のURLを取得できたのですが現在は使えないようです。
以下がアップロードの処理です。
func uploadUserProfile(imageData: Data) -> Single<Void> { let ref = Storage.storage().reference().child("users").child("profile") return Single.create { observer in ref.putData(imageData, metadata: nil) { metadata, error in if let error = error { observer(.error(error)) return } observer(.success(())) } return Disposables.create() } }
画像のダウンロード
ダウンロードには、Data型とURLで取得する2通りの取得方法があります。
Data型で取得する。
Data型は、getDataで取得することができます。引数に、画像のサイズ ' maxSize 'を書きます。
ドキュメントには、1 * 1024 * 1024
と書いてありました。
そして、引数には data
と error
が帰ってきます。
func downloadUserProfile() -> Single<Data> { let ref = Storage.storage().reference().child("users").child("profile") return Single.create { observer in ref.getData(maxSize: 1 * 1024 * 1024, completion: { data, error in if let error = error { observer(.error(error)) return } guard let data = data else { fatalError() } observer(.success(data)) }) return Disposables.create() } }
URL型で取得する
現在のプロダクトは、Kingfisherで画像をキャッシュしているのでURLで取得しています。
URLかたで受け取るには、downloadURLで取得でき、引数は必要ありません。
引数には URL
と error
が帰ってきます。
func downloadProfileURL() -> Single<URL> { let ref = Storage.storage().reference().child("users").child("profile") return Single.create { observer in ref.downloadURL(completion: { url, error in if let error = error { observer(.error(error)) return } guard let url = url else { fatalError() } observer(.success(url)) }) return Disposables.create() } }
Singleを使うと、流れてくる最初の値のみを流しsuucessとerro
rを流すため、APIなど 成功したら結果を、失敗したらエラー情報を返す場合
に便利に使えます。