【问题标题】:FirebaseStorage issue downloading data into memory (Swift)FirebaseStorage 问题将数据下载到内存中(Swift)
【发布时间】:2016-09-22 08:22:25
【问题描述】:

感谢 Firebase 的重大更新,我正在将我的应用程序的图像托管从 AWS 切换到现在包含在 Firebase 中的 GS 存储。 我已经导入了所有必要的 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(bitPattern: 0x11d028fa0).内存) ^~~~~~~~~~~~~~~ /var/folders/9q/g2rz2_hj15548cf15yrxz37c0000gn/T/lldb/1645/expr11.swift:1:45: 注意:在将这个 '

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

提前致谢


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

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 函数,但它可以工作

【问题讨论】:

    标签: ios swift firebase firebase-storage


    【解决方案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 元素更新回主线程。

    【讨论】:

    • 根据您的建议更改了函数,它抛出 nil,存储的文件路径是正确的,那里有一个文件但它仍然没有将它分配给“数据”,存储桶配置为公开。它不会触发 (error != nil) 条件,它只是不下载图像
    【解决方案2】:

    试试这样的

    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! 
    }
    

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

    【讨论】:

    • 在下载任务之前我可以打印Storage参考完整路径:gs://project-xxxxxx163293.appspot.com/images/xxxxxx.jpg,所以参考就ok in dataWithMaxSize:completion I'我在 if 之前添加了一个 print("dataWithMaxSize running") 语句,然后下一个控制台输出是返回图像行中的“found nil”错误,我在想任务没有运行,当图像:UIImage?从返回调用它是零,因此是错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 2022-01-18
    • 2021-03-19
    • 2012-04-03
    • 1970-01-01
    相关资源
    最近更新 更多