精选文章

14. Alamofire 与 Moya

2020-06-10 · Alamofire

14. Alamofire 与 Moya

目标:统一请求结构、统一错误处理、接口定义清晰。

一、安装(SPM)

在 Xcode 添加:

https://github.com/Alamofire/Alamofire
https://github.com/Moya/Moya

二、Alamofire 基础请求

import Alamofire

struct Post: Decodable {
    let id: Int
    let title: String
}

AF.request("https://api.example.com/posts")
  .validate()
  .responseDecodable(of: [Post].self) { response in
      switch response.result {
      case .success(let list):
          print(list.count)
      case .failure(let error):
          print(error)
      }
  }

三、Alamofire 鉴权拦截

import Alamofire

final class AuthAdapter: RequestAdapter {
    private let tokenProvider: () -> String?

    init(tokenProvider: @escaping () -> String?) {
        self.tokenProvider = tokenProvider
    }

    func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
        var request = urlRequest
        if let token = tokenProvider() {
            request.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
        }
        completion(.success(request))
    }
}

let adapter = AuthAdapter(tokenProvider: { "your_token" })
let session = Session(interceptor: Interceptor(adapters: [adapter]))

session.request("https://api.example.com/profile")
    .validate()
    .response { response in
        print(response.response?.statusCode ?? 0)
    }

四、Moya Target 定义

import Moya

enum API {
    case posts
    case detail(id: Int)
}

extension API: TargetType {
    var baseURL: URL { URL(string: "https://api.example.com")! }

    var path: String {
        switch self {
        case .posts: return "/posts"
        case .detail(let id): return "/posts/\(id)"
        }
    }

    var method: Moya.Method { .get }
    var task: Task { .requestPlain }
    var headers: [String: String]? { ["Accept": "application/json"] }
    var sampleData: Data { Data() }
}

五、Moya 请求与解码

import Moya

struct Post: Decodable {
    let id: Int
    let title: String
}

let provider = MoyaProvider<API>()

provider.request(.posts) { result in
    switch result {
    case .success(let response):
        do {
            let list = try JSONDecoder().decode([Post].self, from: response.data)
            print(list.count)
        } catch {
            print(error)
        }
    case .failure(let error):
        print(error)
    }
}

六、选型建议

  • 接口定义复杂、多人协作:Moya
  • 只要轻量封装:Alamofire

框架只是工具,最终需要统一错误处理、鉴权注入、日志与重试策略。

JJ

作者简介

专注于内容创作、产品策略与设计实践。欢迎交流合作。

上一篇 下一篇