大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
网络与 API
iOS 网络层以 URLSession 为核心,生态中有 Alamofire 简化请求。对照 /roadmaps/ios「Networking」节点:REST JSON 是主流,GraphQL 在部分 App 中使用。
学习目标
- 用 URLSession 发起 GET / POST 并解析 JSON
- 封装 API Client,统一错误处理与解码
- 了解 Alamofire、认证头与 REST 最佳实践
- 对照 Spring Boot REST 与 React fetch
核心概念
URLSession 基础
import Foundation
enum APIError: Error, LocalizedError {
case invalidURL
case httpStatus(Int)
case decodingFailed
var errorDescription: String? {
switch self {
case .invalidURL: return "URL 无效"
case .httpStatus(let code): return "HTTP \(code)"
case .decodingFailed: return "JSON 解析失败"
}
}
}
struct APIClient {
let baseURL: URL
let session: URLSession
init(baseURL: URL, session: URLSession = .shared) {
self.baseURL = baseURL
self.session = session
}
func get<T: Decodable>(_ path: String, as type: T.Type) async throws -> T {
guard let url = URL(string: path, relativeTo: baseURL) else {
throw APIError.invalidURL
}
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Accept")
let (data, response) = try await session.data(for: request)
guard let http = response as? HTTPURLResponse else {
throw APIError.httpStatus(-1)
}
guard (200..<300).contains(http.statusCode) else {
throw APIError.httpStatus(http.statusCode)
}
do {
return try JSONDecoder().decode(T.self, from: data)
} catch {
throw APIError.decodingFailed
}
}
}
// 使用
let client = APIClient(baseURL: URL(string: "https://api.coderoadmap.local")!)
let tracks: [Track] = try await client.get("/api/tracks", as: [Track].self)
async/await 版 URLSession(iOS 15+)替代传统 completion handler,代码更清晰。
POST 与认证
func login(email: String, password: String) async throws -> AuthToken {
var request = URLRequest(url: baseURL.appendingPathComponent("/api/auth/login"))
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONEncoder().encode(["email": email, "password": password])
let (data, response) = try await session.data(for: request)
// 解析 token,存入 Keychain
return try JSONDecoder().decode(AuthToken.self, from: data)
}
Bearer Token 放在 Authorization 头;可封装 AuthenticatedClient 自动注入。
Alamofire 概览
// Alamofire 简化链式调用(需 SPM 引入)
AF.request("https://api.example.com/tracks")
.validate()
.responseDecodable(of: [Track].self) { response in
switch response.result {
case .success(let tracks): print(tracks.count)
case .failure(let error): print(error)
}
}
新项目若已全面 async/await,标准库 URLSession 往往足够;Alamofire 适合需要 Upload/Download 进度、复杂拦截的场景。
与 Java/Spring 或 React 对照
| iOS | Spring Boot | React |
|---|---|---|
| URLSession | RestTemplate / WebClient | fetch / axios |
| Codable | Jackson / Gson | JSON.parse |
| APIClient 封装 | @FeignClient / Service | API 模块函数 |
| Keychain Token | JWT + Redis Session | localStorage / Cookie |
| 后台传输 | — | Service Worker |
配合 spring-boot-essentials 自建 API,iOS 模拟器访问 localhost 需用 Mac IP 或 ngrok。
练习
- 封装
APIClient,对接 mock/api/tracks列表 - 实现 POST 登录,Token 写入 Keychain
- 处理 401 自动跳转登录页
小结
URLSession + Codable 是 iOS 网络标准组合。 下一课并发与响应式。见 ios-essentials。