2009-11-04 4 views
7

Diciamo, per esempio, stavo scrivendo un'app di clone iTunes in Cocoa, che era supportata da CoreData. Per semplificazione, diciamo che ci sono due "sezioni", "Libreria" con musica, film, radio, ecc. E una seconda sezione chiamata "Playlist" che contiene playlist create dall'utente (solo elenchi stupidi, playlist non intelligenti) .Come si implementa un elenco sorgente in stile iTunes con Bindings + CoreData in Cocoa?

Quindi il SourceList stesso sarebbe in genere implementato con NSOutlineView, che è generalmente semplice.

La sezione Libreria dell'elenco sorgente non contiene in realtà nulla generato dall'utente, solo "funzioni" dell'app (in sostanza) in cui la sezione Playlist contiene solo elenchi personalizzati creati dall'utente. Come si farebbe con Bindings e CoreData? È possibile associare la sezione Playlist ai dati dell'utente e avere un modo personalizzato di visualizzare le funzionalità della Libreria?

Mi sto ancora bagnando i piedi con Bindings e AppKit in generale, quindi per favore portami dietro. Apprezzo l'aiuto. Dovrei aggiungere, sto prendendo di mira il 10.6 e sopra.

risposta

6

Non ho avuto molta esperienza con i dati di base, ma ho fatto ampio uso delle associazioni di Cocoa. Nella mia esperienza, qualcosa di simile funziona meglio con un intermedio NSArray di oggetti che viene regolato "manualmente".

Ad esempio, immagino che si disponga di una personalizzata di playlist generata dall'utente e che si disponga anche di uno NSArray separato contenente gli elementi della Libreria standard. Con questa configurazione, creerei una proprietà in uno dei controller denominati combinedArray, che sarebbe la proprietà associata a NSOutlineView. Quindi legherei l'array di playlist generato dall'utente al controller e alcuni codice nel controller aggiorna automaticamente l'array combinato ogni volta che l'array di playlist viene modificato.

Ecco una rapida mock-up:

TheController.h

@interface TheController : NSObject 
{ 
    NSArray * combinedArray; 
    NSArray * userPlaylists; 
} 
@property (retain) NSArray * combinedArray; 
@property (copy) NSArray * userPlaylists; 
@end 

TheController.m

@implementation TheController 

@synthesize combinedArray; 
@synthesize userPlaylists; 
- (void)setUserPlaylists:(NSArray *)newLists 
{ 
    // standard property setting code: 
    if (newLists != userPlaylists) 
    { 
     [userPlaylists release]; 
     userPlaylists = [newLists copy]; 
    } 

    // modify the combined array: 
    NSMutableArray * allItems = [NSMutableArray arrayWithCapacity:0]; 
    [allItems addObjectsFromArray:standardLibrary]; 
    [allItems addObjectsFromArray:userPlaylists]; 
    [self setCombinedArray:allItems]; 
} 

@end 
+0

Questo è un po 'quello che pensavo sarebbe stato necessario fare. Quindi "setUserPlaylist" sarebbe un metodo chiamato da Bindings? Sono incredibilmente annebbiato quando si tratta di come funzionano i binding (so che la loro relazione con KVC ma come sono effettivamente configurati con i controller Array/Tree ancora mi sconcerta). – jbrennan

+1

Sì.Cocoa si prende cura di tutta la magia vincolante dietro le quinte. Tutto quello che devi fare è definire una proprietà che soddisfi KVO/KVC. Qualsiasi proprietà che tu @synthesize soddisferà quel requisito, e ogni volta che usi [self setSomePropertyName: someValue], verranno inviati i messaggi KVC appropriati. Intercettare il setter della proprietà (come mostro sopra) è perfettamente legale. Non sono sicuro di quale sia la tua origine dati per le playlist degli utenti (presumo qualcosa di CoreData), ma se la si collega al controller, il controller riceverà un messaggio "setUserPlaylists:" ogni volta che tale lista viene modificata. –

1

Poiché l'elenco di sorgenti in questo caso è davvero un "ambito" e non un semplice elenco di nient'altro che istanze di qualche entità "LibraryItem", penso che sia più semplice implementarlo nel modo "vecchio stile" (cioè, tabella protocollo sorgente dati).

Questo ti dà un controllo preciso sul raggruppamento, come/quando mescolare elementi "statici" (come "Libreria" e "Musica" e "Film", "Playlist") con articoli dal tuo negozio (come la Playlist individuale elementi nella sezione "Playlist").

È anche un po 'più semplice gestire il trascinamento della selezione, secondo me, che è fondamentale per impedire che un elemento della playlist venga rilasciato sul gruppo "Filmati".