Проблема универсального метода Swift при передаче класса модели во вложенные методы - PullRequest
0 голосов
/ 31 января 2019

У меня есть ответ json в формате

ServerResponse -> ResponseData -> массив данных

 struct ServerResponse<T: Codable>: Codable {
    let methodName: String
    let responseCode: Int
    let responseMessage: String
    let responseData: ResponseData<T>

    enum CodingKeys: String, CodingKey {
        case methodName = "methodName"
        case responseCode = "responseCode"
        case responseMessage = "responseMessage"
        case responseData = "ResponseData"
    }
}

    struct ResponseData<T: Codable>: Codable {
        let order: Int
        let data: [T]

        enum CodingKeys: String, CodingKey {
            case order = "order"
            case data = "dataArray"
        }
    }

    struct Post: Codable {}
    struct Comment: Codable {}
    struct Comment: Codable {}

В моем ответе данные могут быть любымивид массива кодируемых классов, таких как Post, comment, Users и т. д.

Я создал несколько универсальных методов для анализа ответа

 func fetchGenericData2<T: Codable>(data: Data, completion: @escaping (T) -> ()) {
    self.fetchGenericData(data: data, completion: { (result:ServerResponse<T>) in
        print(result.responseData.data[0])
       // completion([result.responseData.data])
    })

}
func fetchGenericData<T: Codable>(data: Data, completion: @escaping (T) -> ()) {
    do {
        let responseObject = try JSONDecoder().decode(T.self, from: data)
        print(responseObject)
        completion(responseObject)
    } catch {
        print(error.localizedDescription)

    }
}

Я вызываю метод, передавая требуемый кодируемый класс

 self.fetchGenericData2(data: data, completion: { (response:[User]) in
                    print(response)
                })

В настоящее время моя общая модель не доходит до конечного метода, поэтому она не знает, какой это класс.

Если я отправлю окончательную модель напрямую, она будет работать нормально, какследующее:

 self.fetchGenericData(data: data, completion: { (response:ServerResponse<User>) in
                        print(response.responseData.data)
                    })

но в этом случае мне нужно отправить класс ServerResponse, который не является абстрагированным.

Как я могу отформатировать мои методы, чтобы мне просто нужно было вызвать метод с моим финальнымНазвание модели, и я получаю массив модели напрямую, например: что-то вроде этого:

 self.fetchGenericData(data: data, completion: { (response:[User]) in
                        print(response)
                    })

1 Ответ

0 голосов
/ 01 февраля 2019

Измените тип данных на T, чтобы он декодировал то, что передается,

struct ResponseData<T: Codable>: Codable {
    let order: Int
    let data: T

    enum CodingKeys: String, CodingKey {
        case order = "order"
        case data = "dataArray"
    }
}

Теперь он будет работать так, как ожидалось, когда вы вызываете его, как показано ниже,

 self.fetchGenericData(data: data, completion: { (response: ServerResponse<[User]>) in
                    print(response)
                })

Но если вам нужен синтаксис, в котором вы хотите передать только тип данных, вам нужно обновить общий метод, как показано ниже,

func fetchGenericData<T: Codable>(data: Data, completion: @escaping (T) -> ()) {
    do {
        let responseObject = try JSONDecoder().decode(ServerResponse <T>.self, from: data)
        print(responseObject)
        completion(responseObject)
    } catch {
        print(error.localizedDescription)

    }
}

Это позволит вам вызывать, как показано ниже,

self.fetchGenericData(data: data, completion: { (response: [User]) in
                    print(response)
                })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...