2016-06-16 2 views
0

:중포 기지 저장 : 아이() iOS 앱 작동하지 않습니다 내 중포 기지 저장 장치에서 이미지를 다운로드하려고 시도 할 때 다음과 같은 오류 받고 있어요

오류 도메인 = FIRStorageErrorDomain 코드 = -13010 "개체 2xxxxxxx8/profile_pic이 (가) 존재하지 않습니다. "

는 (I 분명히 개인 정보를 마스크 거기는 X의를 넣어.) 나는 다음과 같은 코드를 사용하여 내 Firebase Storage 경로 참조를 추가 해요

:

let storage = FIRStorage.storage() 
let storageRef = storage.referenceForURL("gs://project-4xxxxxxxxxxxxx.appspot.com") 
let profilePicReference = storageRef.child(signedInUser.uid + "/profile_pic") 

내가 코드를 알고를 위의 모든 것이 좋은 원인입니다 입니다. 내 저장 공간에 폴더가 추가 된 것을 볼 수 있으며 이미지는 해당 폴더에 업로드되었습니다.이 파일은 모두 내 iOS 앱에서 직접 업로드되었습니다.

내가 Firebase 웹 포털을 통해이 폴더를 수동으로 삭제했을 때 문제가 발생 함 - 모든 작업이 제대로 작동했는지 확인한 후 위의 코드가 필요함을 알리기 위해 폴더를 삭제했습니다. 일단 앱을 다시 실행하면 다시 만들어 낼 것입니다. 그리고 그 이후로 나는이 오류를 반복해서 얻고 있습니다.

정말 말이되지 않습니다.

Firebase Storage에 어떤 이슈가 있습니까? 어떤 종류의 캐싱을 해결해야합니까?

팁을 주시면 감사하겠습니다.

+0

'signedInUser.uid'가 ('String! '에 강요하지 않았기 때문에) 객체로 반환되는 것처럼 보입니다. 잘못된 파일을 가리키고 있습니다. 당신이 올바른 'uid'를 얻고 있고 경로가 실제로 맞는지 확인할 수 있습니까? –

답변

3

Firebase Storage에는 어떤 단점이나 문제가 있습니까? 어떤 종류의 캐싱이 해결되어야합니까?

UploadTaskasynchronously을 실행합니다. 이미지를 업로드 한 직후에 이미지를 다운로드하려고하면 오류가 다시 발생합니다. 이미지의 업로드가 완료되기 전에 다운로드 코드가 실행되어 이미지 존재하지 않는 오류가 발생합니다. 당신은 다운로드 코드는 콜백에 어떤 메시지를 인쇄하여 너무 일찍 실행하는 것을 볼 수 있습니다 :

[My Download Error]: ...."Object images/align_menu.tiff does not exist."... 

후 몇 초 후에 내가 출력을 참조하십시오

let storage = FIRStorage.storage() 
    let storageRef = storage.reference() //You don't need to explicitly write the url in your code. 
             //The config file GoogleService-Info.plist will handle that. 

    let imageRef = storageRef.child("images/align_menu.tiff") 

    let localURL = NSBundle.mainBundle().URLForResource(
     "align_menu", 
     withExtension: "tiff" 
    )! 

    //Upload the image: 
    let uploadTask = imageRef.putFile(localURL, metadata: nil) { (metadata, error) -> Void in 
     if let returnedError = error { 
      // Uh-oh, an error occurred! 
      print("[My Upload Error]: \(returnedError)") 
     } else { 
      // Metadata contains file metadata such as size, content-type, and download URL. 
      print("[My Upload Success]:") 
      let downloadURL = metadata!.downloadURL()! 
      print("[URL for download]: \(downloadURL)") 
     } 

    } 

    //Download the image: 
    imageRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in 
     if let returnedError = error { 
      // Uh-oh, an error occurred! 
      print("[My Download Error]: \(returnedError)") 
     } 
     else { 
      print("[My Download Success]:") 

      if let validImage = UIImage(data: data!) { 
       NSOperationQueue.mainQueue().addOperationWithBlock() { 
        self.imageView.image = validImage 
       } 
      } 
     } 

    } 

그 코드는 출력을 생성합니다 :

[My Upload Success]: 
[URL for download]: ... 

다운로드 콜백이 업로드 콜백 이전에 실행 중임을 보여줍니다. 왜 그런 일이 일어 났는지에 대한 자세한 내용을 알 수는 없지만 분명히 콜백은 직렬 대기열에 추가되지 않습니다. *

비동기 문제를 치료하기 위해, 당신은 몇 가지 옵션이 있습니다 :

1) 가 업로드 코드에 대한 콜백 내부의 다운로드 코드를 넣습니다.

그런 식으로 이미지가 성공적으로 업로드 될 때까지 다운로드가 실행되지 않습니다. 내가 한 후 응용 프로그램을 실행하기 전에 중포 기지 저장 웹 페이지를 사용하여 이미지를 삭제, 내 업로드/다운로드에 더 해로운 영향을 미치지 않으며, 메시지는 예상 된 순서대로 출력했다 :

[My Upload Success]: 
[URL for download]: ... 
[My Download Success]: 

2) 를 부착 . 관찰자를 uploadTask에 연결하십시오.

let storage = FIRStorage.storage() 
    let storageRef = storage.reference() //You don't need to explicitly write the url in your code. 
             //The config file GoogleService-Info.plist will handle that. 

    let imageRef = storageRef.child("images/align_menu.tiff") 

    let localURL = NSBundle.mainBundle().URLForResource(
     "align_menu", 
     withExtension: "tiff" 
    )! 

    //Upload the image: 
    let uploadTask = imageRef.putFile(localURL, metadata: nil) { (metadata, error) -> Void in 
     if let returnedError = error { 
      // Uh-oh, an error occurred! 
      print("[My Upload Error]: \(returnedError)") 
     } else { 
      // Metadata contains file metadata such as size, content-type, and download URL. 
      print("[My Upload Success]:") 
      let downloadURL = metadata!.downloadURL()! 
      print("[URL for download]: \(downloadURL)") 
     } 

    } 


    let observer = uploadTask.observeStatus(.Success) { (snapshot) -> Void in 

     //Download the image: 
     imageRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in 
      if let returnedError = error { 
       // Uh-oh, an error occurred! 
       print("[My Download Error]: \(returnedError)") 
      } 
      else { 
       print("[My Download Success]:") 

       if let validImage = UIImage(data: data!) { 
        NSOperationQueue.mainQueue().addOperationWithBlock() { 
         self.imageView.image = validImage 
        } 
       } 
      } 

     } 

    } 

3) 사용 그랜드 센트럴 디스패치 업로드 사용자에게 알리도록하십시오 Monitor Upload Progress section에서 중포 기지 문서에 설명 된대로 uploadTask 성공적으로 이미지를 업로드하면

, 당신은 알림을받을 수 있습니다 성공했습니다.

콜백을 추가 할 대기열 (Firebase 메서드 구현에 따라 결정됨)은 제어 할 수 없지만 임의 코드의 실행이 완료되면 Grand Central Dispatch를 사용하여 사용자에게 알릴 수 있습니다. 나를 위해 다음 작품 :

let storage = FIRStorage.storage() 
    let storageRef = storage.reference() //You don't need to explicitly write the url in your code. 
             //The config file GoogleService-Info.plist will handle that. 

    let imageRef = storageRef.child("images/align_menu.tiff") 

    let localURL = NSBundle.mainBundle().URLForResource(
     "align_menu", 
     withExtension: "tiff" 
    )! 

    let myExecutionGroup = dispatch_group_create() 

    dispatch_group_enter(myExecutionGroup) 
    //Upload the image: 
    let _ = imageRef.putFile(localURL, metadata: nil) { (metadata, error) -> Void in 
     if let returnedError = error { 
      // Uh-oh, an error occurred! 
      print("[My Upload Error]: \(returnedError)") 
     } else { 
      // Metadata contains file metadata such as size, content-type, and download URL. 
      print("[My Upload Success]:") 
      let downloadURL = metadata!.downloadURL()! 
      print("[URL for download]: \(downloadURL)") 

      dispatch_group_leave(myExecutionGroup) 
     } 

    } 

    let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0) 

    dispatch_group_notify(myExecutionGroup, queue) { 
     //This callback executes for every dispatch_group_leave(). 

     //Download the image: 
     imageRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in 
      if let returnedError = error { 
       // Uh-oh, an error occurred! 
       print("[My Download Error]: \(returnedError)") 
      } 
      else { 
       print("[My Download Success]:") 

       if let validImage = UIImage(data: data!) { 
        NSOperationQueue.mainQueue().addOperationWithBlock() { 
         self.imageView.image = validImage 
        } 
       } 
      } 

     } 

    } 

* 나는 원래 업로드 코드 다운로드 코드 사이 sleep(10) 퍼팅 시도하고, 그 문제를 완화하지 않았다. 만약 업로드 콜백이 백그라운드 스레드에서 실행 되었다면 메인 쓰레드가 잠자고있는 동안 업로드 콜백이 완료 될 시간이 있고, 잠자기가 끝나면 다운로드 코드가 실행되고 다운로드 콜백이 대기열에 추가 될 것이라고 생각했습니다. 어딘가에 다운로드 콜백이 실행됩니다. sleep (10)이 문제를 해결하지 못했기 때문에 업로드 콜백이 주 스레드의 실행 대기열에 추가되어야하고 대기 상태가 주 스레드 및 대기열의 모든 항목을 실행 중지했습니다. 날 리드

업로드 및 다운로드 콜백 메인 스레드 (는 달리 콜백 순서대로 실행됩니다 동기 큐 아니다) 상에 비동기 대기열에 추가 있다고 생각합니다. 나는 메인 스레드의 비동기식 대기열은 메인 쓰레드에 데드 타임이있을 때 대기열의 태스크가 실행되고, 특정 태스크에 데드 타임이있을 때 다양한 태스크를 빠르게 전환한다는 것을 의미한다고 생각한다. HTTP 응답을 기다리고 있습니다. 예를 들어 주 스레드의 비동기 대기열에 두 개의 작업이있는 경우 주 스레드, 작업 1 및 작업 2 사이에 아무 데드 타임이있을 때마다 신속하게 전환됩니다.