web-dev-qa-db-fra.com

Codable «n'a pas d'initialiseurs» dans Xcode 9.3 (Swift 4.1)

Après la mise à jour vers Xcode 9.3 (qui utilise Swift 4.1), le problème suivant a été trouvé:

  1. Créez un projet vide, ajoutez-y un nouveau fichier .Swift et créez deux nouvelles classes:

    Created to Codable classes

    class CodableOne: Codable {
    
        let some: String
    
    }
    
    class CodableTwo: Codable {
    
        var some: String
    
    }
    

    La construction réussit

  2. Ajoutez une nouvelle constante à CodableOne de type CodableTwo:

    Added a new constant to CodableOne

    class CodableOne: Codable {
    
        let some: String
        let another: CodableTwo
    
    }
    
    class CodableTwo: Codable {
    
        var some: String
    
    }
    

    La construction réussit

  3. Déplacez maintenant la classe CodableTwo vers un autre fichier (ViewController.Swift, par exemple)

    CodableTwo moved to another file

    La construction échoue .

Maintenant, il y a une erreur, qui ne disparaîtra pas. Codable les classes ne doivent pas nécessiter d'initialisation (comme démontré dans les étapes précédentes).

Toutes les idées sur ce qui pourrait être le problème derrière cela et comment il pourrait être résolu seront très appréciées!


P.S. Le problème n'est pas présent dans Xcode 9.2. Ni nettoyer le chemin du projet/build, ni la réinstallation de Xcode 9.3 n'aide.

37
EBDOKUM

Comme mentionné dans les commentaires , j'ai dû faire deux choses:

  1. changer le mode de compilation en module entier à l'intérieur Paramètres du projet/Paramètres de construction :

    Compilation Mode set to Whole Module

  2. réorganiser les fichiers sous Paramètres du projet/Phases de construction/Compiler les sources . Plus précisément, j'ai mis les fichiers qui avaient une erreur au début de la liste.

    Protip: si vous recherchez le nom du fichier et qu'il y a plus d'un résultat, faire glisser le fichier vers le haut dans cette liste plus petite le mettra toujours en avant.

24
Tamás Sengel

Il s'agit d'un bogue dans le Swift 4.1 compilateur. Pour contourner ce problème, effectuez les étapes décrites dans la réponse de the4kman, ou modifiez simplement let en var dans votre déclaration, en tant que tel:

class C1 : Decodable { 
  let str: String 
  // error: Class 'C1' has no initializers - if class C's `c1` is a let constant. 
}

class C : Decodable {
  var c1: C1 // << Change to `var`, compilation succeeds.
}

Solution avec l'aimable autorisation d'Apples Swift ingénieurs .

Si ni cette réponse ni la réponse à 4 km ne vous aident, vous pouvez ajouter un autre init aux modèles qui ne compileront pas. Si vos classes ont des tonnes de variables, plantez simplement le init pour satisfaire le compilateur. L'initialiseur Codable sera toujours synthétisé.

class C1: Decodable {
    let str: String

    @available(*, deprecated, message: "Do not use.")
    private init() {
        fatalError("Swift 4.1") 
    }
}
21
Oscar Apeland

j'ai eu ce problème même si toutes mes classes étaient dans le même fichier, l'utilisation de structures pour les plus profondes semble fonctionner

0
Hogdotmac