#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. Я не знаю почему. Спасибо за вашу помощь!