У меня есть метод:
func getUsers(completion: @escaping (_ users: [User]?,_ error: String?)->()) { router.request(.getUsers) { (data, response, error) in
var users = [User]()
users = try JSONDecoder().decode(Array<User>.self, from: responseData)
}
Но я хочу сделать эту функцию более общей. Я пытался:
func getUsers<T: Decodable>(completion: @escaping (_ users: [T]?,_ error: String?)->()) { router.request(.getUsers) { (data, response, error) in
var users = [T]()
users = try JSONDecoder().decode(Array<T>.self, from: responseData)
completion(users, nil)
}
Но когда я вызываю этот массив пользователей func, чтобы избежать закрытия, он равен [_]. Если я просто использую только массив пользователей T, это [User.Type], и он не соответствует Decodable, поэтому я могу использовать JSONDecoder().decode. Как это должно выглядеть?





Array< User > is not convertible to '[_]?'
Это из-за типа _ пользователи: [T]?По желанию
Ваш метод работает нормально, вам просто нужно определить необязательный массив.
self.getUsers{ (res:Array<User>?, error) in
}
Я создал один похожий
func getUsers<T: Decodable>(completion: @escaping (_ users: [T]?,_ error: String?)->()) {
URLSession.shared.dataTask(with: URL(string: "test")!) { (data, res, error) in
guard let resData = data else {completion(nil,"data is nil"); return}
do {
var users = [T]()
users = try JSONDecoder().decode(Array<T>.self, from:resData)
completion(users, nil)
} catch {
completion(nil, error.localizedDescription)
}
}
И назови это
self.getUsers{ (res:Array<User>?, error) in
}
Вот структура
struct User :Codable {
var name:String?
}
@hds Для меня он работает с тем же, позвольте мне опубликовать код, попробуйте скопировать его и проверить
Окей я попробую
@hds Попробуйте скопировать, вставить все и просто скомпилировать
Я понял ! Спасибо
но у меня все еще есть эта проблема, если я передам следующий общий параметр в эту функцию
@hds Не понял, что значит следующий общий параметр, у него только один общий параметр
Привет, Hds, вы выполнили большую часть работы правильно, только один недостающий момент - это знания о том, как работают Decodables.
Массив Decodable также Decodable. Итак, я пытаюсь сказать, что вам не нужно явно указывать, что вы хотите декодировать Array<T>.self, вы можете поставить T.self, если вы перешли к функции, которую вы ожидаете от Array<T>.self, поэтому T => Array<T>
Итак, в вашем случае, когда вы вызываете эту функцию и передаете [User] в качестве универсального параметра, T будет Array<User>.self при декодировании. Вот как должен выглядеть код. Я не уверен, будет ли код компилироваться на 100%, потому что у меня есть некоторые недостающие компоненты, но он дает представление.
func get<T:Deocdable>(completion: @escaping (_ object: T?,_ error: String?) -> ()) {
router.request(.getUsers) { (data, response, error) in
do {
let object = try JSONDecoder().decode(T.self, from: responseData)
} catch {
fatalError("Decoding failed because: ", error.localizedDescription)
}
}
Также я добавил блок do catch, потому что try JSONDecoder() выбрасывает.
Также, чтобы добавить, как вы должны вызывать метод, он выглядит следующим образом:
get { (users: [User]?, error) in
}
Надеюсь это поможет.
Привет, спасибо за ответ, но у меня все еще есть ошибка: не удается преобразовать значение типа (Array <User>?, ) -> () к ожидаемому типу ([] ?, String?) -> () '