带有变音符号的图像网址被写入错误的部分

时间:2016-08-27 07:49:39

标签: ios swift firebase firebase-realtime-database

我使用 Firebase 执行一些简单的任务,将图片url设置为json,下载并显示它。但出于某种原因,如果url包含变音符号,例如(ö,ä,ü等......),则网址设置为错误的部分。

编辑:我必须澄清我使用网址进行百分比编码。所以它实际上不包含任何变音符号。

所以url实际上就像Göteborgs Rapé Loose.pnghttps://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

一样

使用变音符号就是这样:

enter image description here

如果没有变音符号,它会像一样正确

enter image description here

这就是我所描述的所有这些步骤:

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)

            })

有什么问题,你能告诉我吗?我一直在寻找这个问题好一周。

1 个答案:

答案 0 :(得分:1)

网址不能直接包含“变音符号”。简单来说,URL是一系列受限制的ASCII字符。

这意味着,需要对不允许的字符(例如öäü等)进行适当编码。由于URL由几个不同的组件组成,因此每个组件可以使用略微不同的编码。详情请参阅:Uniform Resource Identifier (URI): Generic Syntax

在Cocoa和Cocoa Touch中,有一个帮助器类NSURLComponents,可以让您轻松地以自然字符编码从给定的原始组件中组合一个正确的URL字符串。

请注意,简单地将“百分比编码”应用于整个不正确的编码URL通常会产生另一个不正确的编码URL。不要那样做!使用NSURLComponents

修改

让我对您的代码应用一些 - 希望有用的 - 评论:

这个表达式存在问题:

  1. NSURL(string: productsValue[indexPath.row]["productUrl"] as! String)!
  2. 最好从索引URL的潜在缺失值显式初始化"productUrl"并包含正确的错误处理。众所周知,将字符串转换为URL非常容易出错。

    然后

    1. let decomposedPath = productImageref.decomposedStringWithCanonicalMapping
    2. 这没有任何意义,因为根据定义,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