Récupérer la liset des clés des prefs

muqaddarmuqaddar Administrateur
10:59 modifié dans API AppKit #1
Salut,

Je n'arrive tout simplement pas à  récupérer la liste des clés de mes NSUserDefault.
J'ai essayé la méthode dictionary... mais ce n'est pas la bonne.

Et pas de "allKeys" sur les userdefaults !?

Réponses

  • BruBru Membre
    10:59 modifié #2
    Fais un dictionaryRepresentation pour transformer le userDefaults en NSDictionary.

    .
  • muqaddarmuqaddar Administrateur
    10:59 modifié #3
    J'ai fait cela ce matin, mais ça me renvoie des clés toute autres qui commencent par NS...
    Des sortes de constantes en fait, qui n'ont rien à  voir avec mes clés à  moi.
  • AliGatorAliGator Membre, Modérateur
    10:59 modifié #4
    C'est normal, c'est parce que ça fait l'union de tous les domaines.
    (ceux-là , de domaines)

    Faut lire la doc, des fois, hoksitan  ::)
  • muqaddarmuqaddar Administrateur
    janvier 2006 modifié #5
    dans 1136978277:

    C'est normal, c'est parce que ça fait l'union de tous les domaines.
    (ceux-là , de domaines)

    Faut lire la doc, des fois, hoksitan  ::)


    J'ai essayé cela aussi ce matin :
    NSDictionary* allKeysAndValues = [[NSUserDefaults standardUserDefaults] persistentDomainForName:@"com.monApp.Preferences"];
    


    Cela me renvoie tout un charabia, avec certaines clés à  moi, d'autres non, mais elles n'y sont pas toutes.

    Par ailleurs, je ne lis jamais la documentation, surtout pas, ça fatigue. Et pourquoi se compliquer la vie quand d'autres peuvent bosser pour nous, et nous donner la réponse toute cuite.
    Ce genre de propos m'irrite, surtout quand on a fouillé dans la doc trente minute, qu'on a testé 2 ou 3 méthodes et qu'on a p-e pas su complétement s'en servir, ou alors qu'on n'a pas compris tout simplement, ce qui est légitime.


  • AliGatorAliGator Membre, Modérateur
    janvier 2006 modifié #6
    dans 1136985577:

    Ce genre de propos m'irrite, surtout quand on a fouillé dans la doc trente minute, qu'on a testé 2 ou 3 méthodes et qu'on a p-e pas su complétement s'en servir, ou alors qu'on n'a pas compris tout simplement, ce qui est légitime.
    Ben si je t'ai dit ça c'est que moi pour répondre à  ta question j'ai tapé NSUserDefaults dans google (je suis sur PC là  j'ai pas la doc offline, donc je la consulte en ligne), et arrivé sur la page de la doc sur NSUserDefaults sur le site d'Apple, j'ai rapidement trouvé dictionaryRepresentation (pour m'apercevoir que Bru avait répondu et avait raison ;)). Alors j'ai vu ta réponse et je suis retourné dans la doc sur la fonction dictionaryRepresentation, et j'ai de suite eu la réponse à  propos des domaines.

    D'autant que quand j'ai eu le problème que tu as évoqué avec le setStringValue que je t'ai expliqué, j'ai cherché dans la doc Apple sur les bindings, et j'ai appris que ça fonctionnait en domaines, et tout. d'ailleurs c'est dit ici dans la doc sur la méthode de classe standarduserDefaults.

    Tu vois aussi qu'il y a le "Companion Document" expliquant tout de l'utilisation des UserDefaults qu'il est bon de lire les premières fois que tu utilises les UserDefaults, ça va de soi, pour capter comment ça marche. ;)

    Maintenant je ne dis pas qu'il ne m'es pas arrivé de poser des questions stupides pour lesquelles la réponse était quelquepart dans la doc. Bien sûr, ça arrive à  tout le monde, de louper ZE truc important dans la doc tellement on a le nez dans le guidon. 8)
    Mais bon d'une part j'ai pas dit ça méchamment, faut pas le prendre mal, et d'autre part je n'aurai pas dit ça si c'était la première de tes question à  laquelle j'ai pu répondre simplement en lisant la doc alors que je ne connaissais rien de la réponse avant que tu ne poses la question  ::)

    [EDIT]
    Tiens par exemple je viens de trouver en 5 minutes en relisant vite fait le début de le doc sur les NSUserDefaults et les NSDomains puis en lisant la doc de la classe NSUserDefault, que la réponse à  ta question semble se trouver ici si tu ne veux que la représentation des NSUserDefaults du domaine de ton appli uniquement, sans inclure le NSArgumentDomain et ni les NSGlobalDomain & co.
  • AliGatorAliGator Membre, Modérateur
    10:59 modifié #7
    Bon je ne peux pas vérifier car je n'ai pas de mac sous la main (sur PC au taf là ), mais donc pour finir à  mon avis c'est cette ligne là  que tu veux (je te mâche vraiment le travail, là , je t'ai montré toutes les étapes et je vais jusqu'à  te donenr la solution tout cru... c'est pas une bonne idée ça ça t'apprend pas à  chercher. M'enfin bon.)
    NSString* ident = [[NSBundle mainBundle] bundleIdentifier];<br />NSDictionary* dict = [[NSUserDefaults standardUserDefaults] persistentDomainForName::ident];
    

    Enfin si j'ai bien compris que tu veux récupérer un dictionnaire représentant les UserDefaults uniquement présents dans le domaine de ton appli, donc dans "com.tonappli.plist" en gros ;)
  • muqaddarmuqaddar Administrateur
    10:59 modifié #8
    dans 1136990472:

    Bon je ne peux pas vérifier car je n'ai pas de mac sous la main (sur PC au taf là ), mais donc pour finir à  mon avis c'est cette ligne là  que tu veux (je te mâche vraiment le travail, là , je t'ai montré toutes les étapes et je vais jusqu'à  te donenr la solution tout cru... c'est pas une bonne idée ça ça t'apprend pas à  chercher. M'enfin bon.)
    NSString* ident = [[NSBundle mainBundle] bundleIdentifier];<br />NSDictionary* dict = [[NSUserDefaults standardUserDefaults] persistentDomainForName::ident];
    

    Enfin si j'ai bien compris que tu veux récupérer un dictionnaire représentant les UserDefaults uniquement présents dans le domaine de ton appli, donc dans "com.tonappli.plist" en gros ;)


    Ali, tu viens de me donner le code que j'ai mis 3 messages plus haut, qui ne me renvoie pas les bons trucs... apparemment. :-) Je l'avais testé depuis 10h ce matin, après avoir essayé le dictionaryRepresentation. ;-)

    Moi je veux juste récupérer mes clés/valeurs... je n'ai pas le code sous la main, sinon j'aurais mis ce que ça me renvoie... mais mes clés n'y sont pas...

    Merci à  toi Ali de t'être penché sur mon problème, j'en reparlerai demain. ;-)
  • BruBru Membre
    10:59 modifié #9
    Calmez-vous les enfants.

    En fait, les NSUserDefaults servent à  tous le monde dans ton appli.
    Ils servent aussi bien à  NSWindow si tu sauvegardes automatiquement position et taille des fenêtres, à  NSTableView, NSDate, etc...

    Pour retrouver ses petits parmi tout ce bazar, soit :

    1. toutes les clés sont identifiables (par exemple, elles commencent toutes par un préfixe particulier). Dans ce cas, il suffit ensuite de filtrer les clés sur ce préfixe.

    2. toutes les clés ne sont pas mises à  la racine des NSUserDefaults, mais dans un dictionary qui lui se trouve à  la racine. Comme ça, il suffit de récupérer ce dictionary, puis de faire le allKeys... sur ce dernier !

    .
  • AliGatorAliGator Membre, Modérateur
    10:59 modifié #10
    dans 1137055133:
    En fait, les NSUserDefaults servent à  tous le monde dans ton appli.
    Ils servent aussi bien à  NSWindow si tu sauvegardes automatiquement position et taille des fenêtres, à  NSTableView, NSDate, etc...
    Ben oui c'est ce que j'ai mis plus haut aussi...

    Mais ce qui me trouble du coup c'est que dans certains posts Alex nous dit que ses clés n'y sont pas, dans le dico récupéré.
    Qu'il y ait des clés "en trop" c'est normal, il y en a plein qui sont gérées en interne, du autosaveName aux autres trucs.
    Mais qu'il manque des clés parmi celles qu'il a utilisé pour définir ses bindings dans IB (et poru lesquelles il a choisi d'utiliser le NSUserDefaults, comme on fait quasiment tout le temps, bien sûr), c'est déjà  plus étonnant.

    Alex faudrait que tu fasses un "defaults read" pour vérifier, à  la limite.
  • muqaddarmuqaddar Administrateur
    10:59 modifié #11
    Bonjour les papas,

    Voilà  ce que j'ai avec le persitentDomaineForName :

    [tt]allKeysAndValues : {
        NSNavBrowserPreferedColumnContentWidth = 186;
        NSNavLastRootDirectory = "/System/Library/Sounds";
        NSNavPanelExpandedSizeForOpenMode = "{518, 401}";
        "NSTableView Columns NSNavOutlineColumnSettings.v1" = (
            <040b7479 70656473 74726561 6d8103e8 84014084 8484084e 53537472 696e6701 8484084e 534f626a 65637400 8584012b 1c4e534e 61764469 73706c61 794e616d 6546696c 6550726f 70657274 7986>,
            225,
            <040b7479 70656473 74726561 6d8103e8 84014084 8484084e 53537472 696e6701 8484084e 534f626a 65637400 8584012b 184e534e 61764d6f 64446174 6546696c 6550726f 70657274 7986>,
            117
        );
        "NSTableView Sort Ordering NSNavOutlineColumnSettings.v1" = (
            <040b7479 70656473 74726561 6d8103e8 84014084 8484084e 53537472 696e6701 8484084e 534f626a 65637400 8584012b 1c4e534e 61764469 73706c61 794e616d 6546696c 6550726f 70657274 7986>,
            1
        );
        autosavePrefPanel = 2;
        soundNamePrefPanel = "/System/Library/Sounds/Ping.aiff";
    }[/tt]

    Mes 2 seules préférences que j'y vois sont les deux dernières. Où sont les 15 autres ?
    Mes prefs sont déclarés comme ça :

    [defaultPrefs setObject:[NSNumber numberWithFloat:0.00] forKey:@&quot;autosavePrefPanel&quot;];<br />	[defaultPrefs setObject:[NSNumber numberWithFloat:4.00] forKey:@&quot;imageResizingPrefPanel&quot;];
    



    Et le code pour récupérer les clés et certaines prefs qui commencent pas une string et fait un test dessus :

    - (IBAction)resetDialogs:(id)sender<br />{<br />	// here reset all dialogs key to default settings (BOOL false)<br />	NSDictionary* allKeysAndValues = [[NSUserDefaults standardUserDefaults] persistentDomainForName:@&quot;com.aquafadas.iDivePreferences&quot;];<br />	NSEnumerator* enumerator = [allKeysAndValues keyEnumerator];<br />	NSString* key = [NSString string];<br />	NSLog (@&quot;allKeysAndValues : %@&quot;, allKeysAndValues);<br />	while (key = [enumerator nextObject]) {<br />		NSLog (@&quot;key : %@&quot;, key);<br />		if ([[key substringToIndex:14]isEqualToString:@&quot;DontShowDialog&quot;]) {<br />		NSLog (@&quot;toto&quot;);<br />			[[NSUserDefaults standardUserDefaults] setValue:NO forKeyPath:key];<br />		}<br />	}<br />	<br />	// then show reset field when done<br />	[dialogsResetField setHidden:NO];<br />}<br />
    


    voili, voilou
  • AliGatorAliGator Membre, Modérateur
    janvier 2006 modifié #12
    Ah mais tu fixes les valeurs de tes defaults par le code, pas par binding alors ?
    et defaultsPrefs j'imagine que c'est [NSUserDefaults standardUserDefaults] ?

    Si tu fixes les valeur par le code, il faut peut-êter faire un synchronize après la modif de l'ensemble de tes clés, non ? Car le persistantDomainForName doit lire dans le fichier et pas en mémoire, de ce que je comprend... et donc il faut que les 2 soient synchronisés.
    Ca dépend comment est séparé ton code d'écriture et de lecture (pendant la même RunLoop ou pas).
    Cf cette page.

    Enfin c'est une piste, je sais pas si c'est dû à  ça mais c'est ce qui me semble le plus logique.

    (Il n'empêche que je n'arrive pas à  comprendre pourquoi tu as besoin de faire un parcours sur toutes tes clés de ton UserDefaults ? A la limite si tu veux grouper des clés, tu les mets toutes dans un "pseudo-tableau" en utilisant les keypath justement (des keyPath du genre "DontShowDialog.pref1", "DontShowDialog.pref2", etc.), non ?
  • muqaddarmuqaddar Administrateur
    10:59 modifié #13
    Salut Ali,

    Mes defaults sont fixées par le code dans le +initialize.
    Ensuite, c'est tout par bindings... :-)

    Je dois m'accomoder de preferences dans un programme nomées "DontShowDialogXXX", et ou XXX est un nombre. Je veux juste pouvoir les reseter dans mon preference panel justement, donc, il faut que je capte toutes les clés qui commencent par "DontShowDialog".

    J'ai essayé synchronize, ça n'apporte rien apparemment. :(

    Bon, sinon ton idée est bienvenue. Je vais faire un keyPath avec un dictionnaire : DontShoDialog.pref1... etc. Et il suffira de modifier le binding rapidement dans le prog principal... puis de le balayer par la suite.

    Merci à  toi.  :p
  • Eddy58Eddy58 Membre
    janvier 2006 modifié #14
    Il vaudrait mieux passer par le contrôleur pour que les changements soient pris en compte non ? :o
    [tt]
    [[[NSUserDefaultsController sharedUserDefaultsController] values] setValue:NO forKey:key];
    [/tt]
  • AliGatorAliGator Membre, Modérateur
    10:59 modifié #15
    Juste au passage si ça peut aider :
    Although NSUserDefaults should remain your primary programmatic interface to the user defaults, some circumstances require that you get and set the default values contained in an NSUserDefaultsController instance directly. For example, when implementing portions of your preferences window that don't directly interact with an existing binding, such as setting a font or choosing a directory path.


    (ça vient de là )

    m'enfin je reste persuadé que pour ton cas il vaut mieux faire un tableau "DontShowDialog" avec une valeur pour chaque dialogue que tu as, plutôt que de faire une recherche sur toutes les clés, qui me semble pas très propre comme solution ! ;)
  • muqaddarmuqaddar Administrateur
    10:59 modifié #16
    dans 1137079064:

    Juste au passage si ça peut aider :
    Although NSUserDefaults should remain your primary programmatic interface to the user defaults, some circumstances require that you get and set the default values contained in an NSUserDefaultsController instance directly. For example, when implementing portions of your preferences window that don?t directly interact with an existing binding, such as setting a font or choosing a directory path.


    (ça vient de là )

    m'enfin je reste persuadé que pour ton cas il vaut mieux faire un tableau "DontShowDialog" avec une valeur pour chaque dialogue que tu as, plutôt que de faire une recherche sur toutes les clés, qui me semble pas très propre comme solution ! ;)


    Je vais même faire un dictionnaire plutôt qu'un tableau... ;-)
Connectez-vous ou Inscrivez-vous pour répondre.