Einstellungen speichern und wieder abrufen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Einstellungen speichern und wieder abrufen

    Hallo!

    Ich bin noch etwas neu in Objective-C und bin gerade dabei im MVC-Pattern folgendes zu Erreichen:

    Beim ersten mal starten der App, gibt es für die Einstellungen ein paar Default-Werte die gesetzt sind. Beim Schließen der App werden die Einstellungen in einer Datei gespeichert und beim nächsten Aufrufen ausgelesen und gesetzt.
    Dabei möchte ich nicht die NSUserDefaults dafür benutzen.

    Model: Preferences : NSObject
    View: PreferencesWindow (ist eine nib)
    Controller: PreferencesController : NSWindowController

    In meiner PreferencesWindow.nib habe ich ein Object gezogen, welches von der Model-Klasse Preferences ist.
    Dort habe ich die Bindings auf die entsprechenden Werte gesetzt.

    Beispiel:

    [Blockierte Grafik: http://imageshack.us/a/img842/8320/ujo9.png]

    Mein Model sieht so aus:

    Quellcode

    1. // Preferences.h
    2. @interface Preferences : NSObject
    3. {
    4. int _irgendeinRadioMenuTag;
    5. int _nochEinRadioMenuTag;
    6. NSString *_username;
    7. NSString *_password;
    8. BOOL _shouldDoThis;
    9. BOOL _shouldDoThat;
    10. }
    11. @property (nonatomic, assign) int irgendeinRadioMenuTag;
    12. @property (nonatomic, assign) int nochEinRadioMenuTag;
    13. @property (nonatomic, copy) NSString *username
    14. @property (nonatomic, copy) NSString *password;
    15. @property (nonatomic, assign) BOOL shouldDoThis;
    16. @property (nonatomic, assign) BOOL shouldDoThat;
    17. + (Preferences *) sharedPreferences;
    18. - (BOOL) loadDefaults;
    19. - (BOOL) saveDefaults;
    Alles anzeigen


    Quellcode

    1. // Preferences.m
    2. #import "Preferences.h"
    3. @implementation Preferences
    4. @synthesize irgendeinRadioMenuTag = _irgendeinRadioMenuTag;
    5. @synthesize nochEinRadioMenuTag = _nochEinRadioMenuTag;
    6. @synthesize username = _username;
    7. @synthesize password = _password;
    8. @synthesize shouldDoThis = _shouldDoThis;
    9. @synthesize shouldDoThat = _shouldDoThat;
    10. + (Preferences *) sharedPreferences
    11. {
    12. static Preferences *_sharedPreferences = nil;
    13. static dispatch_once_t onceToken;
    14. dispatch_once(&onceToken, ^{
    15. _sharedPreferences = [[self alloc] init];
    16. });
    17. return _sharedPreferences;
    18. }
    19. - (id) init
    20. {
    21. self = [super init];
    22. if (self) {
    23. }
    24. return self;
    25. }
    26. - (BOOL) loadDefaults
    27. {
    28. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    29. NSString *docDir = [paths objectAtIndex: 0];
    30. NSString *preferencesFile = [docDir stringByAppendingPathComponent: @"preferences.plist"];
    31. BOOL settingsExist = [[NSFileManager defaultManager] fileExistsAtPath:preferencesFile];
    32. if (settingsExist) {
    33. NSLog(@"Settings found!");
    34. NSMutableDictionary *defaultsDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:preferencesFile];
    35. _irgendeinRadioMenuTag = (int)[[defaultsDictionary objectForKey:@"irgendeinRadioMenuTag"] integerValue];
    36. _nochEinRadioMenuTag = (int)[[defaultsDictionary objectForKey:@"nochEinRadioMenuTag"] integerValue];
    37. _shouldDoThis = [[defaultsDictionary objectForKey:@"shouldDoThis"] boolValue];
    38. _shouldDoThat = [[defaultsDictionary objectForKey:@"shouldDoThat"] boolValue];
    39. _username = [defaultsDictionary objectForKey:@"username"];
    40. _password = [defaultsDictionary objectForKey:@"password"];
    41. }
    42. return settingsExist;
    43. }
    44. - (BOOL) saveDefaults
    45. {
    46. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    47. NSString *docDir = [paths objectAtIndex: 0];
    48. NSString *preferencesFile = [docDir stringByAppendingPathComponent: @"preferences.plist"];
    49. NSMutableDictionary *defaultsDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:preferencesFile];
    50. [defaultsDictionary setObject:[NSNumber numberWithInt:_irgendeinRadioMenuTag] forKey:@"irgendeinRadioMenuTag"];
    51. [defaultsDictionary setObject:[NSNumber numberWithInt:_nochEinRadioMenuTag] forKey:@"nochEinRadioMenuTag"];
    52. [defaultsDictionary setObject:[NSNumber numberWithBool:_shouldDoThis] forKey:@"shouldDoThis"];
    53. [defaultsDictionary setObject:[NSNumber numberWithBool:_shouldDoThat] forKey:@"shouldDoThat"];
    54. [defaultsDictionary setObject:_username forKey:@"username"];
    55. [defaultsDictionary setObject:_password forKey:@"password"];
    56. if ([defaultsDictionary writeToFile:preferencesFile atomically:YES]) {
    57. NSLog(@"Successfully wrote Settings to %@", preferencesFile);
    58. return YES;
    59. } else {
    60. NSLog(@"Failed to write Settings to %@", preferencesFile);
    61. return NO;
    62. }
    63. return NO;
    64. }
    65. @end
    Alles anzeigen


    Beim starten der Application passiert nun folgendes:

    Quellcode

    1. - (void) applicationDidFinishLaunching:(NSNotification *)aNotification
    2. {
    3. // _preferenceWindow ist einfach eine instanz variable von PreferencesController
    4. if (_preferenceWindow == nil) {
    5. _preferenceWindow = [[PreferencesController alloc] initWithWindowNibName:@"Preferences"];
    6. }
    7. [_preferenceWindow loadDefaults]; // verweist im controller selbst einfach auf [[Preferences sharedPreferences] loadDefaults]
    8. }
    9. - (void) applicationWillTerminate:(NSNotification *)notification
    10. {
    11. [_preferenceWindow saveDefaults];
    12. }
    Alles anzeigen


    1. Wie setze ich die Default-Werte? Kann ich das innerhalb des nibs machen?
    2. Muss ich die preferences.plist zuerst erstellen, bevor ich writeToFile benutzen kann? Oder erstellt er die dann automatisch?
    3. Da es später so sein wird, das es profil-optionen gibt, würde ich die einstellungen dazu gerne dem Usernamen zuordnen und mit in die preferences.plist einfügen. Sprich es sollte so aussiehen:

    [Blockierte Grafik: http://imageshack.us/a/img594/1416/t0n7.png]

    Wie würde ich, da beim Starten der Applikation immer der LETZTE eingeloggte User (mit seinem entsprechenden extraOption-Wert) auch im entsprechenden TextField wieder reingeladen werden sollte, dass hinkriegen?

    Ich hoffe ihr könnt mir etwas weiterhelfen :)

    Vielen Dank!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von mrtnbroder ()

  • Thallius schrieb:

    Und wiso muss das eigentlich ein singleton sein?


    Da ich auf die Variablen, die dort drin gespeichert sind, später noch drauf zugreife(n) wollte.

    Wieso? Gibt es einen anderen/besseren Weg?

    "Mike" schrieb:

    Da frag ich doch mal frech: Warum? Es klingt nämlich so, dass das User Einstellungen sind und die gehören in NSUserDefaults.


    Weil ich nicht genauen Einblick auf die NSUserDefaults habe. Also ich kann nicht eben schnell nachgucken, was dort drinne ist. Bei einer Datei, die auf der Festplatte liegt, schon.
    Deswegen würde ich gerne die Einstellungen irgendwo speichern, ohne auf diese Zuzugreifen.
  • mrtnbroder schrieb:

    Weil ich nicht genauen Einblick auf die NSUserDefaults habe. Also ich kann nicht eben schnell nachgucken, was dort drinne ist.

    Brauchst du doch auch nicht, du als Programmierer weißt doch was du in NSUserDefaults gespeichert hast. Und als Nutzer weißt du auch was du im Programm wie eingestellt hast wobei ohne das Programm diese Einstellungen eh uninteressant sind. Und im Falle des Falles könntest du dir die NSUserDefaults auch noch auf der Festplatte anschaun…du kennst das Schema wie und wo das gespeichert wird?
    [self setSignature:null];
    [[self postCount] increment];
  • Mike schrieb:

    mrtnbroder schrieb:

    Weil ich nicht genauen Einblick auf die NSUserDefaults habe. Also ich kann nicht eben schnell nachgucken, was dort drinne ist.

    Brauchst du doch auch nicht, du als Programmierer weißt doch was du in NSUserDefaults gespeichert hast. Und als Nutzer weißt du auch was du im Programm wie eingestellt hast wobei ohne das Programm diese Einstellungen eh uninteressant sind. Und im Falle des Falles könntest du dir die NSUserDefaults auch noch auf der Festplatte anschaun…du kennst das Schema wie und wo das gespeichert wird?


    Nein, kenne ich nicht. Bin doch noch neu ;)

    Okay dann nutze ich halt die NSUserDefaults dafür.

    Jetzt wäre aber immernoch die Frage, wo ich die defaults registriere und wie genau ich das mit den unterschiedlichen Usern hinbekomme, welche jeweils ja eine unterschiedliche extraOption haben?
  • Ein kleiner Exkurs zu NSUserDefaults aus dem Kopf eines Hobbyprogrammiers (nämlich mir)
    Da ich grad kein Xcode zur Hand hab: Keine Fehlerfreigarantie ;)

    Quellcode

    1. NSString* setting_one = [[NSString alloc] initWithString:@"Ich soll gespeichert werden"];
    2. NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
    3. //speichern:
    4. [userDefaults setObject: setting_one forKey:@"1. Einstellung"];
    5. //lesen:
    6. NSString* readSettingFromUserDefaults = [userDefaults objectForKey:@"1. Einstellung"];


    Gespeichert wird das unter ~/Library/Preferences/ in einer Datei die deinem Bundel-Identifier entspricht, z.B. com.apple.Safari.plist
    Das "~" ist der Verweis auf das Home-Verzeichniss des Users, ich hoffe du weißt das.
    [self setSignature:null];
    [[self postCount] increment];
  • Danke Mike, das hatte ich Gestern dann doch auch noch rausgefunden ;)

    habe seit gestern etwas mehr nachforschungen angestellt und mir unter anderem GCD, NSUserDefaults sowie ein paar andere Sachen angeschaut.

    Bin jetzt dabei alles in meiner App etwas umzustellen und hätte jetzt aber noch die Frage, ob das hier: stackoverflow.com/questions/84…-is-visible-to-subclasses

    ein guter weg ist, mit einer NSInteger variable zu arbeiten, die bei jeder aktion mit ihr um +1 erhöht wird.

    In meinem anderen Thread habe ich gelesen, dass das auch über das Notification Center gehen könnte. Bin nur am überlegen ob das nicht vielleicht zu kompliziert, bzw zu viel ist für diese einfache funktion/aktion.
  • mrtnbroder schrieb:

    Bin jetzt dabei alles in meiner App etwas umzustellen und hätte jetzt aber noch die Frage, ob das hier: stackoverflow.com/questions/84495…e-to-subclasses

    ein guter weg ist, mit einer NSInteger variable zu arbeiten, die bei jeder aktion mit ihr um +1 erhöht wird.


    Das kommt drauf an was deine NSInteger Variable darstellen soll. Ist dir denn klar, was static bedeutet? Hier hats mal jemand (hallo Macmoonshine ;)) erklärt: statische Variablen (Klassenvariblen)/statische Methoden im Sinne von Java

    Was genau hast du denn vor?
    [self setSignature:null];
    [[self postCount] increment];
  • Warum in Gottes Namen ließt du nicht erstmal ein Buch? Ist das so Out bei der heutigen Jugend?

    Alle fragen die du da stellst werden in jedem guten Grundlagenbuch zum OOP genauestens erklärt. Warum soll dir das hier jemand vorkauen? Kannst du dir so gar nicht selber helfen?

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    Warum in Gottes Namen ließt du nicht erstmal ein Buch? Ist das so Out bei der heutigen Jugend?

    Alle fragen die du da stellst werden in jedem guten Grundlagenbuch zum OOP genauestens erklärt. Warum soll dir das hier jemand vorkauen? Kannst du dir so gar nicht selber helfen?

    Gruß

    Claus


    Weil es schneller geht, nichts kostet und ich in einem Land lebe, in dem es nicht verboten ist Fragen zu stellen.

    Sorry, aber wenn du Probleme mit meinen Fragen hast dann kannst du auch genau so gut den Thread verlassen.

    edit: das ist jetzt nicht negativ gemeint, aber ich darf doch wohl noch fragen was ich will...
  • Sehr praktisch gedacht. Du investierst also lieber die Zeit von anderen als Deine eigene.

    Und ich darf ja wohl noch schreiben was ich will oder?

    Viel Spaß noch hier im Forum. Glaube viele Antworten wirst du mit der Einstellung nicht mehr bekommen

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    Sehr praktisch gedacht. Du investierst also lieber die Zeit von anderen als Deine eigene.


    Die Zeit invenstieren Sie, wie du auch, immer noch freiwillig. Niemand wird hier gezwungen zu antworten.

    @Mike

    In meiner App arbeite ich mit vielen GET/POST Request, die alle eine Request-ID mit sich tragen. Die Request-ID erhöht sich nach jedem Request. Deswegen denke ich, dass ich eine Statische Variable brauche, die sich, wie gesagt, nach jeden Request erhöht. :)
  • SteveJ schrieb:

    mrtnbroder schrieb:

    Weil es schneller geht, nichts kostet und ich in einem Land lebe, in dem es nicht verboten ist Fragen zu stellen.


    Kann mir mal schnell einer sagen wie spät es ist? Ich muss um 20 vor Acht los... 8o


    Na dann aber fix...

    Du bist schon zu spät :).

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • na klar geht das schneller, du hast ein problem und einer schreibt den fertig code hin
    du hast wieder ein problem, einer schreibt den fertigen code hin

    ob das dann mit deiner App dann insgesamt genau so schnell geht, ist ne andere geschichte und der Lernfaktor == nil ;)
    Ich weiß nicht immer wovon ich rede aber ich weiß das ich Recht habe. :saint:
  • mrtnbroder schrieb:

    In meiner App arbeite ich mit vielen GET/POST Request, die alle eine Request-ID mit sich tragen. Die Request-ID erhöht sich nach jedem Request. Deswegen denke ich, dass ich eine Statische Variable brauche, die sich, wie gesagt, nach jeden Request erhöht.

    Warum glaubst du denn die Request-ID zu benötigen bevor das Objekt instantiiert ist? Oder anders gefragt: Wann sollte man statische Variablen verwenden? In Objective C kann man nicht aus jeden Typ eine statische Variable machen, daher muss man manchmal andere Wege suchen die das Problem lösen. Ich denke aber, dass du hier gar keine statische Variable brauchst.

    beage schrieb:

    Bier hab ich noch da, Popcorn ist alle. PROST!

    Kekse? :P
    [self setSignature:null];
    [[self postCount] increment];