2016-06-27 26 views
2

Ich habe eine Klasse, die ich gerne öffnen und in eine Datei exportieren könnte. Es muss nicht bearbeitet werden - das ist einfach eine Möglichkeit, die CoreData-Datenbank von Teilobjekten mit anderen Benutzern meiner App zu teilen, daher glaube ich nicht, dass ich die Komplexität der Unterklasse NSDocument benötige.Export Klasse mit String & NSmage Eigenschaften zu Datei

Die Klasse ist ziemlich einfach, mit zwei Eigenschaften String und einem Dateinamen für eine NSImage, die auf ein Bild in der App Sandbox verweist.

Zuerst dachte ich an ein Dokumentenpaket, im Grunde ein Ordner mit den Bildern (falls erforderlich) und ein Plist mit den Zeichenfolgen und Bilddateinamen. Nun möchte ich eine Klasse erstellen, die nur zum Exportieren und Importieren verwendet wird und NSCoding verwendet, um die Bilder und Zeichenketten in einer Datei zu speichern.

Hier ist, was ich bin nicht sicher:

  • ist dies eine gute Idee? Fehle ich hier etwas? Kann ich ein Array von Objekten mit NSImage und String Eigenschaften in einer einzigen Datei speichern? Ich weiß, dass ich ein Bild ziemlich einfach speichern kann, aber kann ich sie in einem einzigen Dokument zusammenfassen? Ist NSCoding der Weg, dies zu tun?
  • Muss ich zuerst die NSImage zu NSData konvertieren?
  • Woher weiß mein Decoder, welcher Teil der Datei ein String ist und welcher Teil ein NSImage ist?

Ich habe meine Nachforschungen gemacht! Es gibt viele Informationen über das Speichern eines Bildes oder das Speichern einer NSDocument, aber ich möchte nur eine einfache Möglichkeit für Benutzer exportieren und importieren beliebige Daten in und aus dem Hauptdatenspeicher meiner Anwendung.

+0

Danke für die tollen Antworten. Für Menschen aus der Zukunft mit ähnlichen Fragen ist dies auch eine gute Ressource: http://shipster.com/ncscoding/ – glenstorey

Antwort

2

zu erhalten Unter Verwendung von NSCoding können Sie jede Klasse speichern, die integrierte Unterstützung hat Port für dieses Protokoll oder Sie fügen es hinzu. Sowohl NSImage als auch - natürlich - NSString entsprechen NSCoding. Sie haben einfach NSCoding Unterstützung für Ihre benutzerdefinierte Klasse hinzuzufügen, which is pretty simple:

- (void)encodeWithCoder:(NSCoder*)coder 
{ 
    [coder encodeObject:self.stringProperty forKey:@"String Property"]; 
    [coder encodeObject:self.imageProperty forKey:@"Image Property"]; 
} 

- (instancetype)initWithCoder:(NSCoder*)coder 
{ 
    self = [super init]; // or `-initWithCoder:, if it is supported 
    if (self) 
    { 
    self.stringProperty = [coder decodeObjectForKey:@"String Property"]; 
    self.imageProperty = [coder decodeObjectForKey:@"Image Property"]; 
    } 
    return self; 
} 

Wenn Sie Ihre Daten als Eigenschaftslistendatei zu speichern, können Sie nur Eigenschaftsliste Klassen verwenden. NSString is a property list, but NSImage is not - und natürlich ist Ihre benutzerdefinierte Klasse nicht. Sie müssen also Instanzen von NSImage und Ihre benutzerdefinierte Klasse in Instanzen von NSData konvertieren, da NSData eine Eigenschaftsliste ist. Sie können das mit - Trommelwirbel - NSCoding tun. Verwenden Sie einfach einen Keyed Archiver. Das Ergebnis von +archivedDataWithRootObject: (NSKeyedArchiver) ist eine Instanz von NSData. Der Weg zurück verwenden Sie NSKeyedUnarchiver.

Aber hier ist wenig Grund, das Dateiformat von Eigenschaftslisten zu wählen, wenn Sie es nicht mit generischen Eigenschaftslistentools bearbeiten möchten.

So antwortet direkt auf Ihr Qs:

ist dies eine gute Idee? Fehle ich hier etwas?

Es ist ok

kann ich ein Array von Objekten mit NSImage und String-Eigenschaften in einer einzigen Datei speichern?

Seit NSArray comforms zu NSCoding und ist eine Eigenschaft Liste, werden beiden Ansätze aus dem Kasten heraus arbeiten.

Ich weiß, dass ich ein Bild ziemlich leicht speichern kann, aber kann ich sie in einem einzigen Dokument bündeln?

Sie sind der Eigentümer der Datei und Sie definieren das Dateiformat. Fahre einfach fort.

Ist NSCoding der Weg, dies zu tun?

Ja.

Muss ich zuerst NSAmage in NSData konvertieren?

Nur wenn Sie eine Eigenschaftslistendatei speichern möchten.

1

Beide Optionen sollten gut funktionieren. Stellen Sie sicher, dass Sie einen verschlüsselten Archivierer verwenden, wenn Sie die Route NSCoding gehen.

Jede Option könnte auch mit einem Array von Objekten umgehen, Sie müssen nur Ihre Dateistruktur/Code bearbeiten, um zu prüfen und damit umzugehen.

Für die Dateioption wird das Bild nur ein Bild auf der Festplatte sein. Für die Kodierungsoption werden alles binäre Daten auf der Festplatte sein, aber das geschieht während des Kodierungsprozesses (wo Sie das Bild in Daten konvertieren).

Basierend auf der Struktur der Datei, die wahrscheinlich die Erweiterungen der Dateien im Paket sein würde. Für die Kodierungsoption sind es die Schlüsselnamen.

Beide Optionen sind für Benutzer identisch und in der Zukunft erweiterbar, je nachdem, welche Option Sie wählen. Ich erwarte, dass die Codierungsoption schneller und einfacher ist, um den Code zu schreiben.

1

Durch das Implementieren des NSCoding-Protokolls können Sie das von Ihnen beschriebene Objekt problemlos freigeben.

public required init!(coder:NSCoder) 
{ 
    self.busStopName = coder.decodeObjectForKey("busStopName") as? String 
    self.busStopID = coder.decodeIntegerForKey("busStopID") as Int 
    let lines: [String]! = coder.decodeObjectForKey("busLines") as? [String] 
    let photo: NSData = coder.decorDataForKey("photo") as? NSData 
} 

public override func encodeWithCoder(encoder: NSCoder) -> Void 
{ 
    encoder.encodeObject(self.busStopName, forKey:"busStopName") 
    encoder.encodeInteger(self.busStopID, forKey: "busStopID") 
    encoder.encodeObject(self.busLines, forKey: "busLines") 
    encoder.encodeDataObject(self.busStopImage, forKey: "photo") 
} 

Um eine UIImage aus NSData verwenden diese initializer

let image: UIImage = UIImage(data: <the nsdata decoded>) 

zu schaffen und die NSData von einem UIImage verwenden eine dieser UIKit Funktionen

UIImageJPEGRepresentation(::) UIImagePNGRepresentation(_:)