Вы хотите передать тип структуры, а не протокол.
Сначала создайте общее ограничение для вашего метода, который говорит, что T
должен соответствовать Decodable
(поскольку он нужен только для декодирования,вам не нужно соответствовать Encodable
)
Затем скажите, что параметр должен иметь тип T.Type
- это позволяет компилятору выводить тип T
, вы можете избежать использованияэтот параметр см. в конце ответа
static func Get<T: Decodable>(codePoint: String, responseType: T.Type) { ... }
... так что T
будет типом, который вы передадите методу.
Тогда для JSONDecoder
'decode
метод использует тип T
JSONDecoder().decode(T.self, from: data)
, а затем, когда вы хотите вызвать свой метод, передайте тип вашей структуры, как вы это делали в декодировании
HttpRequests.Get(codePoint: "getCategoryList", responseType: Category.self)
Также обратите внимание, что ваш вызов асинхронный, поэтому для возврата данных вам понадобится обработчик завершения , определенный как параметр вашего метода
completion: @escaping (T?) -> Void
noteчто имена методов должны начинаться с маленьких заглавных букв
static func get<T: Decodable>(codePoint: String, responseType: T.Type, completion: @escaping (T?) -> Void) {
let urlString = UrlUtils.GetUrl(codePoint: codePoint)
let url = URL(string: urlString)
URLSession.shared.dataTask(with: url!) { data, response, error in
guard let data = data else {
print(error!)
return completion(nil)
}
do {
let decoded = try JSONDecoder().decode(T.self, from: data)
completion(decoded)
} catch {
print(error)
completion(nil)
}
}.resume()
}
HttpRequests.get(codePoint: "getCategoryList", responseType: Category.self) { response in
if let category = response {
...
}
}
Вы можетеn также избегайте использования параметра responseType
, поскольку тип T
может быть выведен из типа параметра закрытия завершения
static func get<T: Codable>(codePoint: String, completion: @escaping (T?) -> Void) { ... }
HttpRequests.get(codePoint: "getCategoryList") { (category: Category?) -> Void in ... }