Variable depuis l'AppDelegate

Bonjour,


 


je souhaite sauvegarder des paramètres lorsque l'utilisateur quitte l'application (et les restaurer au lancement). Mais je ne comprend pas comment récupérer des variables d'autres vu depuis l'AppDelegate...


 


Pour récupérer des variables de l'AppDelegate depuis d'autres vues aucun soucis.


En revanche en sens inverse, je ne comprend pas. J'ai tenté de faire avec le même principe mais j'obtient une erreur à  l'exécution.


 


​Ca doit être tout con, mais je ne trouve ni par moi même, ni en faisant des recherches...


 


Merci pour votre aide !


Réponses

  • Alf1996Alf1996 Membre
    juillet 2014 modifié #2

    Euh... Et tu as utilisé NSUserDefaults ? C'est fait pour çà . En plus tu pourras y accéder de n'importe quelle vue de ton application.

  • Joanna CarterJoanna Carter Membre, Modérateur
    juillet 2014 modifié #3

    Comme Alf, tu peux utiliser NSUserDefaults mais, si tu voulais avoir plusieurs groupes de paramètres, tu pourrais faire tes propres classes comme ci-suivant :



    @protocol Singleton <NSObject>

    + (instancetype)sharedInstance;

    + (id)allocWithZone:(NSZone *)zone;

    - (id)copyWithZone:(NSZone *)zone;

    @end


    //
    // AppPreferences.h
    // Projet
    //
    // Created by Joanna Carter on 31/07/2014.
    // Copyright (c) 2014 Carter Consulting. All rights reserved.
    //


    @interface AppPreferences : NSObject <Singleton>

    //@property (strong, nonatomic) propertyType property;

    ... // autres @propertys

    - (void)updateStorage;

    @end


    //
    // AppPreferences.m
    // Projet
    //
    // Created by Joanna Carter on 31/07/2014.
    // Copyright (c) 2014 Carter Consulting. All rights reserved.
    //

    #import "AppPreferences.h"

    @interface AppPreferences ()

    @property (strong, nonatomic, readonly) NSURL *storageURL;

    @property (strong, nonatomic, readonly) NSMutableDictionary *preferences;

    @end


    @implementation AppPreferences

    @synthesize storageURL = _storageURL;

    @synthesize preferences = _preferences;

    - (NSURL *)storageURL
    {
    if (!_storageURL)
    {
    NSArray *urls = [[NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask];

    _storageURL = urls.lastObject;
    }

    return _storageURL;
    }

    - (NSMutableDictionary *)preferences
    {
    if (!_preferences)
    {
    _preferences = [NSMutableDictionary dictionary];
    }

    return _preferences;
    }
    /*
    - (propertyType)property
    {
    return (propertyType) self.preferences[@...];
    }

    - (void)setProperty:(propertyType)property
    {
    self.preferences[@...] = property;
    }
    */
    - (void)updateStorage
    {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^
    {
    NSString *appPreferencesPath = [self.storageURL URLByAppendingPathComponent:@preferences.plist].path;

    [NSKeyedArchiver archiveRootObject:self.preferences toFile:appPreferencesPath];
    });
    }

    #pragma mark - Singleton implementations

    - (void)initialise
    {
    BOOL isDirectory = YES;

    if (![[NSFileManager defaultManager] fileExistsAtPath:self.storageURL.path isDirectory:&isDirectory])
    {
    NSError *error = nil;

    if (![[NSFileManager defaultManager] createDirectoryAtURL:self.storageURL
    withIntermediateDirectories:NO
    attributes:nil
    error:&error])
    {
    NSLog(@%s : Could not create directory for app preferences at %@, error = %@", __PRETTY_FUNCTION__, self.storageURL.path, error);
    }
    }

    NSString *appPreferencesPath = [self.storageURL URLByAppendingPathComponent:@preferences.plist].path;

    if ([[NSFileManager defaultManager] fileExistsAtPath:appPreferencesPath])
    {
    _preferences = [NSKeyedUnarchiver unarchiveObjectWithFile:appPreferencesPath];
    }
    else
    {
    self.preferences[NSStringFromClass([MyClass class])] = // valeur par défaut

    ... // autres

    [self updateStorage];
    }
    }

    + (instancetype)sharedInstance
    {
    static AppPreferences *instance;

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^
    {
    instance = [[super allocWithZone:nil] init];

    [instance initialise];
    });

    return instance;
    }

    + (id)allocWithZone:(NSZone *)zone
    {
    return [self sharedInstance];
    }

    - (id)copyWithZone:(NSZone *)zone
    {
    return self;
    }

    @end

  • TerflogagTerflogag Membre
    août 2014 modifié #4

    Merci pour vos réponses et désolé de répondre un peu tard.


     


    Effectivement NSUserDefault me parait pas mal. En revanche étant donner que ce que j'ai stocker s'avère être un NSMutable Array composer d'objet que j'ai crée je vais devoir les archiver un par un et les stocker dans un NSArray ? 


     


    Du coup, impossible de récupérer des variables d'une vue en créant une instance de celle ci comme on peut le faire avec l'AppDelegate ?


    J'avais initialement dans l'idée de récupérer les données que je souhaite stocker depuis l'AppDelegate puis de les stocker dans un fichier avec un simple writeToFile. Mais la solution avec NSUserDefault me permettra d'apprendre quelques chose de nouveau donc je vais plutôt me tourner vers celle ci je pense.


     


    @Joanna Carter : Un peu compliquer pour moi comme solution dans l'immédiat  je ne suis pas sure d'avoir bien saisie, je verrai ce genre de solution quand je serais un peu plus à  l'aise avec la programmation iOS.


  • Joanna CarterJoanna Carter Membre, Modérateur
    août 2014 modifié #5


    Effectivement NSUserDefault me parait pas mal. En revanche étant donner que ce que j'ai stocker s'avère être un NSMutable Array composer d'objet que j'ai crée je vais devoir les archiver un par un et les stocker dans un NSArray ? 




     


    Oui mais la méthode la meilleure est d'implémenter NSCoding sur tes classes. Du coup, tous les objets dans un NSArray seront "stocké" automatiquement.


     



     


     


  • AliGatorAliGator Membre, Modérateur
    Pour savoir comment implémenter NSCoding (comme te le conseille Joanna) et tout sur la sérialisation de données (pour stocker ton NSArray,e tc) : Archives and Serialization Programming Guide

    Pour tout savoir sur NSUserDefaults : Preferences and Settings Programming Guide (ne pas se focaliser sur la partie Settings.bundle il y a aussi des choses intéressantes sur comment marche NSUserDefaults et ce qu'on peut y stocker dedans)
  • TerflogagTerflogag Membre
    août 2014 modifié #7

    J'ai finalement implanter le protocole NSCoding sur ma classe (simplement les deux méthodes), puis utiliser NSUserDefaults par la suite. Tout fonctionne parfaitement ! 


     


    Au passage, si quelqu'un tombe sur ce topic et à  eu les mêmes soucis que moi j'ai trouvé un tuto assez simple pour l'utilisation de NSCoding et NSUserDefaults que voici : http://sam.roon.io/archiving-objective-c-objects-with-nscoding


     


    Merci pour votre précieuse aide, sujet résolu ! :)


  • Joanna CarterJoanna Carter Membre, Modérateur
    août 2014 modifié #8

    Le code que tu as trouvé, c'est pas du tout bon. Je l'ai modernisé au normes d'Objective-C 2.0 avec ARC :



    //
    // Note.h
    // Test
    //
    // Created by Joanna Carter on 04/08/2014.
    // Copyright (c) 2014 Joanna Carter. All rights reserved.
    //


    @interface Note : NSObject <NSCoding>

    @property (nonatomic, copy) NSString *title;

    @property (nonatomic, copy) NSString *author;

    @property (nonatomic, getter = isPublished) BOOL published;

    @end


    //
    // Note.m
    // Test
    //
    // Created by Joanna Carter on 04/08/2014.
    // Copyright (c) 2014 Joanna Carter. All rights reserved.
    //


    #import "Note.h"


    @implementation Note

    - (id)initWithCoder:(NSCoder *)decoder
    {
    self = [super init];

    if (self)
    {
    _title = [decoder decodeObjectForKey:@title];

    _author = [decoder decodeObjectForKey:@author];

    _published = [decoder decodeBoolForKey:@published];
    }

    return self;
    }

    - (void)encodeWithCoder:(NSCoder *)encoder
    {
    [encoder encodeObject:_title forKey:@title];

    [encoder encodeObject:_author forKey:@author];

    [encoder encodeBool:_published forKey:@published];
    }

    @end

    ... et voilà  ! Beaucoup plus facile et lisible 


  • AliGatorAliGator Membre, Modérateur
    Yep, ton tuto date de 2010, il y a eu bcp de progrès en ObjC depuis :)
  • C'est le problème de Google, beaucoup de recherches vieillissent et dans certaines sphères c'est très pénalisant. J'ajoute systématiquement des critères de date dans mes recherches sur des exemples de code.


  • Je fais en général de même, mais parfois aucune recherche ne correspond. 


     


    Je vais modifier ça du coup :)


     


    Ceci dis, même avec un code aussi vieux tout fonctionne parfaitement. Je n'ai d'ailleurs pas vraiment saisie la différence entre les deux codes : la notation avec "_" m'est encore inconnue... Je vais m'y pencher dessus ! Un des inconvénients d'apprendre un nouveau langage seul, je ne sait jamais pas ou commencer, surtout quand je mène plusieurs projet de front le temps manque un peu pour faire tout ça correctement.


  • samirsamir Membre
    août 2014 modifié #12

    Voici un lien d'un document Apple pour moderniser le code Objective C, il contient pas tout mais il faut vraiment le lire.


    https://developer.apple.com/library/prerelease/ios/releasenotes/ObjectiveC/ModernizationObjC/AdoptingModernObjective-C/AdoptingModernObjective-C.html#//apple_ref/doc/uid/TP40014150


Connectez-vous ou Inscrivez-vous pour répondre.