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

Swift 4 URL图片下载失败问题求助

解决eBay图片下载时的HTTP错误(-1200/-1002)

咱们先来拆解你遇到的问题:这些HTTP错误本质上和URL合法性、SSL安全验证,以及代码里的请求逻辑都有关系,我帮你一步步排查和解决:

核心问题分析

1. URL里的隐形特殊字符是罪魁祸首

你提供的原始URL里藏了一个看不见的零宽空格字符(就是https://后面那个不起眼的分隔符),这直接导致URL解析失败,触发-1002(NSURLErrorUnsupportedURL)错误。另外,你用addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)处理整个URL是错误的——这个方法是用来编码URL的查询参数部分,不是整个URL,强行编码会把https://里的冒号、斜杠也转义,反而让URL彻底失效。

2. 错误代码对应的含义

  • -1200:属于NSURLErrorSecureConnectionFailed,通常是SSL证书验证失败,或者App的ATS(App Transport Security)配置和目标URL的安全协议不兼容。
  • -1002:NSURLErrorUnsupportedURL,明确说明URL格式不合法,这也是你当前最主要的触发原因。

解决方案

第一步:清理并验证URL

先把原始URL里的隐形字符去掉,正确的URL应该是:

https://i.ebayimg.com/00/s/MTA2NlgxNjAw/z/TaoAAOSwjkdZ57Jm/$_2.jpg

你可以在代码里添加自动清理逻辑,去掉非打印字符和空白:

let cleanedUrlString = rawUrl.trimmingCharacters(in: CharacterSet(charactersIn: "\u{200B}").union(.whitespacesAndNewlines))
guard let url = URL(string: cleanedUrlString) else {
    print("清理后URL依然无效")
    DispatchQueue.main.async {
        self.imageLoadingIndicator.stopAnimating()
        self.image = #imageLiteral(resourceName: "CellDefaultImage")
    }
    return
}

第二步:检查ATS配置

iOS的ATS默认要求HTTPS连接符合严格的安全标准,eBay的图片域名是符合要求的,但如果你的App有特殊配置,可在Info.plist里添加针对ebayimg.com的例外规则(如果清理URL后仍报SSL错误):

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>ebayimg.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <false/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <true/>
        </dict>
    </dict>
</dict>

第三步:优化下载代码(避免资源浪费)

你的代码可以优化几个细节,比如取消旧任务、严格检查HTTP状态码、确保所有UI操作在主线程:

// 保存下载任务引用,避免重复请求
private var imageDownloadTask: URLSessionDataTask?

func loadImage(from rawUrl: String) {
    guard rawUrl != previousUrl else { return }
    
    previousUrl = rawUrl
    
    // 取消正在进行的旧任务
    imageDownloadTask?.cancel()
    
    // UI操作必须在主线程
    DispatchQueue.main.async {
        self.showActivityIndicatory()
    }
    print("Download Started")
    
    // 清理URL中的隐形字符和空白
    let cleanedUrlString = rawUrl.trimmingCharacters(in: CharacterSet(charactersIn: "\u{200B}").union(.whitespacesAndNewlines))
    guard let url = URL(string: cleanedUrlString) else {
        DispatchQueue.main.async {
            self.imageLoadingIndicator.stopAnimating()
            self.image = #imageLiteral(resourceName: "CellDefaultImage")
        }
        print("Invalid URL")
        return
    }
    
    imageDownloadTask = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
        guard let self = self else { return }
        
        // 先停止加载动画
        DispatchQueue.main.async {
            self.imageLoadingIndicator.stopAnimating()
        }
        
        // 处理请求错误
        if let error = error {
            print("下载错误: \(error.localizedDescription)")
            DispatchQueue.main.async {
                self.image = #imageLiteral(resourceName: "CellDefaultImage")
            }
            return
        }
        
        // 检查HTTP状态码是否为200(成功)
        guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
            let statusCode = (response as? HTTPURLResponse)?.statusCode ?? -1
            print("HTTP状态码错误: \(statusCode)")
            DispatchQueue.main.async {
                self.image = #imageLiteral(resourceName: "CellDefaultImage")
            }
            return
        }
        
        // 转换数据为图片
        guard let data = data, let image = UIImage(data: data) else {
            DispatchQueue.main.async {
                self.image = #imageLiteral(resourceName: "CellDefaultImage")
            }
            print("数据转图片失败")
            return
        }
        
        print("Download Finished: \(response?.suggestedFilename ?? url.lastPathComponent)")
        DispatchQueue.main.async {
            self.image = image
        }
        
        // 重置任务引用
        self.imageDownloadTask = nil
    }
    
    imageDownloadTask?.resume()
}

func showActivityIndicatory() {
    imageLoadingIndicator.center = self.center
    imageLoadingIndicator.startAnimating()
}

总结

你当前的问题主要是原始URL包含隐形特殊字符导致的解析失败,按照上面的步骤清理URL、优化代码后,应该能解决-1002和-1200的错误。如果还有问题,可以检查下App的ATS配置是否限制了eBay域名的访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:52:43