SDWebImage 不适用于图像名称中的西班牙字母 iOS Swift

SDWebImage not works with Spanish Alphabets into Image name iOS Swift

我正在使用 SDWebImage 的最新更新版本,到目前为止它运行良好。最近我发现一个问题开始导致我的应用程序崩溃。

我观察到,如果图像 URL 有一个西班牙语字母表,那么它无法下载并生成 nil 异常。这稍后会转化为崩溃问题。

这是我的使用方法:

    cell.imgView.sd_setImage(with: URL(string: imString)!) { (img, error, type, url) in
        cell.imgView.image  = img?.resizeTopAlignedToFill(newWidth: collectionView.frame.size.width)
                cell.imgView.contentMode = .top
    }

这种 URL 图像名称中包含西班牙字母的类型不起作用:

https://test.com/uploads/image_watermark/cloacacaña.PNG

重要提示:

如果有人找到解决此问题的方法,请帮助我。

任何建议将不胜感激。

这不是有效的 URL,因此 URL.init returns 无。请参阅 RFC 3986 section 3.3 定义路径组件的合法字符:

  pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"

unreserved characters 是:

  unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"

ALPHA 包括字符 A-Z 和 a-z(具体来说是 %41-%5a 和 %61-%7a)。 ñ 不在该列表中,因此需要对其进行百分比编码才能位于路径部分中。 US-ASCII 之外的任何其他字母也是如此。

(RFC 3986 涵盖了通用的 URI,并且允许个别方案有不同的规则,但在这种情况下 http 没有。您仍然需要对 ñ 进行百分比编码。)

正确的URL是:

https://test.com/uploads/image_watermark/cloacaca%C3%B1a.PNG

请注意,很多东西(尤其是网络浏览器)对它们接受的 URLs 非常宽松,并将处理各种错误编码。基金会不是。它非常严格地遵循规范,因此您需要确保您的 URL 符合规范。

通常动态创建 URLs 的最佳方法是使用 URLComponents,它将正确编码每个组件:

// Start with the static part that you know is correct
var components = URLComponents(string: "https://test.com")!

// Then add dynamic parts   
let file = "cloacacaña"
components.path = "/uploads/image_watermark/\(file).PNG"

print(components.url!)
// https://test.com/uploads/image_watermark/cloacaca%C3%B1a.PNG

您也可以通过附加动态部分直接构造 URLs:

let file = "cloacacaña"
let url = URL(string: "https://test.com/uploads/image_watermark")!
    .appendingPathComponent(file)
    .appendingPathExtension("PNG")
// https://test.com/uploads/image_watermark/cloacaca%C3%B1a.PNG
然而,

URLComponents 更加灵活,因为它可以处理 URL(主机、片段、查询等)的所有部分的编码,这些部分具有不同的规则。 URL 只能处理编码路径组件。

这不是正确的 URL。尝试通过添加 utf 编码来更改 url 字符串。

cell.imgView.sd_setImage(with: URL(string: imString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)!) { (img, error, type, url) in
cell.imgView.image  = img?.resizeTopAlignedToFill(newWidth: collectionView.frame.size.width)
cell.imgView.contentMode = .top }