2016-10-10 9 views
0

Firebaseをベースにした簡単なポスト作成プロジェクトを作成しました。私はこのようにFirebaseに投稿を保存します:SwiftはStructure内の変数がオプションであると考えます

let data = UIImageJPEGRepresentation(newPostImageView.image!, 0.5)//Take photo from imageview 
     let metadata = FIRStorageMetadata() 
     metadata.contentType = "image/jpeg"//Define post image path 

     let postId = "\(currentUser.generalDetails.uid)\(NSUUID().uuidString)"//Generate postId 
     let imagePath = "postImages\(postId)/postPic.jpg" 

     storageRef.child(imagePath).put(data!, metadata: metadata) { (metadata, error) in 
      if error == nil { 

       let postRef = self.databaseRef.child("posts").childByAutoId() 


       let post = Post(postImageUrl: String(describing: metadata?.downloadURL()), profileImageUrl: self.currentUser.generalDetails.profileImageURL, postId: postId, content: self.newPostTextView.text, username: self.currentUser.generalDetails.userName) 
       postRef.setValue(post.toAnyObject())  

      }else { 
       print(error!.localizedDescription) 
      } 
     } 
     dismiss(animated: true, completion: nil) 

currentUser.generalDetails. ...は私が持っています。

  1. しかし、それは

私がoptionalsを持っていないので、私は、理由を理解していない

"(https://firebasestorage.googleapis.com/v0/b/オプション" のようなFirebaseに"postImageUrl"を設定します。imagePickerからの画像ですオプション?

+0

なぜ 'String(describe:) 'を使用しますか? 'downloadURL()'はヌル入力可能で、理由は... – Larme

+0

Xcodeが不平を言っていたので、私はそれをしました。そして私にそれをそこに入れるように頼みます。 –

+1

'String(describe:)' *何かを文字列に変換します。通常はコンパイルするための正しい解決策ではありません。 –

答えて

0

if letを使用してブロックのすべての必要条件をアンラップしてテストすると、swiftが最も効果的だと思います。

この例では、ラップされていないイメージURLが空でない文字列として必要です。

これをすべて設定することは可能です。

if let downloadUrl = metadata?.downloadURL() { // Unwrap the URL. 
    if let imageUrl = downloadUrl.absoluteString { // URL as a string. 
     if !imageUrl.isEmpty { // URL must not be empty. 
     } 
    } 
} 

幸いにも、これはすべて1行で行うことができます。

if let imageUrl = metadata?.downloadURL()?.absoluteString, !imageUrl.isEmpty { 
} 

これは、以下のとおりです。

storageRef.child(imagePath).put(data!, metadata: metadata) { (metadata, error) in 
    if let imageUrl = metadata?.downloadURL()?.absoluteString, !imageUrl.isEmpty { 
     let postRef = self.databaseRef.child("posts").childByAutoId() 

     let post = Post(postImageUrl: imageUrl, 
         profileImageUrl: self.currentUser.generalDetails.profileImageURL, 
         postId: postId, 
         content: self.newPostTextView.text, 
         username: self.currentUser.generalDetails.userName) 

     postRef.setValue(post.toAnyObject())  
    } else if error != nil { 
     print(error!.localizedDescription) 
    } else { 
     print("Unknown error") 
    } 
} 

最後に、guardステートメントを使用して早期に終了することができます。これにより、コードのメインラインのインデントレベルが低くなります。

storageRef.child(imagePath).put(data!, metadata: metadata) { (metadata, error) in 
    guard let imageUrl = metadata?.downloadURL()?.absoluteString, !imageUrl.isEmpty else { 
     print(error?.localizedDescription ?? "Unknown error") 
     return 
    } 

    let postRef = self.databaseRef.child("posts").childByAutoId() 

    let post = Post(postImageUrl: imageUrl, 
        profileImageUrl: self.currentUser.generalDetails.profileImageURL, 
        postId: postId, 
        content: self.newPostTextView.text, 
        username: self.currentUser.generalDetails.userName) 

    postRef.setValue(post.toAnyObject())  
} 
+0

うわー..ありがとう。それはうまくいった。ミニチュートリアルといくつかのヒントをありがとう。そして、それは物事を強制するのではなく、良いことです。しかし、第2の問題は依然として空中である。何らかの理由で、私がプロファイルviewcontrollerに行っていなければ、ユーザの値は空文字列だと思っています。あなたはこれについての修正を知っていますか? –

0

試行: -

let metaURLString = "\(metaData!.downloadURL())" 

     if metaURLString != "" { 

      let post = Post(postImageUrl: metaURLString, profileImageUrl: self.currentUser.generalDetails.profileImageURL, postId: postId, content: self.newPostTextView.text, username: self.currentUser.generalDetails.userName) 
      postRef.setValue(post.toAnyObject()) 

     } 
+0

少なくとも私にとっては同じです。しかし、私は次のように修正しました。 'let downloadUrl = metadata!downloadURL()'を 'postImageUrl:(downloadUrl?.absoluteString)! 'に設定してください。 しかし、問題は、usernameとuser profileのイメージを何らかの理由で。 –

関連する問題