2016-02-03 32 views
5

Sto costruendo un'app OS X che utilizza i dati principali, NSDocument, storyboard e associazioni Cocoa.Come si associa una visualizzazione dello storyboard a un'entità Core Data quando si utilizza NSDocument?

La mia aspettativa è che si verifica quanto segue:

  1. viene creata un'istanza di MyDocument (NSDocument sottoclasse).

  2. MyDocument crea un Core Data NSManagedObjectContext che rappresenta i dati del documento.

  3. MyDocument crea uno NSWindowController dallo storyboard tramite il suo identificatore.

  4. All'interno dello storyboard, il controller della finestra contiene DocumentEditorViewController (sottoclasse NSViewController) che visualizza e modifica il documento.

  5. All'interno dello storyboard, DocumentEditorViewController ha un NSArrayController che è destinato a MyDocument 's contesto oggetto gestito.

  6. All'interno dello storyboard, DocumentEditorViewController ha una vista tabella associata a NSArrayController.

In questo modo tutte le modifiche nell'interfaccia utente rendono tutto fino alla NSManagedObjectContext, senza alcun codice di colla.

Mi aspetto che questo sia semplice, poiché credo che sto utilizzando queste tecnologie nel modo in cui sono destinate. Tuttavia, non sono riuscito a far funzionare i binding, in particolare ai passaggi 5 e 6. Tutti i modelli di progetto e i progetti di esempio che ho trovato non utilizzano Core Data, non usano storyboard o non usano NSDocuments.

Quali oggetti devono essere associati a quali? Quale dovrebbe essere la classe, le chiavi e il keypath di NSArrayController?

Un altro modo per rispondere a questa domanda è indicare un progetto campione funzionante che utilizzi tutte queste tecnologie insieme.

+1

Si sta utilizzando un separato 'NSManagedObjectContext' per ogni documento? È il modo consigliato in OSX/app basate su documenti? Nelle app iOS (non basate su documenti), di solito utilizzo un singolo contesto (di proprietà del delegato dell'app) e separate istanze di 'NSManagedObject' per ogni oggetto del modello ... –

+2

Non vedo alcun esempio o guida da Apple che risponde alla tua domanda. Penso che i contesti degli oggetti gestiti separati abbiano più senso perché i documenti sono completamente indipendenti. Non ha senso per me mescolare i loro dati in un singolo contesto e quindi dover filtrare tutti gli accessi al contesto per il sottoinsieme di dati della vista corrente. –

+1

Hai provato un testcase in cui aggiungi alcuni oggetti MOC a livello di codice e vedi la tabella? Non è chiaro quando fai riferimento a 5 e 6 se hai provato a eseguire il debug dei binding separati dalla capacità dell'AC di creare contenuti. – stevesliva

risposta

11

Procedura per creare un progetto di applicazione basato su documenti Xcode di esempio con Core Data, Storyboard, NSArrayController, NSTableView e Bindings.

Passaggio 1 Creare un progetto Xcode. Scegli OS X Cocoa Application e seleziona "Usa Storyboard", "Crea applicazione basata su documenti" e "Utilizza dati principali".

Passaggio 2 Selezionare il modello di dati. Aggiungi entità 'Persona' e attributi stringa 'nome' e 'indirizzo'.

Passaggio 3 Selezionare Main.storyboard. Aggiungi un controller NSArray alla scena del controller di visualizzazione. Impostare Modalità su 'Nome entità' e impostare Nome entità su 'Persona'. Seleziona "Prepara contenuto". Legare Managed Object Context del controller di array a View Controller, Percorso chiave modello representedObject.managedObjectContext.

Passaggio 4 Passare alla vista della scena del controller di visualizzazione.Rimuovi il contenuto del tuo documento qui. Aggiungi un NSTableView. Legare Content a Array Controller, Chiave controller arrangedObjects. Legare Selection Indexes a Array Controller, Chiave controller selectionIndexes. Legare Sort Descriptors a Array Controller, Chiave controller sortDescriptors.

Fase 5 Bind Value dei campi di testo nella vista tabella per Table Cell View, Modello Percorso chiave objectValue.name e objectValue.address. Seleziona "Imposta condizionatamente modificabile".

Passaggio 6 Aggiungere due pulsanti 'Aggiungi' e 'Rimuovi' alla vista della scena del controller della vista. Collegare le azioni alle azioni add: e remove: del controller di array.

Passaggio 7 (Objective-C) Selezionare Documento.h. Nel metodo makeWindowControllers, sostituire dichiarazione [self addWindowController:… da

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

Passo 7 (Swift) Select Document.swift. Nel metodo makeWindowControllers, alla fine dopo self.addWindowController(windowController) aggiungere

windowController.contentViewController!.representedObject = windowController.document 

Passo 8 creare, eseguire, Test.

+0

Stavo per rispondere alla mia stessa domanda con fondamentalmente ciò che hai appena pubblicato. Avevo due errori principali nel mio codice. non correlato, ma l'altro è un problema con il nuovo modello di progetto. Esegue l'override del metodo didSet della proprietà representObject senza implementare KVC. Se si imposta windowController.contentViewController! .presententedObject, funziona correttamente, ma se si esegue il cast del cont. entViewController per il tipo di sottoclasse del controllore di finestre, sconfigge KVO e si ottiene l'errore "Impossibile eseguire l'operazione senza un contesto oggetto gestito". –

+0

Questo sembra funzionare per me senza vincolare gli indici di selezione o gli ordinatori di ordinamento nel passaggio 4. Puoi descrivere perché sono necessari? –

+1

Con il binding di indici di selezione e descrittori di ordinamento, la selezione e l'ordinamento del controller di array e della vista tabella sono sincronizzati. 'Seleziona gli oggetti inseriti' del controller di array, l'ordinamento facendo clic sulle intestazioni delle colonne e gli elementi di associazione di una vista di dettaglio sulla selezione del controller di array funzionerà. – Willeke