前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >iOS开发之网络代码进化史

iOS开发之网络代码进化史

作者头像
YungFan
发布2025-03-11 09:49:39
发布2025-03-11 09:49:39
5800
代码可运行
举报
文章被收录于专栏:学海无涯学海无涯
运行总次数:0
代码可运行

介绍

目前,iOS 原生网络请求数据共有 4 种方式,分别是传统 Completion 回调Completion 回调 + ResultCombine 框架Swift Concurrency (async/await)。本文以下载图片为例,详细讲解 4 种网络请求的差异。

传统Completion回调

一种最基础的异步处理方式,使用闭包作为回调函数。

代码

代码语言:javascript
代码运行次数:0
运行
复制
/// 错误枚举
enum FetchError: Error {
    case badURL
    case badRequest
    case badImage
}

/// 1. 传统completion回调
func fetchImage(from url: String, completion: @escaping (UIImage?, Error?) -> Void) {
    guard let url = URL(string: url) else {
        completion(nil, FetchError.badURL)
        return
    }
    let request = URLRequest(url: url)
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            completion(nil, error)
        } else if (response as? HTTPURLResponse)?.statusCode != 200 {
            completion(nil, FetchError.badRequest)
        } else {
            guard let data = data,
                  let image = UIImage(data: data) else {
                completion(nil, FetchError.badImage)
                return
            }
            completion(image, nil)
        }
    }
    task.resume()
}

fetchImage(from: "https://search-operate.cdn.bcebos.com/7e85570b817e17e8f3ae93134cc78451.gif") { image, error in
    if let image {
        print(image)
    } else if let error {
        print(error)
    }
}

优点

  • 简单易懂,学习曲线低。
  • 兼容性好,适用于所有 iOS 版本。

缺点

  • 可能导致"回调地狱"。
  • 错误处理比较分散,每个回调都需要单独处理错误。
  • 取消操作比较麻烦。

Completion回调+Result

对传统 Completion 回调的改进,使用 Swift 的 Result 类型统一处理成功和失败情况。

代码

代码语言:javascript
代码运行次数:0
运行
复制
enum FetchError: Error {
    case badURL
    case badRequest
    case badImage
}

/// 2. completion回调+Result
func fetchImage(from url: String, completion: @escaping (Result<UIImage, Error>) -> Void) {
    guard let url = URL(string: url) else {
        completion(.failure(FetchError.badURL))
        return
    }
    let request = URLRequest(url: url)
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            completion(.failure(error))
        } else if (response as? HTTPURLResponse)?.statusCode != 200 {
            completion(.failure(FetchError.badRequest))
        } else {
            guard let data = data,
                  let image = UIImage(data: data) else {
                completion(.failure(FetchError.badImage))
                return
            }
            completion(.success(image))
        }
    }
    task.resume()
}

fetchImage(from: "https://search-operate.cdn.bcebos.com/7e85570b817e17e8f3ae93134cc78451.gif") { result in
    switch result {
    case let .success(image):
        print(image)
    case let .failure(error):
        print(error)
    }
}

优点

  • 相比传统回调,代码更加清晰和统一。
  • 能够明确区分成功和失败状态。
  • 兼容所有 iOS 版本。

缺点

  • 仍然会导致回调嵌套问题。
  • 取消机制同样需要额外处理。

Combine框架

Combine 是 Apple 在 iOS 13 引入的响应式编程框架,专为处理异步事件流设计。

代码

代码语言:javascript
代码运行次数:0
运行
复制
enum FetchError: Error {
    case badURL
    case badRequest
    case badImage
}

/// 3. Combine
func fetchImage(from url: String) -> AnyPublisher<UIImage, Error> {
    guard let url = URL(string: url) else { return Fail<UIImage, Error>(error: FetchError.badURL).eraseToAnyPublisher() }
    let request = URLRequest(url: url)
    let session = URLSession.shared
    let dataPublisher = session.dataTaskPublisher(for: request)
        .retry(3)
        .timeout(5, scheduler: DispatchQueue.global())
        .tryMap { data, response -> Data in
            guard (response as? HTTPURLResponse)?.statusCode == 200 else { throw FetchError.badRequest }
            return data
        }
        .tryMap { data -> UIImage in
            guard let image = UIImage(data: data) else {throw FetchError.badImage}
            return image
        }
        .receive(on: DispatchQueue.main)
        .subscribe(on: DispatchQueue.global())
        .eraseToAnyPublisher()
    return dataPublisher
}

var cancellables = Set<AnyCancellable>()
fetchImage(from: "https://search-operate.cdn.bcebos.com/7e85570b817e17e8f3ae93134cc78451.gif")
    .sink(
        receiveCompletion: { completion in
            switch completion {
            case .finished:
                print("Image download completed successfully")
            case let .failure(error):
                print(error)
            }
        }, receiveValue: { image in
            print(image)
        }
    )
    .store(in: &cancellables)

优点

  • 声明式编程风格,代码更简洁。
  • 强大的操作符支持。
  • 优雅的错误处理和转换机制。
  • 提供标准的取消机制。

缺点

  • 学习曲线较陡峭。
  • 仅支持 iOS 13 及以上版本。
  • 长链式调用可能影响代码可读性。

4. Swift Concurrency (async/await)

Swift 5.5 引入的现代异步编程模型,使用结构化并发的概念。

代码

代码语言:javascript
代码运行次数:0
运行
复制
enum FetchError: Error {
    case badURL
    case badRequest
    case badImage
}

/// 4. Concurrency
func fetchImage(from url: String) async throws -> UIImage {
    guard let url = URL(string: url) else { throw FetchError.badURL }
    let request = URLRequest(url: url)
    let (data, response) = try await URLSession.shared.data(for: request)
    guard (response as? HTTPURLResponse)?.statusCode == 200 else { throw FetchError.badRequest }
    let image = UIImage(data: data)
    guard let image = image else { throw FetchError.badImage }
    return image
}

Task {
    do {
        let image = try await fetchImage(from: "https://search-operate.cdn.bcebos.com/7e85570b817e17e8f3ae93134cc78451.gif")
        print(image)
    } catch {
        print(error)
    }
}

优点

  • 代码简洁直观,接近同步代码的阅读体验。
  • 易于理解的错误处理。
  • 内置取消支持和结构化并发。
  • 易于调试和维护。

缺点

  • 一定的学习曲线。
  • 需要 iOS 15 及以上版本。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
  • 传统Completion回调
    • 代码
    • 优点
    • 缺点
  • Completion回调+Result
    • 代码
    • 优点
    • 缺点
  • Combine框架
    • 代码
    • 优点
    • 缺点
  • 4. Swift Concurrency (async/await)
    • 代码
    • 优点
    • 缺点
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档