0

感谢 Firebase 的重大更新,我正在将我的应用程序的图像托管从 AWS 切换到现在包含在 Firebase 中的 GS Storage。我已经导入了所有必要的 pod,这个应用程序已经成功地将图像上传到分配的存储桶,但问题是当我想下载到存储的内存图像时,应用程序崩溃,调试我在 FIRStorageReference 对象中发现以下错误:“使用未声明的类型'FirebaseStorage'”我正在将Firebase标头导入函数所在的VC。

func getImage(imageName: String) -> UIImage {
    let imageRef = kBucketRef.child(imageName) 
    print(imageRef) 
    var imageData: NSData? 
    var image: UIImage? 
    imageRef.dataWithMaxSize(200 * 1024) { (data, error) -> Void in 
        if (error != nil) { 
        imageData = data 
        image = UIImage(data: imageData!) 
        } else { 
            print(error?.localizedDescription) 
        } 
   }
    return image! 
}

稍后在尝试显示图像时: image.image = getImage(imageName) 被称为它会在返回图像中引发提到的错误!

致命错误:在展开可选值时意外发现 nil

imageRef 的打印描述:表达式产生错误:/var/folders/9q/g2rz2_hj15548cf15yrxz37c0000gn/T/lldb/1645/expr11.swift:1:46:错误:使用未声明的类型“FirebaseStorage”$__lldb__DumpForDebugger(Swift.UnsafePointer< FirebaseStorage. FIRStorageReference >(bitPattern: 0x11d028fa0).memory) ^~~~~~~~~~~~~~~ /var/folders/9q/g2rz2_hj15548cf15yrxz37c0000gn/T/lldb/1645/expr11.swift:1:45: 注意:同时将此'<'解析为类型参数括号 $__lldb__DumpForDebugger(Swift.UnsafePointer(bitPattern: 0x11d028fa0).memory)

'print(imageRef)' 的输出打印 GS 参考 (gs://project-xxxxxx...) 但 '.dataWithMaxSize()' 失败

提前致谢


(几天后)好的,这是一个解决方法,因为 FIRStorage 方法没有修改单独函数中的变量以供以后返回:

let bucket: String = "gs://mystoragetesterxxxxxx.appspot.com"


func getImage() {

    let storage = FIRStorage.storage()
    let storageRef = storage.referenceForURL(bucket)
    let path = storageRef.child("photo.jpg")
    print(path)
    path.dataWithMaxSize(1024 * 1024) { (data, error) in
        if (error != nil) {
            print(error!.localizedDescription)
        } else {
            self.imageView.image = UIImage(data: data!)
        }
    }

}

现在 getImage 它是一个 void 函数,但它可以工作

4

2 回答 2

1

您确定这不仅仅是您声明可选类型的问题:

var image: UIImage?

然后调用异步函数

imageRef.dataWithMaxSize...

然后不等待它,返回一个隐式展开的可选?

return image!

在我看来,因为 image 是 nil,所以你“意外地解开了一个 nil”,这在很大程度上依赖于竞争条件来取得成功。

我会尝试更多类似的东西:

var image: UIImage? 
imageRef.dataWithMaxSize(200 * 1024) { (data, error) -> Void in 
    if (error != nil) { 
        return UIImage(data: data!)!
    } else { 
        print(error?.localizedDescription) 
    } 
}

但总的来说,包装异步调用并尝试使其同步是一个坏主意(除非您实现了类似 Promise 的东西)——您应该只使用异步调用来更新主线程上的 UI 元素。

于 2016-05-25T06:04:09.183 回答
1

尝试这样的事情

let storage = FIRStorage.storage()

然后函数

    func getImage(imageName: String) -> UIImage {
        let gsReference = storage.referenceForURL(imageName!)

        print(imageRef) 
        var imageData: NSData? 
        var image: UIImage? 
        let downloadTask = gsReference.dataWithMaxSize(200 * 1024) { (data, error) -> Void in 
            if (error != nil) { 
            //imageData = data 
            //image = UIImage(data: imageData!) 

             let image = UIImage.init(data: data!)

            } else { 
                print(error?.localizedDescription) 
            } 

          downloadTask.observeStatus(.Resume) { (snapshot) -> Void in
                print("Downloading has started")


            }
      }
    return image! 
}

然后您会在日志中看到下载是否已开始。

于 2016-05-26T15:08:01.693 回答