Общий сетевой вызов с Alamofire и ObjectMapper - PullRequest
0 голосов
/ 10 декабря 2018

Я использую Alamofire и Alamofire Object Mapper для выполнения сетевого запроса и его сериализации.Мы всегда получаем наш ответ одинаковой формы со следующим примером, который включает результат, isSuccessfull и сообщение.

{
    "Result": {
        "WaitingCount": 0,
        "ApprovedCount": 0,
        "RejectedCount": 0
    },
    "IsSuccessfull": true,
    "Message": null
}

Я создал базовый класс для предотвращения дублирования кода с помощью следующего кода.

    struct BaseObjectResponseParser<T:Mappable>: Mappable {
    public var item: T?
    public var isSuccessful:Bool?
    public var message: String?
    init?(map: Map){
    }
    mutating func mapping(map: Map) {
        item <- map["Result"]
        isSuccessful <- map["IsSuccessfull"]
        message <- map["Message"]
    }
}

Затем для каждой модели я создал класс модели со следующими параметрами.

class UnitWorkOrdersCount: Mappable {
    var waitingCount: Int = 0
    var approvedCount: Int = 0
    var rejectedCount: Int = 0

    required init?(map: Map) {
    }

    func mapping(map: Map) {
        waitingCount <- map["WaitingCount"]
        approvedCount <- map["ApprovedCount"]
        rejectedCount <- map["RejectedCount"]
    }    
}

Я использую следующий фрагмент кода для выполнения сетевого вызова с сервера и сериализации ответа.

typealias HandlerGetUnitWorkOrdersCount = (UnitWorkOrdersCount?, _ message: String?) -> ()
func getUnitWorkOrdersCount(by identifier: Int, handler: @escaping HandlerGetUnitWorkOrdersCount) {
    let parameters: Parameters = ["identifier": identifier]
    Alamofire.request(URL_GET_UNIT_WORK_ORDER_COUNT, method: .get, parameters: parameters).responseObject { (response: DataResponse<BaseObjectResponseParser<UnitWorkOrdersCount>>) in
        switch response.result {
        case .success:
            if let result = response.result.value {
                if result.isSuccessful ?? false {
                    handler(result.item, nil)
                } else {
                    handler(nil, result.message)
                }
            }
        case .failure(let error):
            print(error)
            handler(nil, error.localizedDescription)
        }
    }
}

Однако у меня много сетевых запросов, и мой код дублируется приведенным выше кодом.Я пытаюсь сделать его общим, но не смог добиться успеха.Как сделать функцию networkRequest и мой обработчик завершения универсальными и предотвратить их дублирование?

1 Ответ

0 голосов
/ 10 декабря 2018

Вы можете попробовать сделать его общим, как показано ниже,

class MyService {

    public static func request<T: Mappable>(_ urlString: String,
                                            method: HTTPMethod,
                                            params: Parameters?,
                                            type: T.Type,
                                            completion: @escaping (T?, String?) -> Void) {

        Alamofire.request(urlString, method: method, parameters: params).responseObject { (response: DataResponse<BaseObjectResponseParser<T>>) in
            switch response.result {
            case .success:
                if let result = response.result.value {
                    if result.isSuccessful ?? false {
                        completion(result.item, nil)
                    } else {
                        completion(nil, result.message)
                    }
                }
            case .failure(let error):
                completion(nil, error.localizedDescription)
            }
        }
    }
}

Использование

MyService.request("urlPathString", method: .get, params: nil,
                  type: UnitWorkOrdersCount.self) { (unitWork, message) in
                    if let message = message {
                        print(message)
                        return
                    }
                    print(unitWork!.waitingCount)
}
...