質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

3244閲覧

Firebaseで複数画像をStorageに保存した後、Databaseに同じディレクトリに保存したい。

yuga

総合スコア14

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/07/04 16:21

編集2018/07/08 02:05

現在SNSっぽいアプリの開発を行なっており、投稿画面でつまづいています。
Firebaseで複数画像をStorageとDatabaseに保存し、Databaseで1投稿に複数画像を同じ階層に保存するという処理を書きたいです。

ImagePickerを使って、複数画像を取得し、それをFirebaseに送る処理を書いています。以下がコードです。

Swift

1import UIKit 2import ImagePicker 3import ProgressHUD 4import Firebase 5class PostTableViewController: UITableViewController, UITextFieldDelegate { 6 7 var pageCount = 0 8 @IBOutlet weak var selectedimageView: UIImageView! 9 @IBOutlet weak var noteNameTextField: UITextField! 10 @IBOutlet weak var noteDetailTextView: UITextView! 11 @IBOutlet weak var categoryTextField: UITextField! 12 @IBOutlet weak var post_Btn: UIButton! 13 @IBOutlet weak var goPage_Btn: UIButton! 14 @IBOutlet weak var backPage_Btn: UIButton! 15 16 var selectedImages = [UIImage]() 17 18 19 override func viewDidLoad() { 20 super.viewDidLoad() 21 selectedimageView.image = selectedImages[pageCount] 22 print("selectedImages1: (selectedImages)") 23 24 post_Btn.setTitleColor(UIColor.lightText, for: UIControlState.normal) 25 post_Btn.isEnabled = false 26 handleTextDidChanged() 27 } 28 29 override func viewWillAppear(_ animated: Bool) { 30 super.viewWillAppear(animated) 31 handlePhotoChanged() 32 handlePhotoChanged2() 33 } 34 35 36 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 37 38 self.view.endEditing(true) 39 if (noteNameTextField.isFirstResponder) || (categoryTextField.isFirstResponder){ 40 41 noteNameTextField.resignFirstResponder() 42 categoryTextField.resignFirstResponder() 43 } 44 45 } 46 47 48 func handlePhotoChanged(){ 49 guard selectedimageView.image != selectedImages[0] else{ 50 return backPage_Btn.isEnabled = false 51 } 52 backPage_Btn.isEnabled = true 53 } 54 55 func handlePhotoChanged2(){ 56 guard selectedimageView.image != selectedImages.last else{ 57 return goPage_Btn.isEnabled = false 58 } 59 goPage_Btn.isEnabled = true 60 } 61 62 func handleTextDidChanged(){ 63 noteNameTextField.addTarget(self, action: #selector(self.textFieldDidChange), for: UIControlEvents.editingChanged) 64 categoryTextField.addTarget(self, action: #selector(self.textFieldDidChange), for: UIControlEvents.editingChanged) 65 } 66 67 @objc func textFieldDidChange(){ 68 guard let noteName = noteNameTextField.text, !noteName.isEmpty, let category = categoryTextField.text, !category.isEmpty else{ 69 70 post_Btn.setTitleColor(UIColor.lightText, for: UIControlState.normal) 71 post_Btn.isEnabled = false 72 return 73 } 74 post_Btn.setTitleColor(.white, for: UIControlState.normal) 75 post_Btn.isEnabled = true 76 } 77 78 79 @IBAction func canel_touchUpInside(_ sender: Any) { 80 81 dismiss(animated: true, completion: nil) 82 } 83 84 85 @IBAction func goPage_touchUpInside(_ sender: Any) { 86 pageCount += 1 87 selectedimageView.image = selectedImages[pageCount] 88 handlePhotoChanged() 89 handlePhotoChanged2() 90 } 91 92 @IBAction func backPage_touchUpInside(_ sender: Any) { 93 pageCount -= 1 94 selectedimageView.image = selectedImages[pageCount] 95 handlePhotoChanged() 96 handlePhotoChanged2() 97 } 98 99 100 var photoStringDelegate:String? 101 102 @IBAction func post_touchUpInside(_ sender: Any) { 103 //データをまとめてデータベースに投げる処理 104 ProgressHUD.show("Waiting...", interaction: false) 105 for selectedImage in selectedImages { 106 print("selectedImage times: (selectedImage)") 107 108 if selectedImage == selectedImages.first{ 109 if let imageData = UIImageJPEGRepresentation(selectedImage, 0.1) { 110 print("selectedImage[0]: (selectedImage)") 111 let photoIdString = NSUUID().uuidString 112 print("photoIdString[0]: (photoIdString)") 113 photoStringDelegate = photoIdString 114 let storageRef = Storage.storage().reference(forURL: Config.STORAGE_ROOF_REF).child("posts").child("(photoIdString)").child(photoIdString) 115 sendDataTostorage(storageRef: storageRef, imageData: imageData) 116 117 } 118 } 119 120 if selectedImage != selectedImages.first{ 121 if let imageData = UIImageJPEGRepresentation(selectedImage, 0.1) { 122 print("selectedImage[other]: (selectedImage)") 123 let photoIdString = NSUUID().uuidString 124 let storageRef = Storage.storage().reference(forURL: Config.STORAGE_ROOF_REF).child("posts").child(photoStringDelegate!).child(photoIdString) 125 print("photoStringDelegate: (photoStringDelegate)") 126 sendDataTostorage2(storageRef: storageRef, imageData: imageData) 127 } 128 129 } 130 131 } 132 133 } 134 135 func sendDataTostorage(storageRef:StorageReference,imageData:Data){ 136 storageRef.putData(imageData, metadata: nil) { (metadata, error) in 137 if error != nil{ 138 return 139 } 140 storageRef.downloadURL(completion: { (url, error) in 141 if error != nil{ 142 ProgressHUD.showError(error!.localizedDescription) 143 return 144 } 145 if let mainPhotoUrl = url?.absoluteString { 146 sendToDatabase(mainPhotoUrl:mainPhotoUrl,subPhotoUrl:nil) 147 } 148 149 }) 150 } 151 } 152 153 func sendDataTostorage2(storageRef:StorageReference,imageData:Data){ 154 storageRef.putData(imageData, metadata: nil) { (metadata, error) in 155 if error != nil{ 156 return 157 } 158 storageRef.downloadURL(completion: { (url, error) in 159 if error != nil{ 160 ProgressHUD.showError(error!.localizedDescription) 161 return 162 } 163 if let subPhotoUrl = url?.absoluteString { 164 165 sendToDatabase(mainPhotoUrl:nil,subPhotoUrl:subPhotoUrl) 166 } 167 }) 168 } 169 } 170 171 172 173 func sendToDatabase(mainPhotoUrl:String? = nil,subPhotoUrl:String? = nil){ 174 let newPostId = Api.Post.REF_POSTS.childByAutoId().key 175 let newPostReference = Api.Post.REF_POSTS.child(newPostId) 176 177 var dict = [:] as [String:Any] 178 if let mainPhotoUrl = mainPhotoUrl { 179 dict["mainPhotoUrl"] = mainPhotoUrl 180 } 181 if let subPhotoUrl = subPhotoUrl{ 182 dict["subPhotoUrl"] = subPhotoUrl 183 } 184 185 newPostReference.setValue(dict, withCompletionBlock: { 186 (error, ref) in 187 if error != nil { 188 ProgressHUD.showError(error!.localizedDescription) 189 return 190 } 191 ProgressHUD.showSuccess("Success") 192 }) 193 } 194 195} 196

for文を用いて、selectedImages配列に入っている画像を一づつstorage保存しています。現在のコードだとStorageに1投稿ごとの画像を保存することはできています。
以下が三つの画像を保存した際のStorageの画面です。
イメージ説明

しかし、Databaseを見ると一つの画像IDごとに1投稿IDが生成されてしまいます。以下がその画像です。

イメージ説明

理想は以下の構造で保存したいです。

イメージ説明

原因としてはfor文でsendToDatabaseを一回一回呼んでいるため、その度にpostIdが呼ばれてしまっていることが原因だとわかっているのですが、どうしたらpostIdを一回一回呼ばずに複数の画像をDatabaseに保存できるかわかりません。分かる方いらっしゃいましたら教えていただけるとありがたいです。。よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

解決できませんでした。

投稿2018/08/01 09:08

yuga

総合スコア14

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

原因としてはfor文でsendToDatabaseを一回一回呼んでいるため、その度にpostIdが呼ばれてしまっていることが原因だとわかっているのですが、どうしたらpostIdを一回一回呼ばずに複数の画像をDatabaseに保存できるかわかりません。

とのことですが、貼り付けられたコードはsendToDatabaseを呼び出している箇所がどこにもありません。
sendToDatabaseメソッドの内容を見る限り、mainPhotoUrlsubPhotoUrlの2つの引数にURLを入れて呼び出せば、1つの投稿IDの中にmainPhotoUrlsubPhotoUrlの2つのキーが格納される形で保存できていると思います。
(Api.Post.REF_POSTSがなんなのか見えていませんが、おそらくDatabase.database().reference().child("posts")を意味するのだろうと推測しました。)

手書きで書かれている理想の構造は、PostIdの下にsubPhotoUrlという同じキーが2つ存在するようになっていますが、1つのPostIdの中に同じキーを2つ作ることはできません。
1つのフォルダの中に同じ名前のファイルやフォルダを2つ作ることはできないのと同じです。

もうちょっとちゃんと質問しないと、何がしたくてどう困っているのかよくわかりませんが、sendToDatabaseを何回呼び出しても同じ場所に保存できるようにしたいのであれば、

swift

1 let newPostId = Api.Post.REF_POSTS.childByAutoId().key

sendToDatabaseの呼び出し元で実施し、それをプロパティに覚えるなり、sendToDatabaseの引数で渡せるようにするなりして、sendToDatabaseの中の処理は、あらかじめ指定された投稿IDに保存する形にしたらいいと思います。

投稿2018/07/06 07:46

TakeOne

総合スコア6299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問