Не удалось преобразовать значение типа T.Введите в T

#swift #generics #alamofire #objectmapper

#swift #общие #alamofire #objectmapper

Вопрос:

Я пытаюсь создать универсальный метод, используемый AlamofireObjectMapper для отправки запроса, где ввод BasicMappable (общий тип), а вывод — ответ

 func sendRequest<T>(endPoint: String,
                    parameters: Parameters,
                    method: HTTPMethod,
                    mappingObject: T.Type) -> T where T : BaseMappable {
        var answer = T.self
        Alamofire.request(applicationBaseURL   endPoint,
                          method: method,
                          parameters: parameters,
                          headers: nil)
            .responseObject { ( response: DataResponse<T>) in
                let data = response.result.value
                answer = data as! T.Type
        }
        return answer as! T
    }
 

Поэтому я использую этот метод в VC следующим образом:

 let authResponse = requestHelper.sendRequest(endPoint: "/auth/users/create/",
                                             parameters: params,
                                             method: .post,
                                             mappingObject: AnswerClass.self)
 

И он хорошо строится.
Но когда я пытаюсь отправить запрос, у меня сбой и ошибка

 Could not cast value of type 'Travel.AuthController.AnswerClass.Type' (0x110186bf8) to 'Travel.AuthController.AnswerClass' (0x10de153b0).
2019-04-15 18:42:28.811494 0300 Travel[9951:596186] Could not cast value of type 'Travel.AuthController.AnswerClass.Type' (0x110186bf8) to 'Travel.AuthController.AnswerClass' (0x10de153b0).
 

Я уже делал это в VC с этим

 Alamofire.request(applicationBaseURL   "/auth/users/create/",
                                  method: .post,
                                  parameters: params,
                                  headers: nil)
   .responseObject { (response: DataResponse<AnswerClass>) in
                        let loginRespone = response.result.value
                        for error in loginRespone?.errors ?? [] {
                            print(error.detail)
                            print(error.source)
                            print(error.status)
                        }
 

И это работает хорошо

Но я хочу сделать этот метод универсальным для всего проекта

Как правильно привести значение этих типов или есть какие-либо другие способы?

Ответ №1:

Спасибо, @Kamran за вашу помощь!

Мое окончательное решение:

 class RequestHelper {
    func sendRequest<T>(endPoint: String,
                        parameters: Parameters,
                        method: HTTPMethod,
                        mappingObject: T.Type,
                        completion: @escaping (_ response: T?, _ error: Error?) -> Void) where T : BaseMappable {
        Alamofire.request(applicationBaseURL   endPoint,
                          method: method,
                          parameters: parameters,
                          headers: nil)
            .responseObject { ( response: DataResponse<T>) in
                switch response.result {
                case .success(let value):
                    completion(value, nil)
                case .failure(let error):
                    completion(nil, error)
                }
        }
    }
}
 

Комментарии:

1. Это совершенно нормально

Ответ №2:

Вам нужно использовать completionHandler , как показано ниже, чтобы получить объект,

 func sendRequest<T>(endPoint: String,
                    parameters: Parameters,
                    method: HTTPMethod,
                    mappingObject: T.Type,
                    completion: (T?, Error?) -> Void) {
    Alamofire.request(applicationBaseURL   endPoint,
                      method: method,
                      parameters: parameters,
                      headers: nil)
        .responseObject { ( response: DataResponse<T>) in
            switch response.result {
            case .success(let value):
                completion(value, nil)
            case .failure(let error):
                completion(nil, error)
            }

    }
}
 

Комментарии:

1. Статус @sigald 400 означает, что API не выполнен успешно. Вы не можете перейти к .success случаю, когда код ошибки равен 400. Можете ли вы предоставить больше информации о том, чего вы пытались достичь?

2. Так оно и есть. Например, «Пользователь с этим электронным письмом уже существует» .успех, но ошибка со статусом 400. Я не знаю почему. Спасибо за вашу помощь!