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

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

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

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

解決済

1回答

1418閲覧

エラーコード(Value of type 'StorageMetadata' has no member 'downloadURL')を解消したい.

mansan

総合スコア11

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

0クリップ

投稿2019/10/28 14:09

前提・実現したいこと

現在、Udemyでインスタグラムのクローンを作っています。(教材ページ)
しかし、Xcodeのバージョンが古いため、たくさんエラーが発生しました。そこで現在はXcode10.1にバージョンを下げてプロジェクトを作っています。Swiftのバージョンは4.2です。

FireBaseでプロフィール画像を設定するところまでなんとか進みましたが、解消できないエラーが起こりました。

発生している問題・エラーメッセージ

以下のコードを入力したら、 guard let profileImageURL = metadata?.downloadURL()?.absoluteString else { return } 次のようなエラーが起こる! Value of type 'StorageMetadata' has no member 'downloadURL'

該当のソースコード

Swift

1 2import UIKit 3import Firebase 4 5class SignUpVC: UIViewController,UINavigationControllerDelegate, UIImagePickerControllerDelegate{ 6 7 var imageSelected = false 8 9 10 let plusPhotoBtn: UIButton = { 11 let button = UIButton(type: .system) 12 button.setImage(#imageLiteral(resourceName: "plus_photo").withRenderingMode(.alwaysOriginal),for: .normal) 13 button.addTarget(self, action: #selector(handleSelectProfilePhoto), for: .touchUpInside) 14 return button 15 }() 16 17 let emailTextField: UITextField = { 18 let tf = UITextField() 19 tf.placeholder = "Email" 20 tf.backgroundColor = UIColor(white: 0, alpha: 0.03) 21 tf.borderStyle = .roundedRect 22 tf.font = UIFont.systemFont(ofSize: 14) 23 tf.addTarget(self, action: #selector(formValidation), for: .editingChanged) 24 return tf 25 }() 26 27 let passwordTextField: UITextField = { 28 let tf = UITextField() 29 tf.placeholder = "Password" 30 tf.isSecureTextEntry = true 31 tf.backgroundColor = UIColor(white: 0, alpha: 0.03) 32 tf.borderStyle = .roundedRect 33 tf.font = UIFont.systemFont(ofSize: 14) 34 tf.addTarget(self, action: #selector(formValidation), for: .editingChanged) 35 return tf 36 }() 37 38 let fullNameTextField: UITextField = { 39 let tf = UITextField() 40 tf.placeholder = "Full Name" 41 tf.backgroundColor = UIColor(white: 0, alpha: 0.03) 42 tf.borderStyle = .roundedRect 43 tf.font = UIFont.systemFont(ofSize: 14) 44 tf.addTarget(self, action: #selector(formValidation), for: .editingChanged) 45 return tf 46 }() 47 48 let usernameTextField: UITextField = { 49 let tf = UITextField() 50 tf.placeholder = "Username" 51 tf.backgroundColor = UIColor(white: 0, alpha: 0.03) 52 tf.borderStyle = .roundedRect 53 tf.font = UIFont.systemFont(ofSize: 14) 54 tf.addTarget(self, action: #selector(formValidation), for: .editingChanged) 55 return tf 56 }() 57 58 let signUpButton: UIButton = { 59 let button = UIButton(type: .system) 60 button.setTitle("Sign Up", for: .normal) 61 button.setTitleColor(.white, for: .normal) 62 button.backgroundColor = UIColor(red: 149/255, green: 204/255, blue: 244/255, alpha: 1) 63 button.layer.cornerRadius = 5 64 button.isEnabled = false 65 button.addTarget(self, action: #selector(handleSignUp), for: .touchUpInside) 66 return button 67 }() 68 69 let alreadyHaveAccountButton: UIButton = { 70 let button = UIButton(type: .system) 71 72 let attributedTitle = NSMutableAttributedString(string: "Already have an account? ", attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14), NSAttributedString.Key.foregroundColor: UIColor.lightGray]) 73 attributedTitle.append(NSAttributedString(string: "Sign In", attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 14), NSAttributedString.Key.foregroundColor: UIColor(red: 17/255, green: 154/255, blue: 237/255, alpha: 1)])) 74 button.addTarget(self, action: #selector(handleShowLogin), for: .touchUpInside) 75 button.setAttributedTitle(attributedTitle, for: .normal) 76 77 return button 78 }() 79 80 81 82 override func viewDidLoad() { 83 super.viewDidLoad() 84 85 view.backgroundColor = .white 86 87 view.addSubview(plusPhotoBtn) 88 plusPhotoBtn.anchor(top: view.topAnchor, left: nil, bottom: nil, right: nil, paddingTop: 40, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 140, height: 140) 89 plusPhotoBtn.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 90 91 configureViewComponents() 92 93 view.addSubview(alreadyHaveAccountButton) 94 alreadyHaveAccountButton.anchor(top: nil, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 50) 95 96 } 97 98 99 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { 100 101 // selected image 102 guard let profileImage = info[.editedImage] as? UIImage else { 103 imageSelected = false 104 return 105 } 106 107 // set imageSelected to true 108 imageSelected = true 109 110 // configure plusPhotoBtn with selected image 111 plusPhotoBtn.layer.cornerRadius = plusPhotoBtn.frame.width / 2 112 plusPhotoBtn.layer.masksToBounds = true 113 plusPhotoBtn.layer.borderColor = UIColor.black.cgColor 114 plusPhotoBtn.layer.borderWidth = 2 115 plusPhotoBtn.setImage(profileImage.withRenderingMode(.alwaysOriginal), for: .normal) 116 117 self.dismiss(animated: true, completion: nil) 118 } 119 120 121 122 @objc func handleSelectProfilePhoto() { 123 124 // configure image picker 125 let imagePicker = UIImagePickerController() 126 imagePicker.delegate = self 127 imagePicker.allowsEditing = true 128 129 // present image picker 130 self.present(imagePicker, animated: true, completion: nil) 131 132 } 133 134 135 136 @objc func handleShowLogin() { 137 _ = navigationController?.popViewController(animated: true) 138 } 139 140 @objc func handleSignUp() { 141 guard let email = emailTextField.text else { return } 142 guard let password = passwordTextField.text else { return } 143 guard let fullName = fullNameTextField.text else { return } 144 guard let username = usernameTextField.text else { return } 145 146 147 Auth.auth().createUser(withEmail: email, password: password) { (user, error) in 148 // handle error 149 if let error = error { 150 print("Failed to create user with error: ", error.localizedDescription) 151 return 152 } 153 // set profile image 154 guard let profileImg = self.plusPhotoBtn.imageView?.image else { return } 155 156 // upload data 157 guard let uploadData = profileImg.jpegData(compressionQuality: 0.3) else { return } 158 159 // place image in firebase storage 160 let filename = NSUUID().uuidString 161 Storage.storage().reference().child("profile_images").child(filename).putData(uploadData, metadata: nil, completion: { (metadata, error) in 162 163 // handle error 164 if let error = error { 165 print("Failed to upload image to Firebase Storage with error", error.localizedDescription) 166 } 167 168 // profile image url 169 //*エラーコード:Value of type 'StorageMetadata' has no member 'downloadURL' 170 guard let profileImageURL = metadata?.downloadURL()?.absoluteString else { return } 171 172 }) 173 174 } 175 176 177 178 } 179 180 181 182 183 184 185 @objc func formValidation() { 186 187 // ensures that email and password text fields have text 188 guard 189 emailTextField.hasText, 190 passwordTextField.hasText,fullNameTextField.hasText,usernameTextField.hasText,imageSelected == true else { 191 192 // handle case for above conditions not met 193 signUpButton.isEnabled = false 194 signUpButton.backgroundColor = UIColor(red: 149/255, green: 204/255, blue: 244/255, alpha: 1) 195 return 196 } 197 198 // handle case for conditions were met 199 signUpButton.isEnabled = true 200 signUpButton.backgroundColor = UIColor(red: 17/255, green: 154/255, blue: 237/255, alpha: 1) 201 } 202 203 204 205 func configureViewComponents() { 206 207 let stackView = UIStackView(arrangedSubviews: [emailTextField, fullNameTextField, usernameTextField, passwordTextField, signUpButton]) 208 209 stackView.axis = .vertical 210 stackView.spacing = 10 211 stackView.distribution = .fillEqually 212 213 view.addSubview(stackView) 214 stackView.anchor(top: plusPhotoBtn.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 24, paddingLeft: 40, paddingBottom: 0, paddingRight: 40, width: 0, height: 240) 215 } 216 217 218} 219 220 221

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

nakasho_dev

2019/10/28 14:58

Udemyの教材であればUdemyの講師に質問するのが筋なのではないでしょうか?
hameji

2019/10/28 17:13 編集

バージョンを下げて開発を行うのはあまりお勧めできないです。 Xcode, swiftはバージョンアップが割と頻繁なので、 今そのバージョンを使って開発を行っている人は少ないと思います。 なので、その状況を再現して、検証してくれる人は少ないのでは、、、? バージョンの違いによる差はXcode自体から修正方法が示される事もあるので、 慣れれば割と簡単に変換できるようになると思います。
mansan

2019/10/29 01:44

nakasho_devさん Udemyの方で質問しても返信が全く来ないため、こちらで質問しました、、
mansan

2019/10/29 01:53

hamejiさん バージョンを下げなくても、同じエラーが起こりました。 こちらのエラーコードの場合、どのように変換すれば宜しいでしょうか?m(__)m
guest

回答1

0

ベストアンサー

古い教材を使っているのであれば、その教材に合わせたバージョンのXcodeを使うのが正しいと思います。
今の問題は、Firebase SDKのバージョンが上がってdownloadURLを取得する方法が変わっている
ことが原因です。
最新のFirebase SDKを使うのであれば、
https://firebase.google.com/docs/storage/ios/download-files?hl=ja#generate_a_download_url
の「ダウンロード URL を生成する」で説明されている方法で取得する必要があります。

そのUdemyの教材がどのようにしてFirebase SDKをセットアップするよう指示しているのか
わかりませんが、教材で使っているFirebase SDKと同じバージョンのFirebase SDKを
セットアップすれば、教材通りのコードでdownloadURLを取得できると思います。

一番いいのは最新のXcodeと最新のFirebase SDKに対応した教材を使うことだと思います。

投稿2019/10/29 02:10

TakeOne

総合スコア6299

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問