5

为什么 Xcode 会向我抱怨关于将图像上传到 Firebase 存储的权限,但是当我在模拟器中运行相同的应用程序时,它工作正常?

权限错误:

正文文件无法访问:/var/mobile/Media/DCIM/100APPLE/IMG_0974.JPG Error Domain=NSCocoaErrorDomain Code=257 “文件“IMG_0974.JPG”无法打开,因为您没有查看权限。 " UserInfo={NSURL=file:///var/mobile/Media/DCIM/100APPLE/IMG_0974.JPG, NSFilePath=/var/mobile/Media/DCIM/100APPLE/IMG_0974.JPG, NSUnderlyingError=0x14805d680 {错误域=NSPOSIXErrorDomain 代码=1 "不允许操作"}}

4

6 回答 6

7

我现在也有同样的问题。在模拟器中上传工作正常,但在设备上它给了我权限错误。我的解决方法是将图像作为数据上传,而不是使用文件的 URL:

let imageData = UIImageJPEGRepresentation(image, 1.0)
let uploadTask = storageReference.child(remoteFilePath).putData(imageData, metadata: metadata, completion: { (metadata, error) in
    // Your code here
}
于 2016-07-15T20:27:30.933 回答
1

在模拟器中上传工作正常,但在设备上它给了我权限错误。将图像作为数据而不是 URL 上传到文件:

先声明

    fileprivate lazy var storageRef: StorageReference = Storage.storage().reference(forURL: "gs://yourAPP.appspot.com/")

然后

     let path : String = "\(String(describing: Auth.auth().currentUser?.uid))/\(Int(Date.timeIntervalSinceReferenceDate * 1000))/\(photoReference)"

                // 6

                let imageData = UIImageJPEGRepresentation(photoReference, 0.1)
                let uploadTask = self.storageRef.child(path).putData(imageData!, metadata: nil, completion: { (metadata, error) in
                    // Your code here
                    if let error = error {
                        print("Error uploading photo: \(error.localizedDescription)")
                        return
                    }

                    // 7
                    self.setImageURL(self.storageRef.child((metadata?.path)!).description, forPhotoMessageWithKey: key)
                })
于 2017-07-26T11:11:35.007 回答
0

另一种选择是将文件复制到“文档”目录(可写)。它使用的代码比该UIImageJPEGRepresentation方法多一点,因此您可能仍然更喜欢使用该技术。如果您真的不想更改原始图像,也许可以使用“文档目​​录”方法(但是,理论上,原始图像与使用UIImageJPEGRepresentation100% 创建的图像之间的差异应该是难以察觉的)。

asset.requestContentEditingInput(with: options, completionHandler: {(contentEditingInput: PHContentEditingInput?, info: [AnyHashable : Any]) -> Void in

    let originalFileUrl = contentEditingInput!.fullSizeImageURL!

    /* Copy file from photos app to documents directory */
    let fileManager = FileManager.default
    let documentsDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
    let destinationPath = documentsDirectory.appendingPathComponent(originalFileUrl.lastPathComponent)
    let destinationUrl = URL(fileURLWithPath: destinationPath)

    do {
        try fileManager.copyItem(at: originalFileUrl, to: destinationUrl)
    }
    catch {
        print("Unable to copy file from photos to documents directory (run out of space on device?)")
        return
    }

    /* Create metadata etc. for Firebase... */

    /* Upload file to Firebase */
    fileRef.putFile(from: destinationUrl, metadata: metadata, completion: { (metadata, error) in

        // Remove the file from the documents directory
        do {
            try fileManager.removeItem(at: destinationUrl)
        }
        catch {
            print("Unable to remove file from documents directory")
        }

    })


})
于 2017-10-31T16:35:39.303 回答
0

我正在使用 SwiftUI 和 .fileImporter,它对我来说仍然很新,所以我不确定它是否可以,但它现在可以工作了,所以我想我会把代码留在这里,让那些也在苦苦挣扎的人。 文件导入器代码

上传前移动文档的功能

添加文件管理器扩展

 extension FileManager {


   static func getDocumentsDirectory() -> URL {
       let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
       let documentsDirectory = paths[0]
       return documentsDirectory
   }
}
于 2021-09-08T10:17:31.207 回答
0

这段代码在 didFinishPickingMediaWithInfo 下面。

我评论了当用户从 photoLibrary 中选择图像时处理的代码:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    picker.dismissViewControllerAnimated(true,completion:nil)
    let image = info[UIImagePickerControllerOriginalImage] as! UIImage//<--

    let imageData = UIImageJPEGRepresentation(image, 1.0)
    let imagePath = "photos/xxxyyyzzz.jpg"//whatever you want
    let metadata = FIRStorageMetadata()
    metadata.contentType = "image/jpeg"
            
    storageRef.child(imagePath).putData(imageData!,metadata:metadata){
                (metadata, error) in
                if let error = error{
                    print("Error uploading photo: \(error)")
                }
                else{
                    //if there is no error the compiler will come here
                    print("no error")
                    //and maybe you want to use the full url or download url after success
                    //for example you wanna have tha downloadURL...
                    let downloadURL = metadata!.downloadURL()
                    print("\(downloadURL)")
                    //do whatever you want...
                }
    }

}
于 2017-08-22T13:47:46.270 回答
-1

查看 Firebase 存储规则。并临时允许所有没有身份验证的路径。

于 2016-06-05T09:17:37.963 回答