ios开发:封装alamofire
一,代码:
1,networkmanager
//
// NetworkingManager.swift
// helloworld2
//
// Created by liuhongdi on 2026/4/6.
//
import Alamofire
import Foundation
// 2. 封装网络请求类
class NetworkManager {
static let shared = NetworkManager()
// 基础配置:超时时间、拦截器等
private let session: Session = {
let configuration = URLSessionConfiguration.af.default
configuration.timeoutIntervalForRequest = 15
return Session(configuration: configuration)
}()
private let baseURL = "http://www.test.net"
/// 通用请求方法
/// - Parameters:
/// - path: 接口路径
/// - method: HTTP方法
/// - parameters: 参数
/// - completion: 成功与失败的回调
func request<T: Decodable>(
_ path: String,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
completion: @escaping (Result<T, AFError>) -> Void
) {
let url = baseURL + path
// 可以在这里统一添加 Header (如 Token)
let headers: HTTPHeaders = [
"Authorization": "Bearer your_token_here",
"Accept": "application/json"
]
session.request(url, method: method, parameters: parameters, encoding: URLEncoding.default, headers: headers)
.validate() // 验证状态码 200..<300
.responseDecodable(of: ApiResponse<T>.self) { response in
switch response.result {
case .success(let apiResponse):
print("manager中获取到数据:")
print(apiResponse)
// 这里可以根据业务 code 处理逻辑错误
if apiResponse.code == 200 {
let data = apiResponse.data
completion(.success(data))
} else {
// 封装自定义错误或直接返回
print("业务错误: \(apiResponse.msg)")
}
case .failure(let error):
print("manager中返回错误:")
completion(.failure(error))
}
}
}
}
2, 响应体model
import Foundation
// 使用泛型 T,并约束 T 必须符合 Decodable 协议
struct ApiResponse<T: Decodable>: Decodable {
let status: String
let code: Int
let time: String
let msg: String
let data: T // 这里可以是任何类型:List 结构体、单个对象、甚至是一个数组
}
3, viewmodel
import Foundation
import Alamofire
@MainActor // 确保 UI 更新在主线程
class PoemViewModel: ObservableObject {
@Published var poems: [Poem] = []
@Published var isLoading = false
@Published var currentPage = 0
@Published var isFull = false // 是否全部加载完毕
func fetchData(isRefresh: Bool=false) async {
// 如果正在加载或已加载完毕且不是刷新,则直接返回
if self.isLoading || (self.isFull && !isRefresh) { return }
if isRefresh {
self.isFull = false
self.currentPage = 0
}
self.isLoading = true
let destPage = self.currentPage+1
let path = "/list.php?p="+String(destPage)
print("当前请求接口:"+path)
NetworkManager.shared.request(path, method: .get) { (result: Result<PoemListData, AFError>) in
switch result {
case .success(let res):
if (isRefresh == true) {
self.poems = res.list
} else {
self.poems.append(contentsOf: res.list)
}
if res.pageinfo.current_page == res.pageinfo.pages {
print("isFull = true")
self.isFull = true
} else {
print("isFull = false")
}
self.currentPage = destPage
case .failure(let error):
print("网络请求失败: \(error.localizedDescription)")
}
}
self.isLoading = false
}
}
4,view
//
// ContentView.swift
// helloworld2
//
// Created by liuhongdi on 2026/3/28.
//
import SwiftUI
import Alamofire
struct ContentView: View {
@State private var message = "加载中..."
//@State private var poems: [Poem] = [] // 存储解析后的数组
// 初始化 ViewModel
@StateObject private var viewModel = PoemViewModel()
var body: some View {
NavigationStack {
VStack {
Text(message)
List {
if viewModel.isLoading && viewModel.poems.isEmpty {
ProgressView("加载中..")
}
ForEach(viewModel.poems){ poem in
NavigationLink(value: poem) {
PoemRow(poem: poem) // 进一步拆分出子视图
.onAppear() {
// 核心逻辑:如果当前行是数组最后一行,触发加载更多
if poem == viewModel.poems.last {
Task {
//let nextPage = viewModel.currentPage+1
await viewModel.fetchData(isRefresh: false)
}
}
}
}
}
}
.navigationTitle("唐诗鉴赏1")
.navigationDestination(for: Poem.self) { poem in
Mp3View()
}
// 调用逻辑
.task{
print("列表出现时的task")
await viewModel.fetchData(isRefresh: false)
}
.refreshable{
await viewModel.fetchData(isRefresh: true)
}
}
}
}
}
// 一行元素的view
struct PoemRow: View {
let poem: Poem
var body: some View {
HStack(spacing: 15) {
AsyncImage(url: URL(string: poem.image)) { image in
image.resizable().aspectRatio(contentMode: .fit)
} placeholder: {
Color.purple.opacity(0.1)
}
.frame(width: 60, height: 60)
.background(Color.purple)
.cornerRadius(8)
VStack(alignment: .leading){
Text(poem.title).font(.headline)
Text(poem.author).font(.subheadline).foregroundColor(.secondary)
}
}.frame(height:120)
}
}
#Preview {
ContentView()
}
二,测试效果:

浙公网安备 33010602011771号