You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift iOS 接收随机URL的编码实现优化及更Swifty写法咨询

Swift 随机URL场景编码方案优化求助

背景

由于我没有足够的声望值在Stack Overflow的《URL Encoding swift IOS》问题下发表评论,因此创建了新问题,希望获得反馈,让下述针对随机URL场景的编码方案更符合Swifty规范。

我对原问题的理解是:API响应或其他数据源中存在多张图片的URL链接,可能来自不同的主机域名。
这种情况下,可以先提取主机URL,也可以用类似方法单独提取路径。
路径可以按下述方式编码,之后再拼接回主机字符串:

addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)

初始实现方案

以下是我最初在Playground中尝试的实现:

import Foundation

extension String {
    var encoded: String? {
        return self.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)
    }
}

let urlStrings:[String] = ["https://example.com/test.jpg",
                           "https://example.cc/test2.jpg",
                           "https://example.dev.cc/test3.jpg"]

var encodedUrlStrings: [String] = []

urlStrings.forEach { urlString in
    print(urlString)
    guard let url = URL(string: urlString),
            let domain = url.host,
            let encodedPath = url.path.encoded else { return }
    
    let encodedUrlString = domain + encodedPath
    encodedUrlStrings.append(encodedUrlString)
}
encodedUrlStrings.count
encodedUrlStrings.forEach { print($0) }

异常场景兼容方案

但我注意到原问题中存在一个特殊情况:部分URL本身包含空格或Unicode字符,例如:

https://ftximages.apk.in/test Fretailer_Point-6685.jpg

这类字符串使用URL(String:)方法转换为URL时始终返回nil,使用URLComponents也会得到相同结果,因为路径中的字符不符合URL规范。这种情况理论上需要和后端开发或发送未编码URL的相关人员提前约定规范。

如果后端开发不配合调整,下述代码提供了这类URL字符串的编码示例,其中String扩展来自@Claudio的回答:

import Foundation

extension String {
    var encoded: String? {
        return self.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)
    }
}

let urlStrings:[String] = ["https://example.com.cc/folder/test.jpg",
                           "https://example.com/test.jpg",
                           "https://Ftximages.apk.in/test Fretailer_Point-6685.jpg",
                           "https://example.com/원 더 우먼.jpg",
                           "https://example.dev.cc/刺客聶隱娘-6685.jpg",
                           "https://example.cc/बाजीराव मस्तानी.jpg"]

var encodedUrlStrings: [String] = []

func encodeURL(scheme: String, host: String, path: String) -> String? {
    var components = URLComponents()
    components.scheme = scheme
    components.host = host
    components.path = path
    
    return components.url?.absoluteString ?? URL(string: "\(scheme)://\(host)/\(path)")?.absoluteString
}

func encodeWeirdUrlString(_ urlString: String) -> String? {
    var urlSplitStrings = urlString.components(separatedBy: ["/"])
    urlSplitStrings.removeAll(where: { $0.isEmpty })
    guard  urlSplitStrings.indices.contains(0), urlSplitStrings.indices.contains(1) else { return nil }
    
    let scheme = String(urlSplitStrings[0].dropLast())
    let host = urlSplitStrings[1]
    
    urlSplitStrings.remove(at: 1)
    urlSplitStrings.remove(at: 0)
    
    guard let path = urlSplitStrings.joined(separator: "/").encoded else { return nil}
    
    let encodedUrlString = encodeURL(scheme: scheme, host: host, path: path)
    
    return encodedUrlString
}

urlStrings.forEach { urlString in
    print(urlString)
    guard let url = URL(string: urlString),
          let scheme = url.scheme,
          let host = url.host,
          let encodedPath = url.path.encoded,
          let encodedUrlString = encodeURL(scheme: scheme, host: host, path: encodedPath) else {
              
              if let encodedUrlString = encodeWeirdUrlString(urlString) {
                  encodedUrlStrings.append(encodedUrlString)
              }
              return
          }
    
    encodedUrlStrings.append(encodedUrlString)
}

encodedUrlStrings.count
encodedUrlStrings.forEach { print($0) }

优化诉求

请问上述方案可以做哪些优化,让其更符合Swifty的代码规范?


内容的提问来源于stack exchange,提问作者Skron31

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 22:45:06