Firebase Storage에는 어떤 단점이나 문제가 있습니까? 어떤 종류의 캐싱이 해결되어야합니까?
UploadTask
은 asynchronously
을 실행합니다. 이미지를 업로드 한 직후에 이미지를 다운로드하려고하면 오류가 다시 발생합니다. 이미지의 업로드가 완료되기 전에 다운로드 코드가 실행되어 이미지 존재하지 않는 오류가 발생합니다. 당신은 다운로드 코드는 콜백에 어떤 메시지를 인쇄하여 너무 일찍 실행하는 것을 볼 수 있습니다 :
[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 사이에 아무 데드 타임이있을 때마다 신속하게 전환됩니다.
'signedInUser.uid'가 ('String! '에 강요하지 않았기 때문에) 객체로 반환되는 것처럼 보입니다. 잘못된 파일을 가리키고 있습니다. 당신이 올바른 'uid'를 얻고 있고 경로가 실제로 맞는지 확인할 수 있습니까? –