追記
サンプルプロジェクトをBitBucketにあげているので良かったらみてください。
また、Firebase上からはすでにプロジェクトを削除しているので動作はしません。
自身のものと置き換えてから実験などどうぞ
https://bitbucket.org/nnsnodnb/firebasestoragesample/src
環境
- OSX 10.11.6
- Xcode 8
- CocoaPods 0.39.0
- iOS 10.0.1 (iPhone5)
準備
- Xcodeの新規プロジェクトを作成及びFirebaseコンソールでのアプリ登録
- Firebaseのプロジェクト適用
上記は済ませている前提で
ちなみにPodfileは以下
use_frameworks!
target 'Sample' do
pod 'Firebase'
pod 'Firebase/Storage'
end
Firebase Storageの設定
まずはルールから設定します。デフォルトの設定だと、認証をしているユーザしかファイルアップロードができない設定のようです。
今回は私なりに適当に設定したルールを置いておきます。
service firebase.storage {
match /b/<YOUR-GS-URL>.appspot.com/o {
match /{allPaths=**} {
allow read:if request.auth != null;
allow write;
}
}
}
また、ルール作成の手助けになったサイトは以下です。感謝!!
https://groups.google.com/forum/#!topic/firebase-talk/WCShGLoRO2I
意味合いとしては read
には認証がいる。 write
は誰でもできる!と言った感じ。
今回はアップロードのみなので write
は認証なしでOKにしました。
また、以下のようにすると認証なしで誰でも読み書きが可能になります。
service firebase.storage {
match /b/<YOUR-GS-URL>.appspot.com/o {
match /{allPaths=**} {
allow read, write
}
}
}
実装
画面自体はこんな感じのボタンがあるだけのものです。
今回は、カメラロールから画像を選択してそれをアップロードしてみます。
iOS10で実装を行ったため、 Info.plist
にカメラロール使用許可を求めるものを設定しました。
Privacy - Photo Library Usage Description
を追加してそれっぽいものを追加しておきましょう!
実際にカメラロールにアクセスするときにこんな感じにアラートが表示されます!
実際に使ったソースコードは以下
import UIKit
import Firebase
import FirebaseStorage
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let ud = UserDefaults.standard
ud.set(0, forKey: "count")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func selectImageWithLibrary(_ sender: AnyObject) {
pickImageFromLibrary()
}
func countPhoto() -> String {
let ud = UserDefaults.standard
let count = ud.object(forKey: "count") as! Int
ud.set(count + 1, forKey: "count")
return String(count)
}
}
// MARK: UINavigationControllerDelegate
extension ViewController: UINavigationControllerDelegate {
func pickImageFromLibrary() {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) {
let controller = UIImagePickerController()
controller.delegate = self
controller.sourceType = UIImagePickerControllerSourceType.photoLibrary
present(controller, animated: true, completion: nil)
}
}
}
// MARK: UIImagePickerControllerDelegate
extension ViewController: UIImagePickerControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo
info: [String : Any]) {
let storage = FIRStorage.storage()
let storageRef = storage.reference(forURL: "gs://<YOUR-GS-APP>.appspot.com")
if let data = UIImagePNGRepresentation(info[UIImagePickerControllerOriginalImage] as! UIImage) {
let reference = storageRef.child("image/" + NSUUID().uuidString + "/" + countPhoto() + ".jpg")
reference.put(data, metadata: nil, completion: { metaData, error in
print(metaData)
print(error)
})
dismiss(animated: true, completion: nil)
}
}
}
流れ
- UserDefaultsに
0
を追加。(起動時に毎回呼ばれる...これは各自修正お願いします) - 「アップロードする」ボタンを押下する。
- アクセス許諾アラートが表示される。(OKだった前提)
- フォトライブラリ(カメラロール)から任意の画像を選ぶ。
- UIImagePickerControllerDelegateによってFirebase Storageにアップロードする準備をする。
- UserDefaultsからファイルアップロード回数を確認しそれとUUIDをフォルダ構成をしてアップロードをする。
完全なものにしたいのであれば UserDefaults
ではなく Keychain
を使ってカウントをしていくのがいいと思います。
結果
カレントディレクトリの下に image/<UUID>/[0-9].jpg
の形で保存することができました!
最後に
Firebase Storageのアップロード容量がいくらか忘れてしまったのですが(誰か教えてください)、これを使えば簡単な共有アプリとか作れそうですね!