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
相关产品推荐
相关产品推荐

