SwiftUI 11-网络请求与数据解析

在实际开发中,App 常常需要从远程服务器获取数据并展示给用户。本章将介绍在 SwiftUI 中如何优雅地处理网络请求与 JSON 解析,包括:

  • 使用原生 URLSession 的方式(用于入门和底层理解)

  • 实际项目中更常用的第三方库 Alamofire

  • 如何将请求逻辑与 SwiftUI 的视图进行解耦(MVVM 架构)


一、使用 URLSession 加载数据(了解底层原理)

URLSession 是苹果提供的原生网络 API,适合理解网络请求的基本流程:

func fetchData(from urlString: String, completion: @escaping (Data?) -> Void) {
    guard let url = URL(string: urlString) else {
        completion(nil)
        return
    }

    URLSession.shared.dataTask(with: url) { data, _, error in
        if let error = error {
            print("请求失败:\(error)")
            completion(nil)
        } else {
            completion(data)
        }
    }.resume()
}


二、定义模型并解析 JSON 数据

苹果提供了 Codable 协议用于自动解析 JSON 数据,非常方便。

struct Article: Codable, Identifiable {
    let id: Int
    let title: String
    let author: String
}

func parseArticles(from data: Data) -> [Article]? {
    let decoder = JSONDecoder()
    do {
        return try decoder.decode([Article].self, from: data)
    } catch {
        print("解析失败:\(error)")
        return nil
    }
}


三、使用 Alamofire 简化网络请求(推荐方式)

在真实开发中,为了减少样板代码并提高可维护性,推荐使用第三方网络库 Alamofire

安装方式

使用 Swift Package Manager 集成:

https://github.com/Alamofire/Alamofire

使用示例

import Alamofire

func loadArticles(completion: @escaping ([Article]?) -> Void) {
    AF.request("https://example.com/api/articles")
        .validate()
        .responseDecodable(of: [Article].self) { response in
            switch response.result {
            case .success(let articles):
                completion(articles)
            case .failure(let error):
                print("请求失败:\(error)")
                completion(nil)
            }
        }
}


四、ViewModel 统一管理网络请求与状态(MVVM 架构)

将网络请求逻辑封装在 ViewModel 中,便于状态管理和 SwiftUI 绑定。

class ArticleViewModel: ObservableObject {
    @Published var articles: [Article] = []
    @Published var isLoading = false
    @Published var errorMessage: String?

    func fetchArticles() {
        isLoading = true
        errorMessage = nil

        loadArticles { [weak self] result in
            DispatchQueue.main.async {
                self?.isLoading = false
                if let result = result {
                    self?.articles = result
                } else {
                    self?.errorMessage = "加载失败"
                }
            }
        }
    }
}


五、构建绑定视图显示加载状态与数据

结合 SwiftUI 状态系统自动刷新界面:

struct ArticleListView: View {
    @StateObject private var viewModel = ArticleViewModel()

    var body: some View {
        NavigationStack {
            Group {
                if viewModel.isLoading {
                    ProgressView("加载中...")
                } else if let error = viewModel.errorMessage {
                    Text(error).foregroundColor(.red)
                } else {
                    List(viewModel.articles) { article in
                        VStack(alignment: .leading, spacing: 4) {
                            Text(article.title)
                                .font(.headline)
                            Text("作者:\(article.author)")
                                .font(.subheadline)
                                .foregroundColor(.gray)
                        }
                        .padding(.vertical, 4)
                    }
                }
            }
            .navigationTitle("文章列表")
            .onAppear {
                viewModel.fetchArticles()
            }
        }
    }
}


六、总结

技术点 实践意义
URLSession 理解底层网络请求流程
Codable 自动解析 JSON 数据,提高开发效率
Alamofire 简化请求流程、处理错误、自动解码
ObservableObject 管理异步状态并驱动视图刷新
SwiftUI 状态绑定 自动更新 UI,无需手动刷新
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容