V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Livid
V2EX  ›  Swift

Alamofire 和 URLSession 的一个对比例子

  •  
  •   Livid · 2021-11-12 14:27:35 +08:00 · 1319 次点击
    这是一个创建于 867 天前的主题,其中的信息可能已经有所发展或是发生改变。

    https://medium.com/swift-programming/alamofire-vs-urlsession-a-comparison-for-networking-in-swift-c6cb3bc9f3b8

    同样的一个需求,用 AF 实现:

    AF.request("https://api.mywebserver.com/v1/board", method: .get, parameters: ["title": "New York Highlights"])
        .validate(statusCode: 200..<300)
        .responseDecodable { (response: DataResponse) in
            switch response.result {
            case .success(let board):
                print("Created board title is \(board.title)") // New York Highlights
            case .failure(let error):
                print("Board creation failed with error: \(error.localizedDescription)")
            }
    }
    

    用 URLSession 实现:

    enum Error: Swift.Error {
        case requestFailed
    }
    
    // Build up the URL
    var components = URLComponents(string: "https://api.mywebserver.com/v1/board")!
    components.queryItems = ["title": "New York Highlights"].map { (key, value) in
        URLQueryItem(name: key, value: value)
    }
    
    // Generate and execute the request
    let request = try! URLRequest(url: components.url!, method: .get)
    URLSession.shared.dataTask(with: request) { (data, response, error) in
        do {
            guard let data = data,
                let response = response as? HTTPURLResponse, (200 ..< 300) ~= response.statusCode,
                error == nil else {
                // Data was nil, validation failed or an error occurred.
                throw error ?? Error.requestFailed
            }
            let board = try JSONDecoder().decode(Board.self, from: data)
            print("Created board title is \(board.title)") // New York Highlights
        } catch {
            print("Board creation failed with error: \(error.localizedDescription)")
        }
    }
    
    2 条回复    2021-12-08 20:47:05 +08:00
    pupboss
        1
    pupboss  
       2021-11-24 10:55:28 +08:00
    其实 AF 只是替开发者执行了 let board = try JSONDecoder().decode(Board.self, from: data)

    然后 AF 使用了 Swift 语言特性 Result 类型,上面这个 AF 的例子过于简化了,实际项目也不会这么短的

    https://developer.apple.com/documentation/swift/result
    ming1016
        2
    ming1016  
       2021-12-08 20:47:05 +08:00
    可以搭配着 Combine 来用,assign 给 ViewModel 的数据属性和 SwiftUI 绑定在一起,响应式交互。
    ```swift
    URLSession.shared.dataTaskPublisher(for: req)
    .map { data, res in
    print(String(decoding: data, as: UTF8.self))
    return data
    }
    .mapError { _ in
    APISevError.resError
    }
    .decode(type: Request.Res.self, decoder: de)
    .mapError(APISevError.parseError)
    .receive(on: RunLoop.main)
    .eraseToAnyPublisher()
    ```
    绑定部分代码
    ```swift
    repStream = resSubject
    .map {
    $0.items
    }
    .assign(to: \.repos, on: self)
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3066 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 14:36 · PVG 22:36 · LAX 07:36 · JFK 10:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.