Как сохранить объект Decodable.Protocol в переменную?

protocol
swift
ios

#1

Всем доброго времени суток! В моем приложении несколько контроллеров имеют очень похожую структуру кода, различия минимальны, поэтому для оптимизации я решил создать основу для этих контроллеров, а каждый конкретный контроллер наследовать от основы.

У меня имеется функция для отправки сетевых запросов и обработки ответа, в эту функцию я передаю структуру ответа в качестве параметра, для того, чтобы функция мне вернула готовую структуру ответа. Каждая такая структура Decodable.

Пример такой структуры:

struct APIAnswerUserActivity: Decodable {

let status: String

let code: Int?

let data: [UserActivity]?

let total: Int?

}

Функция для сетевых запросов, в качестве параметра jsonType принимается объект (структуру) типа Decodable.Protocol:

public func networkRequest<T: Decodable> (
url: String,
timeout: Double = 30,
method: URLMethods = .GET,
data: [String : String]? = nil,
files: [URL]? = nil,
jsonType: T.Type,
success: @escaping (T) -> Void,
failure: @escaping (APIError) -> Void
) -> URLSessionDataTask {}

В главном контроллере имеется несколько параметров, которые я переопределяю через override в дочерних контроллерах, один из таких параметров как раз должен быть объект типа Decodable для правильной работы общей функции для получения данных. Структуры JSON ответа очень похожи, но все же немного различаются, общую структуру для них создать нельзя, т.к. данные все же немного разные.

Если в главном контроллере сделать так:

public var decodableType: Decodable.Type {

return APIAnswerUserActivity. self

}

То это будет работать, и переопределять типы можно, но вот сетевая функция такое не принимает, ей нужен объект именно Decodable.Protocol. Если у переменной decodableType указать тип Decodable.Protocol, то в неё уже нельзя добавить APIAnswerUserActivity.self, который спокойно принимается при вызове функции networkRequest.

Как быть в данной ситуации? Надеюсь, мне удалось правильно и понятно изложить суть своей проблемы. Спасибо!


#2

Правильно я понимаю, что у тебя приходят отличающиеся JSON,а ты хочешь под них запилить общий парсер?


#3

Можно сказать и так. Функция networkRequest (в классе для работы с сетью в моем приложении) как раз принимает параметр jsonType (дженерик Decodable), если все проходит успешно, то в замыкание success она отдаёт уже заполненную структуру того типа, который я передал в функцию. Посколько у всех контроллеров функционал практически ничем не отличается, функция получения данных из сети также работает одинаково, принимает лишь разные типы данных. Но вот как передать эту структуру при наследовании от общего контроллера, где прописаны все методы - не понимаю. Если сделать open var decodableType: Decodable.Type, то туда можно поместить любую структуру Decodable, но при передаче decodableType в качестве значения аргумента jsonType в функцию networkRequest компилятор ругается.


#4

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

Но даже без этого. У тебя будет провайдер, который является дженериком (или имеет дженерик функцию), которая возвращает нужную тебе модель.