2017-10-26 1 views
1

zu referenzieren Ich habe eine Funktion, die ich gerne wiederverwenden möchte und es einen Parameter einer Decocable Struktur akzeptieren. Zum Beispiel, ist dies eine Vereinfachung meines aktuellen Code ist (unter der Annahme „MyDecodableStruct“ ist eine Dekodierbare Struktur an anderer Stelle in der App erklärt):Wie eine generische Decodable Struktur in Swift 4

static func getResults(url: String, parameters: Parameters) { 
    // On success REST response 
    if response.result.isSuccess { 
     struct Results: Decodable { 
      let items: [MyDecodableStruct] 
     } 

     if let jsonResults = try? JSONDecoder().decode(Results.self, from: response.data!) { 
     //success 
    } 
} 

und anstatt zu sagen „MyDecodableStruct“, mag ich es ein Dekodierbare sein struct I gebe ich als Parameter ein. Etwas wie folgt aus:

static func getResults(url: String, parameters: Parameters, myStruct: Decodable) { 
    // On success REST response 
    if response.result.isSuccess { 
     struct Results: Decodable { 
      let items: [myStruct] 
     } 

     if let jsonResults = try? JSONDecoder().decode(Results.self, from: response.data!) { 
     //success 
    } 
} 

und ich kann es nennen wie

getResults(url: "url", parameters: nil, myStruct: MyDecodableStruct) 

ich nicht die Syntax herausfinden können, wie dies zu bekommen, obwohl zu arbeiten. Die Fehler, die ich bekomme, sind

Type 'Results' does not conform to protocol 'Decodable' 
Expected element type 

Irgendwelche Ideen auf den besten Weg, damit umzugehen?

Antwort

3

Wenn Sie einen Typ als Parameter übergeben möchten, müssen Sie den Typ des Parameters als Metatyp deklarieren. In Ihrem Fall ist es ein generischer Typ, der Decodable entsprechen muss.

So müssen Sie so etwas schreiben:

struct Results<Element: Decodable>: Decodable { 
    let items: [Element] 
} 
static func getResults<Element: Decodable>(url: String, parameters: Parameters?, myStruct: Element.Type) { 
    //... 
     // On success REST response 
     if response.result.isSuccess { 

      do { 
       let jsonResults = try JSONDecoder().decode(Results<Element>.self, from: response.data!) 
       //success 
       print(jsonResults) 
      } catch { 
       //Better not dispose errors silently 
       print(error) 
      } 
     } 
    //... 
} 

Swift sagt Typen können nicht in generischen Kontext verschachtelt werden, so zog ich es heraus auf die äußere nicht-generischen Kontext.

Nennen Sie es, wie:

getResults(url: "url", parameters: nil, myStruct: MyDecodableStruct.self) 
+0

Sehr hilfreich, danke! –

Verwandte Themen