请问如何使用Alamofire来全局处理一些事件?

发布于 2022-09-04 05:25:12 字数 154 浏览 20 评论 0

我们在做网络请求的时候,有很多相同的情况需要处理。
比如处理HTTP状态码,很多请求函数都需要处理遇到200、401、500...的情况,
我想把这些处理情况统一起来,每次调用Alamofire来进行网络请求的时候首先调用这个函数。
请问这种情况下怎么封装Alamofire?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你是年少的欢喜 2022-09-11 05:25:12

用 protocol 和 extension. 所有的 请求都实现 protocol, 就行了。让 protocol 的 extension 去实现公共的方法。

给你个例子:
协议文件

import UIKit
import Alamofire

public protocol RequestProtocol {
    var route: String { get }
    var parameters: [String: Any]? { get }
    var method: HTTPMethod { get }
}

extension RequestProtocol {
    var BaseUrl: String {
        return "http://api.chojer.com/"
    }
    
    var url: String {
        return BaseUrl + route
    }
    
    var encoding: URLEncoding {
        return method == .get || method == .head || method == .delete ? URLEncoding.default : URLEncoding.httpBody
    }
    
    var headers: [String: String] {
        return [
            "Accept":"application/json",
            "Api-token": LoginViewController.info.user.token,
            "Api-Device": Sys.shared.device,
            "Api-Os-Name": "IOS",
            "Api-Os-Version": UIDevice.current.systemVersion,
            "Api-Network-Status": ApplicationLunch.networkingStatus,
            "Api-Version": "\(Sys.shared.build)"
        ]
    }
    
}

网络请求封装


import Foundation
import Alamofire
import SwiftyJSON

class RequestProvider {
    
    var target: RequestProtocol!
    
    init(target: RequestProtocol) {
        self.target = target
    }
    
    
    func response(success: ((_ json: JSON)-> Void)? = nil, error: ((_ code: Int)-> Void)? = nil, complete: (()-> Void)? = nil) {
        Alamofire.request(target.url, method: target.method, parameters: target.parameters, encoding: target.encoding, headers: target.headers)
            .responseData { (response) in
                switch response.result {
                case .failure:
                    Notify.whistle(status: NotifyStatus.warning, msg: "网络请求失败,请稍后再试")
                    if let errorEvent = error { return errorEvent(-999) }
                case .success(let data):
                    let json = JSON(data: data)
                    let errCode = json["errCode"].intValue
                    let errMsg = json["errMsg"].stringValue
                    let data =  json["data"]
                    if  errCode == 0 {
                        if let successEvent = success { return successEvent(data) }
                    } else {
                        if errCode == -2 {
                            NavigationController.defaultViewController.showDetailViewController(LoginViewController(), sender: nil)
                        }
                        Notify.whistle(status: NotifyStatus.danger, msg: errMsg)
                        if let errorEvent = error { return errorEvent(errCode) }
                    }
                }
                if let completeEvent = complete { return completeEvent() }
        }
    }
    
    func responseSuccess(success: ((_ json: JSON)-> Void)? = nil) {
        return response(success: success, error: nil, complete: nil)
    }
    
    func responseError(error: ((_ code: Int)-> Void)? = nil) {
        return response(success: nil, error: error, complete: nil)
    }
    
    func responseComplete(complete: (()-> Void)? = nil) {
        return response(success: nil, error: nil, complete: complete)
    }
    
}

具体的一个网络请求

import Foundation
import Alamofire

enum HomeRequestTarget: RequestProtocol {

    case index // GET    /photos
    case create // GET    /photos/create
    case store // POST    /photos
    case show() // GET    /photos/{photo}
    case edit // GET    /photos/{photo}/edit
    case update // PUT/PATCH    /photos/{photo}
    case destroy // DELETE    /photos/{photo}
    
    var route: String {
        return ""
    }
    var parameters: [String: Any]? {
        return nil
    }
    var method: HTTPMethod {
        return .get
    }
}

执行网络请求时,只需要这样访问就OK了。这样,如果遇到同样的网络请求错误信息,可以统一处理,也可以根据需要传入回调函数,进行错误处理。完美。

RequestProvider(target: HomeRequestTarget.index).responseSuccess { (json) in
            Notify.whisper(vc: self, status: NotifyStatus.success, msg: "登陆成功,欢迎回来")
            LoginViewController.update(json: json["user_info"])
            if json["version_info"].exists() {
                let confirm = ConfirmPopView()
                confirm.label(label: "检测到新的版本,建议您及时更新", confirmLabel: "确认更新", cancelLabel: "稍后提醒")
                confirm.proxy = self
                confirm.show()
            }
        }
请叫√我孤独 2022-09-11 05:25:12

自己封装一层呀,发送和返回时套一层自已的通用处理逻辑。
比如加密,带上 app 版本号之类的,以及接收数据后的解密,错误码处理等。
个人觉得你可以参考 Moya 的做法,自己写一个类似的。我觉得这种封装形式就很好。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文