我使用 Firebase 执行一些简单的任务,将图片url
设置为json
,下载并显示它。但出于某种原因,如果url
包含变音符号,例如(ö,ä,ü等......),则网址设置为错误的部分。
编辑:我必须澄清我使用网址进行百分比编码。所以它实际上不包含任何变音符号。
所以url
实际上就像Göteborgs Rapé Loose.png
:https://firebasestorage.googleapis.com/v0/b/snuspedia.appspot.com/o/Go%CC%88teborgs%20Rape%CC%81%20Loose.png?alt=media&token=e8f2219b-d14e-46f6-a90f-ee21f912af6c
使用变音符号就是这样:
如果没有变音符号,它会像一样正确:
这就是我所描述的所有这些步骤:
if productsValue[indexPath.row]["productUrl"] != nil {
cell.snusProductImageView!.kf_setImageWithURL(NSURL(string: productsValue[indexPath.row]["productUrl"] as! String)!)
}
else {
let productImageref = productsValue[indexPath.row]["Products"] as! String
let decomposedPath = productImageref.decomposedStringWithCanonicalMapping
cell.snusProductImageView.image = nil
cell.snusProductImageView.kf_showIndicatorWhenLoading = true
FIRStorage.storage().reference().child("\(decomposedPath).png").downloadURLWithCompletion({(url, error)in
FIRDatabase.database().reference().child("Snuses").child(decomposedPath).child("productUrl").setValue(url!.absoluteString)
let resource = Resource(downloadURL: url!, cacheKey: decomposedPath)
cell.snusProductImageView.kf_setImageWithURL(url)
})
有什么问题,你能告诉我吗?我一直在寻找这个问题好一周。
答案 0 :(得分:1)
网址不能直接包含“变音符号”。简单来说,URL是一系列受限制的ASCII字符。
这意味着,需要对不允许的字符(例如ö
,ä
,ü
等)进行适当编码。由于URL由几个不同的组件组成,因此每个组件可以使用略微不同的编码。详情请参阅:Uniform Resource Identifier (URI): Generic Syntax。
在Cocoa和Cocoa Touch中,有一个帮助器类NSURLComponents
,可以让您轻松地以自然字符编码从给定的原始组件中组合一个正确的URL字符串。
请注意,简单地将“百分比编码”应用于整个不正确的编码URL通常会产生另一个不正确的编码URL。不要那样做!使用NSURLComponents
!
修改强>
让我对您的代码应用一些 - 希望有用的 - 评论:
这个表达式存在问题:
NSURL(string: productsValue[indexPath.row]["productUrl"] as! String)!
最好从索引URL
的潜在缺失值显式初始化"productUrl"
并包含正确的错误处理。众所周知,将字符串转换为URL非常容易出错。
然后
let decomposedPath = productImageref.decomposedStringWithCanonicalMapping
这没有任何意义,因为根据定义,URL字符串无论如何都由一组受限制的ASCII字符组成。
因此,总之,检查您的给定字符串应该成为URL,并确保您可以从中初始化正确的URL(作为类型URL
的值),并将其再次正确地转换回字符串,通过网络发送时,分别为ASCII字符数组。
编辑2:
下面的代码演示了如何利用NSURLComponents
从给定的基本URL安全地创建URL,部分路径组件引用端点以及给定的参数集。
复制/过去进入游乐场试试。
import Cocoa
extension String: ErrorType {}
// First, create a base URL and save it later for reuse:
// Caution: The given string must be properly encoded! But usually, the base address
// in native form should only use allowed characters anyway, so the encoded form
// should be equal to the native form (otherwise, you have to encode it per component).
let urlBaseString = "https://firebasestorage.googleapis.com/v0/b/snuspedia.appspot.com/o"
guard let urlBase = NSURL(string: urlBaseString) else {
throw "bad base URL"
}
print("Base URL path: \"\(urlBase.path!)\"")
// Get the current path and parameters using strings using their "native character set":
let itemPath = "Göteborgs Rapé Loose.png"
let params = ["alt": "media", "token": "e8f2219b-d14e-46f6-a90f-ee21f912af6c"]
// Create a partial URL components (representing a relative URL) with the given
// path and query component:
let components = NSURLComponents()
components.path = itemPath
components.queryItems = params.map { NSURLQueryItem(name: $0, value: $1) }
// Combine the base URL with the partial URL in order to get a fully specified URL:
guard let url = components.URLRelativeToURL(urlBase) else {
throw "Failed to create final URL"
}
print("URL: \(url.absoluteString)")
输出:
URL: https://firebasestorage.googleapis.com/v0/b/snuspedia.appspot.com/G%C3%B6teborgs%20Rap%C3%A9%20Loose.png?alt=media&token=e8f2219b-d14e-46f6-a90f-ee21f912af6c