2016-07-17 15 views
4

は、私はファイルをアップロードしようとした2つの方法があります。:ここでは、ファイル「ファイル名は」開くことができませんでしたエラー

1.

getURLOfPhoto(assetURL: imagesDictionary[String(whichProfileImage)]! , completionHandler: { (responseURL) in   
            FIRStorage.storage().reference().putFile(responseURL as! URL) 
          }) 

2.

let assets = PHAsset.fetchAssets(withALAssetURLs: [imagesDictionary[String(whichProfileImage)] as! URL], options: nil) 
      let asset = assets.firstObject 
      asset?.requestContentEditingInput(with: nil, completionHandler: { (contentEditingInput, info) in 
       let imageFile = contentEditingInput?.fullSizeImageURL? 

       FIRStorage.storage().reference().child("test").putFile(imageFile!, metadata: nil) { (metadata, error) in 
         if let error = error {     
          return 
         } 
       } 
      }) 

私はこのエラーを取得しています:

Body file is unreachable: /var/mobile/Media/DCIM/100APPLE/picture.JPG   
    Error Domain=NSCocoaErrorDomain Code=257 "The file “picture.JPG” couldn’t be opened because you don’t have permission to view it."  
     UserInfo={NSURL=file:///var/mobile/Media/DCIM/100APPLE/picture.JPG, NSFilePath=/var/mobile/Media/DCIM/100APPLE/picture.JPG,  
    NSUnderlyingError=0x15da49a0 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}} 

URLが正常に取得されているようですが、エラーはputFile()メソッドが呼び出されたときにのみ発生します。

このエラーやファイル(Dataオブジェクトではない)をFirebase Storageにアップロードする方法を知っている人はいませんか?事前

+0

アプリがクラッシュするか、エラーログに記録されますか?あなたにそれを見る権限がないと言うなら、私はFirebaseの設定で確認します。 – Echizzle

+0

ご回答ありがとうございます。アプリはクラッシュしないで、エラーを記録するだけです。私のFirebaseストレージルールは 'allow read、write:if request.auth!= null || request.auth == null; 'であるため、Firebaseの読み取り/書き込みアクセス権によってStorage Databaseに書き込むことができます。 –

答えて

4

現在Firebaseストレージは、私が使用PHAssetベースのコードを使用して取得されたファイルのURLを使用することができません自分のiPhoneでカメラで撮影したファイルであっても、私の質問(または少なくとも私の経験ではそれはできませんでした)。そのため、問題のファイルをFirebase Storage APIにアクセス可能な場所に再保存してから、その場所のURLをputFile()メソッドに渡してファイルをアップロードしてください。あなたはimagePickerController()メソッドを使用している場合

あなたは、このメソッドを使用することができます。

do { 
    let documentsURL = FileManager.default().urlsForDirectory(.documentDirectory, 
                      inDomains: .userDomainMask)[0] 
    let fileURL = try documentsURL.appendingPathComponent("fileName.jpg") 

    let image = info[UIImagePickerControllerOriginalImage] 

    try UIImageJPEGRepresentation(image as! UIImage,1.0)?.write(to: fileURL, options: []) 

        FIRStorage.storage().reference().child("exampleLocation") 
         .putFile(fileURL, metadata: nil) { (metadata, error) in 
    if let error = error { 
           print("Error uploading: \(error.description)") 
           return 
          } 
         }     
       } 
     catch { 
      print("error is ", error) 
     } 
+0

あなたに感謝して、私の時間を節約しました! – mehmetsen80

+0

ただし、ドキュメントのURLの前に試す必要はありません。 let fileURL = documentsURL.appendingPathComponent( "fileName.jpg") – mehmetsen80

1

おかげで私たちのアップローダーが原因アプリのサンドボックスに、そのファイルにアクセスするための適切な権限を持っていない(と私たちは広範囲のファイルシステムへのアクセス権限を付与するにはかなり躊躇している)ことが可能です。それは、システムリソースから来る場合

私だけDocuments/tmp/確か

https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.htmlあたりに格納したファイルをお勧めします、私たちはその行動を再訪したい場合があります。通常、私は(はい、私はそれが代わりに filedata知っているので、より悪いメモリの動作を持っています)を実行します。

// pragma mark - UIImagePickerDelegate overrides 
    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { 

    // Get local image 
    guard let image: UIImage = info[UIImagePickerControllerOriginalImage] as? UIImage else { return } 
    let imageData = UIImagePNGRepresentation(image)! 

    // Get a reference to the location where we'll store our photos 
    let photosRef = storage.reference().child("chat_photos") 

    // Get a reference to store the file at chat_photos/<FILENAME> 
    let photoRef = photosRef.child("\(NSUUID().UUIDString).png") 

    // Upload file to Firebase Storage 
    let metadata = FIRStorageMetadata() 
    metadata.contentType = "image/png" 
    photoRef.putData(imageData, metadata: metadata).observeStatus(.Success) { (snapshot) in 
     // When the image has successfully uploaded, we get it's download URL 
     let text = snapshot.metadata?.downloadURL()?.absoluteString 
    } 

    // Clean up picker 
    dismissViewControllerAnimated(true, completion: nil) 
    } 
+0

お返事ありがとうございます。 URLはimagePickerController()を使用して選択した画像で、Firebaseがその種のURLにアクセスすることは妥当ではないでしょうか?私のアプリはマルチプラットフォーム(Android&iOS)で、Android APIのputBytes()メソッドを使用してFirebase Storageに保存されたiOSアプリに画像を表示できませんでしたので、AndroidとiOSデータベース内の同じ画像を取得できるアプリケーションファイルを使用する必要があります。したがって、putData()を使用すると、アプリのオプションにならない場合があります。または、イメージを複数のプラットフォームでファイルとして保存せずに利用できるようにすることはできますか? –

+1

ユーザーの同意なしに(または開発者の知識なしに)任意の写真をアップロードすることを可能にすることは、巨大な潜在的なセキュリティ脆弱性のようです。あなたの個人的な写真をすべて真空にするアプリケーションをインストールし、あなたが知らないうちにWebサーバーにアップロードすると想像してください。 –

+1

2番目の場合:メモリとファイルのアップロードの間に互換性の観点から違いはありません。つまり、1日の終わりに、Androidの携帯電話からメモリまたはファイルからJPGをアップロードすると、サーバー上でファイルを保存/保存するのではなく、JPGやPNGなどのイメージタイプ間で変換する問題があるように私には聞こえます。 –

0

@マイクマクドナルドは、あなたの答えのためのおかげで、それは私のために働きました。私はまったく同じ問題を抱えていて、あなたの提案で解決することができました。ここに私のコードです:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { 

    guard let image: UIImage = info[UIImagePickerControllerOriginalImage] as! UIImage else { return } 
    let profileImageName = "profileImageName.png" 
    let imageData = UIImagePNGRepresentation(image)! 
    let filePath = "\(FIRAuth.auth()!.currentUser!.uid)/\(Int(NSDate.timeIntervalSinceReferenceDate() * 1000))" 

    let photoStorageRef = FIRStorage.storage().reference().child(filePath) 
    let photoRef = photoStorageRef.child("\(profileImageName)") 

    let metadata = FIRStorageMetadata() 
    metadata.contentType = "image/png" 

    photoRef.putData(imageData, metadata: metadata) { metadata, error in 
     if let error = error { 
      print("Error uploading:\(error.localizedDescription)") 
      return 
     } else { 
      guard let downloadURL = metadata!.downloadURL() else { return } 
      guard let downloadURLString = metadata!.downloadURL()?.absoluteString else { return } 

      //do what I need to do with downloadURL 
      //do what I need to do with downloadURLString 
     } 
    } 

これは、誰かが同じ問題を抱えていることを願っています!

関連する問題