我正在制作视频分享应用,我有一个Objective-C版本和一个Swift版本。我在两个项目中成功将所选视频的网址上传到Firebase存储并检索它们。在Objective-C项目中,视频显示没问题,但在Swift版本中,尽管URL已经登录到控制台,但完全相同,他们不是,AVPlayer只是空白,没有噪音没有什么。
这是我的Swift上传和检索代码:
上传:(尝试使用metadata.downloadURL和metadata.downloadURL.absoluteString)
func sendData(string: String) {
if string == "" && self.urlToUpload == nil {
self.showAlertWithTitle("Please upload a valid file and caption", message: "")
}
else {
//write url to storage ref
if urlToUpload != nil {
let childString = NSString(format: "Video %@", NSUUID().UUIDString)
let videosRef = storageReference.child("postVideos").child(childString as String)
let metadata = FIRStorageMetadata()
metadata.contentType = "Video"
let uploadTask = videosRef.putFile(self.urlToUpload!, metadata: metadata, completion: { (metadata, error) in
if error != nil {
print("ERROR DESC. %@", error?.localizedDescription)
print("ERROR %@", error)
}
else {
print(metadata)
//pop alert here then set button back etc.
}
})
uploadTask.observeStatus(.Success) { snapshot in
print("Success!")
print(snapshot)
print(snapshot.metadata?.downloadURL())
//self.downloadURLToUpload = snapshot.metadata?.downloadURL()
self.downloadURLString = snapshot.metadata?.downloadURL()?.absoluteString
uploadTask.removeAllObservers()
//if download url exists send rest of data
let emailString = String(FIRAuth.auth()!.currentUser!.email!)
//let postToSend = Post(name: emailString, message: string, downloadURLString: String(self.downloadURLToUpload!))
let postToSend = Post(name: emailString, message: string, downloadURLString: self.downloadURLString)
let postDict = ["name" : postToSend.name!, "message" : postToSend.message!, "downloadURLString" :postToSend.downloadURLString!]
self.reference.child("messages").childByAutoId().setValue(postDict)
self.tableView.reloadData()
}
}
}
}
检索:
func returnDataFromURL(urlString: String!, completion: CompletionHandler) {
let strg = FIRStorage.storage()
let ref = strg.referenceForURL(urlString)
ref.downloadURLWithCompletion { (url, error) in
if error != nil {
print(error?.localizedDescription)
}
else {
completion(url: url!)
}
}
}
URL本身是相同的格式,但是控制台中的属性看起来有点不同,这可能是我将它们传递给AVPlayer的问题(它与测试视频一起使用所以不是问题)。
如何在Objective-C项目中打印检索到的下载URL。
在斯威夫特......
感谢您的帮助,就像往常一样。
答案 0 :(得分:0)
TL; DR:这是预期的行为;只需使用HTTP库(NSURLSession
,GTMSessionFetcher
,AlamoFire
)下载它,而不是使用FIRStorageReference
将其转换为referenceWithURL
。
长篇故事:你有一个项目(让我们称之为foo
),它附有一个存储桶foo.appspot.com
。您上传了一个对象(我们称之为myFile.txt
)。现在,您想与朋友分享该对象。
有两种方式可以表示存储在您的广告资源myFile.txt
中的foo.appspot.com
:
gs://foo.appspot.com/myFile.txt
https://firebasestorage.googleapis.com/v0/b/foo.appspot.com/o/myFile.txt?alt=media&token=<token>
必须通过我们的库(dataWithMaxSize:completion:
,writeToFile:
)下载私人网址,并检查其是否有正确的身份验证凭据,然后通过Firebase Storage Security Rules进行授权。
公共网址可以通过任何图书馆(如AlamoFire
等)和任何用户下载,无论他们是否使用您的应用。这些下载不会进行身份验证或授权检查,而是依赖于您(开发人员)进行适当控制(如果URL过于广泛,我们允许您撤消该无法使用的令牌)。由于有时候开发人员为我们提供公共下载URL并且他们想要操纵它(比如在引用处添加新文件或修改现有文件,以及允许外部下载),我们提供{{ 1}}将公用URL(referenceWithURL:
)转换为私有URL(https://
)的方法,然后可以对其进行操作。
因此,当您尝试从项目外部的URL创建存储引用时(这意味着您将对该文件执行经过身份验证和授权的请求),我们会抛出异常,因为您无法坚持将gs://
之类的网址下载到项目https://firebasestorage.googleapis.com/v0/b/bar.appspot.com/o/myOtherFile.txt?alt=media&token=<token>
中的应用中并获取除失败以外的任何结果 - 我们不允许项目foo
中的随机验证用户对项目{{}中的文件进行操作1}}(超出公共下载网址)。
将来,当我们为每个项目支持多个存储桶时,我们将允许您创建对您可以控制的其他存储桶的引用,但在此之前,只需像下载任何其他文件一样下载文件。