Dateipfad mit NSUserDefaults speichern?

M

michael m.

Aktives Mitglied
Thread Starter
Dabei seit
29.12.2006
Beiträge
407
Reaktionspunkte
6
Hallo,

in meinem kleinen Beispiel erforsche ich das speichern und laden von Systemeinstellungen mit Hilfe von NSUserDefaults.

Ich möchte einen Dateipfad speichern, den ich mit einem Dialogfenster ausgewählt habe.
Code:
// Liefert ein Array-Objekt mit den vollständigen Pfadnamen der ausgewählten Dateien
        NSArray *ladeURLs = [ladePanel URLs];
        // Da nur eine Auswahl möglich war, wird die erste Datei im Arrray ermittelt
        dateiPfadURL = [ladeURLs objectAtIndex:0];
        // Der Pfad wird in dem TextField ausgegeben
        [textfeldPfad setStringValue:[NSString stringWithFormat:@"%@", dateiPfadURL]];
       
        // speichert den Datenpfad auf der Festplatte im Preferences Verzeichnis
        NSUserDefaults *systemEinstellungen = [NSUserDefaults standardUserDefaults];
        [systemEinstellungen setURL:dateiPfadURL forKey:@"dateiPfadURL"];
        [systemEinstellungen synchronize];

Ich erhalte imTextfeld folgendes
file:///Users/michael/Desktop/Daten%20Programm/

Zum Laden der Systemeinstellungen habe ich folgenden Code geschrieben
Code:
// Laden der Programmeinstellungen für die SD-Karte
    NSUserDefaults *systemEinstellungen = [NSUserDefaults standardUserDefaults];
    dateiPfadURL = [systemEinstellungen valueForKey:@"dateiPfadURL"];
    // Der String wird im Label ausgegeben
    [textfeldPfad setStringValue:[NSString stringWithFormat:@"%@", dateiPfadSDURL]];
Im Textfeld erhalte ich dann folgendes
~/Desktop/Daten Programm

Die Variable dateiPfad habe ich als NSURL deklariert.
Beim speichern wird diese aber scheinbar als String abgespeichert?

In einer Version habe ich wohl ziemliche Probleme bekommen und hatte auch kauderwelsch in Pfade.
Kann hier der Grund dafür liegen?

Wäre schön wenn mir da jemand helfen könnte.

Vielen Dank
M.
 
~ ist die kurzform für /Users/xxxx

vielleicht solltest du mal die methoden von NSURL benutzen, um die URL dort raus zu bekommen, statt das NSURL objekt einfach einer string methode zu geben.
 
Vielleicht kannst mir da ein mehr bisschen erklären?
Die Variable habe ich als NSURL deklariert und sollte auch in diesem Format übergeben und gespeichert werden, also intern.
Lediglich für die Ausgabe in das Textfeld im Label wird es als String übergeben.
Die Darstellung mit der Tilde am Anfang wäre mir auch lieber, wenn der Pfad ausgewählt wurde.
Ich habe auch noch nie einen Pfad in einem Programm gesehen die mit ///file beginnt.

Vielen Dank
M.
 
~ ist die kurzform für /Users/xxxx

vielleicht solltest du mal die methoden von NSURL benutzen, um die URL dort raus zu bekommen, statt das NSURL objekt einfach einer string methode zu geben.
Er meint das:
Code:
[textfeldPfad setStringValue:[NSString stringWithFormat:@"%@", dateiPfadSDURL]];
 
Ich habe jetzt verschiedene möglichketien Probiert und noch keine Lösung gefunden.
Code:
[textfeldPfad setNSURLValue:[NSURL  fileWithURL :dateiPfadSDURL];

Bei set* konnte keinen Befehl finden, der irgendetwas mit NSURL zu tun hat
Dann habe ich mit "setStringValue" weiter versucht und dann in der zweiten Klammer mit NSURL zu hantieren.
Code:
[textfeldSdKarte setStringValue:[NSURL  URLWithString:<#(nonnull NSString *)#> ];
Ich habe keine passende Methode gefunden, die eine NSURL entgegennimmt.
Alles läuft auf einen String hinaus.
 
Wenn eine Methode einen String erwartet solltest du auch einen übergeben und nicht eine NSURL, NSNumber oder was du sonst gerade hast, denn dann wird - (NSString *)description aufgerufen und das Ergebnis davon genommen, was oft nicht das ist was du möchtest.

Wie macht man jetzt einen String aus einer URL? Richtig man schaut in der Doku welche Methoden NSURL hat und ob eine davon einen String zurück gibt und mit etwas Glück ist das sogar das Ergebnis was man gerne hätte, wenn nicht schreibt man sich eine Methode oder noch besser eine Extension zu NSURL, NSNumber usw. und erstellt den String selbst.

Als nächstes solltest du also mal hier nachsehen.
https://developer.apple.com/library...s/#//apple_ref/occ/instp/NSURL/relativeString
 
OneOeight sagte oben ich solle NSURL Methoden benutzen.
Aber welche denn, ich kann keine finden.
Kann mir denn hier keiner einen Tipp geben.
Ausserdem habe ich in der Doku nachgeschaut auch da konnte ich nichts bezglich der NSURL Methoden finden.
 
Es fällt mir gerade schwer mich zu beherrschen, aber ich versuche es. Ich bezweifle, dass du in die Doku gesehen hast, bzw. dass du versucht hast dort etwas zu finden. Hast du den Link geklickt den ich gepostet habe? Hast du gesehen dass der zur Doku von NSURL führt, dass er sogar direkt zu einer Methode führt die relativeString heißt? Hast du dir die Mühe gemacht den Rückgabewert anzusehen? Oh Wunder das ist ein String. Könnte man den evtl. an eine Methode die einen String erwartet übergeben? Jetzt die Frage zum Verständnis: Was könnte wohl die Methode von NSURL Namens absoluteString zurück geben?

Ich weiß, dass aller Anfang schwer ist, aber wenn man nicht bereit ist ein wenig Eigeninitiative an den Tag zu legen, sollte man es lieber lassen. Es wird immer Fälle geben, bei denen dir keiner helfen kann, dann musst du die Doku lesen und auch verstehen, fang also direkt damit an.
 
so jetzt noch mal langsam:
was für ein typ objekt ist denn dateiPfadSDURL?
das ist doch ein NSURL objekt, oder nicht?
und wenn man dessen NSURL methoden nutzt sieht das so aus:
[dateiPfadSDURL relativeString]
das ist im code doch wesentlich besser als
Code:
[NSString stringWithFormat:@"%@", dateiPfadSDURL]
 
Ich weis das ich einiges Lernen und viel Üben muss, aber es ist nicht leicht, schon gar nicht in der Doku.
Vielleicht liegt mein Problem überhaupt nicht dort?

Ich wähle einen Ordner aus, der als Dateipfad der im Label angezeigt werden und in NSUserDefaluts gepsichert werden soll.
Dabei habe ich NSOpenPanel verwendet.
https://developer.apple.com/library...Class/#//apple_ref/occ/instp/NSOpenPanel/URLs
In dieser Doku finde ich nichts bezüglich der Angabe war zurückgegeben wird.
https://developer.apple.com/library...nandSavePanels/UsingtheOpenandSavePanels.html
In diesem Links ist ein Beispiel indem Rückgabewerte in ein Array zurückgeliefert werden. So habe ich es auch gemacht.
Ich bin davon ausgegangen, das NSURLs zurückgegeben werden und habe das auch so gehandhabt.
Warscheinlich funktioniert auch die Ausgabe in dem Label korrekt mit ///file....
Das speichern in NSUserDefaults klappt zwar, aber in der plist wird der Wert als String abgespeichert anstatt NSURL.
Dann gehe ich mal davon aus, das in dem Array keine NSURL zurückgegeben wird, sondern Strings.

Um dann im Label die richtige Darstellung zu bekommen, schaätze ich mal muss eine konvertierung nach NSURL gemacht werden und dann wieder in einen String?

Ich bin ja vielleicht ein bisschen dumm, aber nicht faul.
 
NSUserDefaults speichert die daten doch als XML datei (auch mal die datei inzwischen als binary plist sieht).
eigentlich ist auch egal wie NSUserDefaults die daten speichert, wichtig ist was du zurück bekommst, und das sind ja wohl keine strings, wenn du NSURL oder ein Array dort rein packst.

schau dir doch mal bitte die NSURL class reference noch mal genau an:
wenn du jetzt wirklich aus dem NSURL etwas mit
Code:
file://pfad
raus bekommen willst, dann bietet sich doch die methode absoluteURL an…
 
Ich bin davon ausgegangen, das NSURLs zurückgegeben werden und habe das auch so gehandhabt.
Warscheinlich funktioniert auch die Ausgabe in dem Label korrekt mit ///file....
Das speichern in NSUserDefaults klappt zwar, aber in der plist wird der Wert als String abgespeichert anstatt NSURL.
Dann gehe ich mal davon aus, das in dem Array keine NSURL zurückgegeben wird, sondern Strings.

Es wird ein Array von NSURL Instanzen zurück gegeben, das sieht man in der Swift Version der Doku besser.
Wenn du dir die URL mit - (NSURL *)URLForKey:(NSString *)defaultName holst, erhältst du eine NSURL da musst du also nicht weiter machen. Die kannst du dann nutzen um mit den entsprechenden Methoden dein Textfeld zu füllen.
Code:
NSURL *url = [systemEinstellungen URLForKey:@"dateiPfadURL"];
 
Hallo,

siehe unten für eine Kleine Einführung in "NSURL und ich"…

Viele Grüße

Code:
-(BOOL)someTest:(id)sender
{
    
    // …
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    if(fileManager == nil)
    {
    
        return NO;
    
    }

    // …
    
    NSArray *array = [fileManager URLsForDirectory:NSDownloadsDirectory
                                         inDomains:NSUserDomainMask];;
    
    if([array count] < 1)
    {
    
        return NO;
    
    }
    
    // …
    
    NSURL *URL = [array objectAtIndex:0];
    
    //
    
    NSLog(@"Ich bin eine lokale URL: %@ ", URL);
    
    // …
    
    if([URL isFileURL] == YES)
    {
    
         NSLog(@"… und ich zeige auf eine Datei/Ordner");
    
    }
    
    // …
    
    NSString *string = [URL path];
    
    if([string length] < 1)
    {
    
        return NO;
    
    }
    
    //
    
    NSLog(@"Als Dateipfad sehe ich so aus: %@ ", string);
    
    NSLog(@"… und so sollte ich dem Anwender gezeigt werden");
    
    // …
    
    URL = [NSURL fileURLWithPath:string];
    
    if(URL == nil)
    {
    
        return NO;
    
    }
    
    // …
    
    NSLog(@"Pfad zu URL konvertiert: %@ ", URL);

    // …
    
    return YES;
    
    // …

}
 
Ach, doch noch eine Frage an alle mit Rätselspass:

Warum sind es eigentlich /// bei der NSURL?

Viele Grüße
 
Wenn du die 3 / am Anfang meinst. file:// gehört zur File URI, der letzte / gehört zum Pfad, fängt als absoluter Pfad im root Verzeichnis an.
 
So also meine Erkenntis aus dem ganzen ist, das es in dem Array doch NSURLs zurückgegeben werden.
Code:
NSURL *dateiPfadSDURL = [ladeURLs objectAtIndex:0];
        NSLog(@"Die URL ist %@", dateiPfadSDURL);
gibt folgendes zurück
Die URL ist file:///Users/michael/Desktop/Projekte/Daten%20Programm/
Des weiteren erhalte ich mit
Code:
NSLog(@"Die URL als Pfad ist %@", [dateiPfadSDURL path]);
die Ausgabe von
Die URL als Pfad ist /Users/michael/Desktop/Projekte/Daten Programm

Wenn ich Dateien modifizieren, schieben, löschen usw, will dann arbeite ich mit NSURL
die mit file:/// beginnen und auch %20 im Dateinamen enthalten.
Wen ich dem Benutzer Pfade anzeigen lasen möchte, benutze ich die option Path, damit dieser
so dargestellt wird.

Die PList habe ich auch mal auf gemacht um zu sehen was drin steckt.
Bei der NSURL habe ich folgende information dirn gesehen.
Key = dateiPfadSDURL
Type = String
Value = ~/Desktop/Projekte/Daten Programm

und dabei ist es egal ob ich beim Speichern der NSUserdefault genommen habe
Code:
[systemEinstellungen setURL:dateiPfadSDURL forKey:@"dateiPfadSDURL"]
oder
[systemEinstellungen URLForKey:@"dateiPfadSDURL"];

ich hätte jetzt mal angenommen, das bei Type nicht String enthlten wäre, sondern NSURL oder URL?
 
der type bezieht sich ja auf den plist XML inhalt, nicht auf den objekt typ im programm code …
 
Wenn du die 3 / am Anfang meinst. file:// gehört zur File URI, der letzte / gehört zum Pfad, fängt als absoluter Pfad im root Verzeichnis an.
Das ist nicht die vollständige Lösung :p

Du hast vorne das Scheme, also "file". Danach folgt die Abtrennung "://" zum Host. Erst dann folgt der Pfad.
Dein Argument mit dem Wurzelverzeichnis trifft also immer zu. Auch bei "http" etc.

Apple schenkt sich einfach den host "localhost" in allen -fileURL.
Deshalb entstehen ///.

Viele Grüße
 
Die PList habe ich auch mal auf gemacht um zu sehen was drin steckt.
Bei der NSURL habe ich folgende information dirn gesehen.
Key = dateiPfadSDURL
Type = String
Value = ~/Desktop/Projekte/Daten Programm

und dabei ist es egal ob ich beim Speichern der NSUserdefault genommen habe
Code:
[systemEinstellungen setURL:dateiPfadSDURL forKey:@"dateiPfadSDURL"]
oder
[systemEinstellungen URLForKey:@"dateiPfadSDURL"];

ich hätte jetzt mal angenommen, das bei Type nicht String enthlten wäre, sondern NSURL oder URL?

Es ist doch egal was in der Plist steht…

-URLForKey: macht für Dich folgendes:

- hole den Wert "Meine URL" aus der Plist
- ist dieser Wert ein NSString/NSData?
- wenn ja, dann baue daraus eine URL
- liefere eine Instanz von NSURL zurück, wenn es klappt
- wenn es nicht klappt, dann bekommst Du nil

Kurzum:

Apple baut für die fertige Instanz. Im Prinzip musst Du nichts mehr machen.
Apple macht nichts anderes als was ich Dir oben mit "path" etc. gezeigt habe.

Probiere doch mal das:

Werfe einen Wert 1 als Integer für den Schlüssel "Meine Zahl" rein.
Hole dann von "Meine Zahl" die URL ab? Was kommt raus?

Viele Grüße
 
Nicht Apple schenkt sich den Host sondern der RFC 1738 Standard (klingt sonst ein wenig als würde Apple mal wieder machen sie wollen), aber mit dem Rest hast du recht.
 
Zurück
Oben Unten