現在、firebaseのstorageを使ってProfile画像を作っています。
主な使い方は、Firebaseのドキュメントを使って知ることができます。
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")
と変数を持たせれば、画像の取得を楽にすることができます。
はじめに
CocoaPodsでFirebase/Storageをインストールします。
use_frameworks!
pod "Firebase"
pod "Firebase/Storage"
次にFirebase Storageの設定を修正します。
今はAuthorizeしたユーザーしかファイルの読み書きをできないので、誰でもできるように変更します。
画像のアップロード
画像のアップロードは、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とerrorを流すため、APIなど 成功したら結果を、失敗したらエラー情報を返す場合
に便利に使えます。