我正在
FIRStorageReference
上编写一个 Swift 扩展来检测文件是否存在。我打电话给metadataWithCompletion()
。如果未设置完成块的可选 NSError
,我认为可以安全地假设该文件存在。
如果设置了 NSError,则要么出现问题,要么文件不存在。关于处理 iOS 中的错误的 存储文档 指出
FIRStorageErrorCodeObjectNotFound
是我应该检查的错误类型,但它无法解决(可能 Swiftified 为更短的 .Name 样式常量?)并且我不是确定我应该检查什么。
如果在某处设置了
completion(nil, false)
,我想致电 FIRStorageErrorCodeObjectNotFound
。
这是到目前为止我的代码。
extension FIRStorageReference {
func exists(completion: (NSError?, Bool?) -> ()) {
metadataWithCompletion() { metadata, error in
if let error = error {
print("Error: \(error.localizedDescription)")
print("Error.code: \(error.code)")
// This is where I'd expect to be checking something.
completion(error, nil)
return
} else {
completion(nil, true)
}
}
}
}
提前非常感谢。
您可以像这样检查错误代码:
// Check error code after completion
storageRef.metadataWithCompletion() { metadata, error in
guard let storageError = error else { return }
guard let errorCode = FIRStorageErrorCode(rawValue: storageError.code) else { return }
switch errorCode {
case .ObjectNotFound:
// File doesn't exist
case .Unauthorized:
// User doesn't have permission to access file
case .Cancelled:
// User canceled the upload
...
case .Unknown:
// Unknown error occurred, inspect the server response
}
}
这是一个简单的代码,我用它来检查用户是否已经通过 hasChild("") 方法获取了用户照片,参考在这里:
https://firebase.google.com/docs/reference/ios/firebasedatabase/interface_f_i_r_data_snapshot.html
希望这能有所帮助
let userID = FIRAuth.auth()?.currentUser?.uid
self.databaseRef.child("users").child(userID!).observeEventType(.Value, withBlock: { (snapshot) in
// Get user value
dispatch_async(dispatch_get_main_queue()){
let username = snapshot.value!["username"] as! String
self.userNameLabel.text = username
// check if user has photo
if snapshot.hasChild("userPhoto"){
// set image locatin
let filePath = "\(userID!)/\("userPhoto")"
// Assuming a < 10MB file, though you can change that
self.storageRef.child(filePath).dataWithMaxSize(10*1024*1024, completion: { (data, error) in
let userPhoto = UIImage(data: data!)
self.userPhoto.image = userPhoto
})
}
斯威夫特5
let storageRef = Storage.storage().reference().child("yourPath").child("\(someFile)") // eg. someVideoFile.mp4
print(storageRef.fullPath) // use this to print out the exact path that your checking to make sure there aren't any errors
storageRef.getMetadata() { (metadata: StorageMetadata?, error) in
if let error = error {
guard let errorCode = (error as NSError?)?.code else {
print("problem with error")
return
}
guard let err = StorageErrorCode(rawValue: errorCode) else {
print("problem with error code")
return
}
switch err {
case .objectNotFound:
print("File doesn't exist")
case .unauthorized:
print("User doesn't have permission to access file")
case .cancelled:
print("User cancelled the download")
case .unknown:
print("Unknown error occurred, inspect the server response")
default:
print("Another error occurred. This is a good place to retry the download")
}
return
}
// Metadata contains file metadata such as size, content-type.
guard let metadata = metadata else {
// an error occured while trying to retrieve metadata
print("metadata error")
return
}
if metadata.isFile {
print("file must exist becaus metaData is a file")
} else {
print("file for metadata doesn't exist")
}
let size = metadata.size
if size != 0 {
print("file must exist because this data has a size of: ", size)
} else {
print("if file size is equal to zero there must be a problem"
}
}
没有详细错误检查的较短版本:
let storageRef = Storage.storage().reference().child("yourPath").child("\(someFile)")
storageRef.getMetadata() { (metadata: StorageMetadata?, error) in
if let error = error { return }
guard let metadata = metadata else { return }
if metadata.isFile {
print("file must exist because metaData is a file")
} else {
print("file for metadata doesn't exist")
}
let size = metadata.size
if size != 0 {
print("file must exist because this data has a size of: ", size)
} else {
print("if file size is equal to zero there must be a problem"
}
}
对于 FirebaseStorage (10.16.0),请改用
StorageError
,因为在此版本中 objectNotFound
的错误代码变为 1
。
extension StorageReference {
func fileExists() async throws -> Bool {
do {
let _ = try await self.getMetadata()
return true
} catch {
if case StorageError.objectNotFound = error {
return false
} else {
throw error
}
}
}
}