У меня есть несколько классов, в которых есть код, который вызывает общий сетевой класс для вызова API GET. Ниже приведен пример одного из них:
public typealias Api1Result = (Result<Api1Model>) -> Void
private var path = "the/path/api1"
public enum Api1ServiceError: String, Error {
case error = "Sorry, the api1 service returned something different than expected"
}
extension Api1Model {
public static func getApi1(networkClient: NetworkClient = networkClient, completion: @escaping Api1Result) {
networkClient.getPath(path) { result in
switch result {
case .success(let data):
do {
let api1Model = try JSONDecoder().decode(Api1Model.self, from: data)
completion(.success(api1Model))
} catch {
completion(.failure(Api1ServiceError.error))
}
case .failure(let error):
completion(.failure(error))
}
}
}
}
Вот перечисление Результата, если интересно:
public enum Result<Value> {
case success(Value)
case failure(Error)
}
Существует несколько других классов моделей, и единственное отличие состоит в том, что декодируется фактический класс модели (в данном случае Api1Model
), а также типализации завершения (Api1Result
). Он делает то же самое с несколькими другими, просто вызывает метод networkClient.getPath()
, проверяет успех / неудачу и вызывает закрытие завершения.
Интересно, есть ли какие-нибудь эксперты по протоколам, которые могли бы помочь в упрощении этого и рефакторинге, чтобы у меня не было одинакового кода для нескольких классов?