2016-02-03 13 views
5

Ich erstelle eine OS X-App, die Kerndaten, NSDocument, Storyboards und Cocoa-Bindungen verwendet.Wie binden Sie eine Storyboard-Ansicht an eine Core Data-Entität, wenn Sie NSDocument verwenden?

Meine Erwartung ist, dass die folgenden Ereignisse eintritt:

  1. Eine Instanz MyDocument (NSDocument Unterklasse) erstellt.

  2. MyDocument erstellt eine Core Data NSManagedObjectContext, die die Daten des Dokuments darstellt.

  3. MyDocument Instanziiert eine NSWindowController aus dem Storyboard durch seine Kennung.

  4. Innerhalb des Storyboards enthält der Fenstercontroller DocumentEditorViewController (NSViewController Unterklasse), der das Dokument anzeigt und bearbeitet.

  5. Im Storyboard, DocumentEditorViewController hat eine NSArrayController, die MyDocument ‚s verwaltete Objekt Kontext gebunden ist.

  6. Im Storyboard, DocumentEditorViewController hat eine Tabellenansicht, die auf die NSArrayController gebunden ist.

Auf diese Weise Änderungen in der Benutzeroberfläche an die ohne Klebstoff Code NSManagedObjectContext, den ganzen Weg machen.

Ich erwarte, dass dies unkompliziert ist, da ich glaube, dass ich diese Technologien so nutze, wie sie gedacht sind. Jedoch konnte ich die Bindungen nicht zum Laufen bringen, besonders in den Schritten 5 und 6. Alle von mir gefundenen Projektvorlagen und Beispielprojekte verwenden entweder keine Core-Daten, verwenden keine Storyboards oder verwenden sie nicht NSDokumente.

Welche Objekte sollen an welche gebunden werden? Was sollten NSArrayControllers Klasse, Schlüssel und Schlüsselpfad sein?

Eine andere Möglichkeit, diese Frage zu beantworten, besteht darin, auf ein funktionierendes Beispielprojekt hinzuweisen, das all diese Technologien zusammen verwendet.

+1

Sie verwenden einen separaten 'NSManagedObjectContext' für jedes Dokument? Ist das der empfohlene Weg in OSX/Dokumenten-basierten Apps? In (nicht dokumentenbasierten) iOS-Apps verwende ich normalerweise einen einzelnen Kontext (gehört dem Anwendungsdelegaten) und separate Instanzen von 'NSManagedObject' für jedes Modellobjekt ... –

+2

Ich sehe keine Beispiele oder Anleitungen von Apple, die deine Frage beantworten. Ich denke, dass separate Kontexte für verwaltete Objekte sinnvoller sind, da die Dokumente vollständig unabhängig sind. Es macht für mich keinen Sinn, ihre Daten in einen einzigen Kontext zu mischen und dann den gesamten Zugriff auf den Kontext für die Teilmenge der Daten der aktuellen Ansicht zu filtern. –

+1

Haben Sie einen Testfall ausprobiert, in dem Sie programmgesteuert ein paar MOC-Objekte hinzufügen und in der Tabellenansicht angezeigt werden? Es ist nicht klar, wenn Sie auf 5 & 6 verweisen, wenn Sie versucht haben, die Bindungen zu debuggen, und zwar unabhängig von der Fähigkeit des AC, Inhalte zu erstellen. – stevesliva

Antwort

11

Schritte zum Erstellen eines Beispielprojekts für Xcode Document-Based Application mit Core Data, Storyboard, NSArrayController, NSTableView und Bindings.

Schritt 1 Erstellen Sie ein Xcode-Projekt. Wählen Sie OS X Cocoa Application und wählen Sie "Storyboards verwenden", "Dokumentbasierte Anwendung erstellen" und "Core-Daten verwenden".

Schritt 2 Wählen Sie das Datenmodell aus. Fügen Sie die Entität 'Person' und die String-Attribute 'Name' und 'Adresse' hinzu.

Schritt 3 Wählen Sie Main.storyboard. Fügen Sie der View-Controller-Szene einen NSArrayController hinzu. Setzen Sie Mode auf 'Entity Name' und setzen Sie Entity Name auf 'Person'. Überprüfen Sie "Inhalt vorbereiten". Binden Sie Managed Object Context des Array-Controllers an View Controller, Modell Key Path representedObject.managedObjectContext.

Schritt 4 Gehen Sie zur Ansicht der View-Controller-Szene.Entfernen Sie "Ihren Dokumentinhalt hier". Fügen Sie eine NSTableView hinzu. Bind Content bis Array Controller, Controller Key arrangedObjects. Bind Selection Indexes bis Array Controller, Controller Key selectionIndexes. Bind Sort Descriptors an Array Controller, Controller Key .

Schritt 5 Bind Value der Textfelder in der Tabellenansicht zu Table Cell View, Modell Key Path objectValue.name und objectValue.address. Aktivieren Sie "Bedingungssätze editierbar".

Schritt 6 Fügen Sie zwei Schaltflächen "Hinzufügen" und "Entfernen" zur Ansicht der View-Controller-Szene hinzu. Verbinden Sie die Aktionen mit den Aktionen add: und remove: des Array Controllers.

Schritt 7 (Objective-C) Dokument.h auswählen. In Verfahren makeWindowControllers, REPLACE-Anweisung [self addWindowController:… durch

NSWindowController *aWindowController = [[NSStoryboard storyboardWithName:@"Main" bundle:nil] instantiateControllerWithIdentifier:@"Document Window Controller"]; 
[self addWindowController:aWindowController]; 
aWindowController.contentViewController.representedObject = aWindowController.document; 

Schritt 7 (Swift) Select Document.swift. In Verfahren makeWindowControllers, am Ende nach self.addWindowController(windowController) hinzufügen

windowController.contentViewController!.representedObject = windowController.document 

Schritt 8 Build-Run, Test.

+0

Ich wollte meine eigene Frage im Wesentlichen mit dem beantworten, was Sie gerade gepostet haben. Ich hatte zwei große Fehler in meinem Code nicht verwandt, aber der andere ist ein Problem mit der neuen Projektvorlage.Es überschreibt die didset-Methode der presidedObject-Eigenschaft, ohne KVC zu implementieren.Wenn Sie windowController.contentViewController! .representedObject setzen, funktioniert es gut, aber wenn Sie die cont entViewController zu dem Typ der Unterklasse Ihres Fenstercontrollers, es besiegt KVO und Sie erhalten den Fehler "Konnte keinen Vorgang ohne verwalteten Objektkontext ausführen". –

+0

Dies scheint für mich zu funktionieren, ohne die Auswahlindizes oder Sortierdeskriptoren in Schritt 4 zu binden. Können Sie beschreiben, warum diese notwendig sind? –

+1

Mit der Bindung von Auswahlindizes und Sortierdeskriptoren sind Auswahl und Sortierung des Array-Controllers und der Tabellenansicht synchronisiert. 'Select Insert Objects' des Array-Controllers, Sortieren durch Klicken in die Spaltenüberschriften und Bindungselemente einer Detailansicht auf die Auswahl des Array-Controllers funktioniert. – Willeke