Mam pewne podstawy w Swift, a teraz próbuję nauczyć się rozwoju IOS. Obecnie pracuję w małej aplikacji, która poprosi o zasób na interfejs API, które zrobiłem, które zwraca JSON wykonane z:

struct A : Codable {
    let name: String
    let age: Int
}

struct B : Codable {
    let something: String
}

Oba interfejsy API i aplikacji zdefiniowano te struct. Jak zawsze zapytam tego samego API, pomyślałem o owijaniu części, która poprosi o API niektóre zasoby i dekoduję, więc mam instancję struktury do użycia w moim wywołaniu zwrotnym. Oto ta metoda:

static func getContent(urlRequest: URLRequest, decodable: Decodable, completion: @escaping (Codable?, ErrorEnum?)->Void) {
    let config = URLSessionConfiguration.default
    let session = URLSession(configuration: config)

    let task = session.dataTask(with: urlRequest) {
        data, response, error in

        guard let data = data else {
            completion(nil, .noData) // Handling errors in an enum
            return 
        }
        let decoder = JSONDecoder()
        if let full = try? decoder.decode(decodable, from: data) {
            completion(full, nil)
        }
    }

    task.resume()
}

Mój problem dotyczy dekodowania parametry. Pokazuje błąd i zapobiec mi kompilacji aplikacji. Po znalezieniu niektórych zasobów na stackoverflow próbowałem zmienić parametry

static func getContent(urlRequest: URLRequest, decodable: Decodable.Type, completion: @escaping (Codable?, ErrorEnum?)->Void)

Próbowałem również utrzymać taki parametr, a zamiast tego zmień wewnątrz parametrów Decode

if let full = try? decoder.decode(decodable, from: data) {
    completion(full, nil)
}

Ale nic nie wydaje się spełniać kompilatora ... i patrząc na metodę decode wewnątrz Swift Code Source nie pomógł mi tak bardzo, jak wymaga T.Type where T is Decodable

Moim życzeniem ma być w stanie użyć tego zgodnie z następującymi:

static func getA() {
    guard let url = URL(string: "http://localhost/a") else { return }

    let urlRequest = URLRequest(url: url)
    getContent(urlRequest: urlRequest, decodable: A.self) {
        a, error in

        guard a = a else { return }
        print(a.name!)
    }
}

Czy masz jakiś pomysł, jak mogłem to osiągnąć? Naprawdę nie wiem, jak zadzwonić do tego typu parametrów lub co do wyszukiwania w Google, które może doprowadzić mnie do odpowiedzi (brak słownictwa).

Dziękuję Ci !

0
Zyigh 20 luty 2019, 19:23

1 odpowiedź

Najlepsza odpowiedź

Wypróbuj to po prostu dodaj generic .Type Codable i użyj swojego typu jako parametru, aby przejść foo.self

static func getContent<T: Codable>(urlRequest: URLRequest, decodable: T.Type, completion: @escaping (T?, ErrorEnum?)->Void) {
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)

let task = session.dataTask(with: urlRequest) {
    data, response, error in

    guard let data = data else {
        completion(nil, .noData) // Handling errors in an enum
        return
    }
    let decoder = JSONDecoder()
    if let full = try? decoder.decode(decodable, from: data) {
        completion(full, nil)
    }
}
task.resume()
}
1
Mohmmad S 20 luty 2019, 16:30