Créer une couleur avec SwiftUI

Je cherche non pas à pêcher une couleur dans les ressources, mais à permettre à l’utilisateur de choisir une couleur, et, à un moment, je sauvegarde les composants dans les UserDefaults pour la recréer à la relance de l’application. j’ai, à un moment, dans une fonction qui fait ça, le code suivant :

var color: Color = Color(red: Double(red), green: Double(green), blue: Double(blue), opacity: 1.0)

à quoi Xcode me répond par une erreur de compilation avec

Type of expression is ambiguous without more context

Comment s’en sortir ? que veut-il pour s’affranchir de cette ambiguïté ?

Avec uniquement ta variable, je n’ai pas assez de contexte pour être sur. Que passes tu en paramètre, les variables à l’intérieur de chaque Double ? tu devrais les nommer autrement ce sont des mots réservés sur le principe. C’est peut être cela ton soucis. Mais je n’ai pas tout le contexte.

1 « J'aime »

Non, ce ne sont pas des mots réservés, la preuve :
guard let rrr = userDefault.object(forKey: « Red ») else {let red = 0.5}

guard let ggg = userDefault.object(forKey: "Green")  else {let green = 0.6}

guard let bbb = userDefault.object(forKey: "Blue") else {let blue = 0.7}

var acolor = Color(red: Double(rrr), green: Double(ggg), blue: Double(bbb), opacity: 1.0)

J’ai changé les noms, ça ne change rien à la réaction négative d’Xcode. Même erreur de compilation de sa part, « Type of expression ambiguous without more context » (à propos de l’appel à Color). Je précise que userDefault est défini plus haut comme étant UserDefaults.standard.

Bonsoir,

import SwiftUI

struct testColor {
    func declareColor() {
        let red = UserDefaults().double(forKey: "Red")
        let green = UserDefaults().double(forKey: "Green")
        let blue = UserDefaults().double(forKey: "Blue")
        var aColor = Color(red: red, green: green, blue: blue, opacity: 1.0)
    }
}

Le « object(forKey… » crée un objet de type Any, je pense que le problème vient de là.

Cordialement,
Nicolas

J’ai besoin de vérifier la présence d’un enregistrements dans les UserDefaults, car avant le premier lancement, il n’y a encore rien dans les préférences utilisateurs, et, seule object(forKey permet d’obtenir un optionnel. C’est pourquoi je caste les valeurs en Double au moment de l’appel à Color. Je vais vérifier ton idée qui fait sens, en effet.

Comme ceci, alors:

import SwiftUI

struct testColor {
    
    @AppStorage("red") var red: Double = 0.5
    @AppStorage("green") var green: Double = 0.4
    @AppStorage("blue") var blue: Double = 0.8
    
    func declareColor() {
        var aColor = Color(red: red, green: green, blue: blue, opacity: 1.0)
    }
}

Oui, mais ta rédaction est prévue pour s’exécuter avec des wrappers value qui n’ont pas cours la où je déclare la mienne. Voici le texte final de ma fonction :

guard let rrr = userDefault.object(forKey: « Red ») else {return Color.gray}

guard let ggg = userDefault.object(forKey: « Green ») else{return Color.gray}

guard let bbb = userDefault.object(forKey: « Blue ») else {return Color.gray}

let _rrr = rrr as! Double

let _ggg = ggg as! Double

let _bbb = bbb as! Double

let acolor: Color = Color(red: _rrr, green: _ggg, blue: _bbb, opacity: 1.0)

return acolor

Tu peux montrer plus de code pour comprendre pourquoi les AppStorage ne s’appliqueraient pas ?
(Une raison pourrait être qu’il faut au moins iOS xx mais ce n’est pas celle que tu évoques)
Merci
Nicolas

Le code en question n’est pas dans une View, mais dans un fichier Swift séparé. Dans une vue, les @AppStorage ont toute leur place; tu les retrouves dans les UserDefaults dont tu as l’habitude dans un fichier Swift à part.

En outre, les @AppStorage restent invariables (extrait de la doc développeur : " A property wrapper type that reflects a value from UserDefaults and invalidates a view on a change in value in that user default.")
Ce qui ne fait pas mon affaire.

Dans l’extrait de code que je t’ai montré, on est bien au sein d’une Struct dans un fichier séparé et pas dans une View

Je pense qu’il y maldonne; les AppStorage sont justement destinés à gérer des UserDefault; on peut donc changer la valeur d’une variable AppStorage et ça se reflètera dans le UserDefault. Au prochain démarrage de ton app, ou à la prochaine utilisation de ta Struct, c’est la nouvelle valeur qui sera appelée

Dans un fichier séparé, Xcode me répond toujours : « Property wrappers are not yet supported in top-level code »

Si tu le souhaites, montre nous plus de code (dont celui qui fait appel à ta couleur), pour trouver une solution, je suis certain qu’il y en une (au moins !)

Tes Property Wrappers n’est pas en dehors des accolades de ta classe ou ta structure par hasard ?

En tous cas, ils ne sont pas dans des vues, mais dans du code : il semble que ça passe mal. Mais j’ai résolu le problème en passant directement par les UserDefaults pour l’écriture, et par le @AppStorage pour la lecture…

Tu as tout à fait raison. Merci pour ta réponse qui m’a bien aidée.