2009-06-03 12 views
11

Apple fornisce NSArchiver e NSUnachriver per la serializzazione/deserializzazione degli oggetti, ma questo non può gestire alcun schema xml personalizzato. Quindi compilare una struttura ad oggetti con i dati di qualsiasi schema xml personalizzato deve essere fatto manualmente. Dato che la comunità degli sviluppatori di iPhone sta crescendo rapidamente, molti programmatori principianti sono disperati per affrontare le possibilità di analisi dei xml disponibili.Libreria di serializzazione Xml per applicazioni iPhone

iPhone SDK fornisce solo NSXmlParser per l'analisi xml, che è più utile per leggere determinate parti di un file xml, piuttosto che riempire un'intera struttura di oggetti, il che è davvero un dolore.

L'altra possibilità è la famosa libreria libxml, che è scritta in ANSI C - non è facile da usare per qualcuno che inizia a programmare con C obiettivo-c e mai appreso prima. Evento ci sono molti wrapper disponibili, trattare con xml può essere un problema per i principianti.

E qui la mia idea ha luogo. Una libreria XmlSerializer che riempie automaticamente una struttura di oggetti potrebbe renderla molto più semplice e aumentare la qualità delle app per molti programmatori. mia idea dovrebbe funzionare in questo modo:

il file XML

<Test name="Michael" uid="28"> 
    <Adress street="AlphaBetaGammastrasse 1" city="Zürich" postCode="8000" /> 

    <Hobbies> 
    <Hobby describtion="blabla"/> 
    <Hobby describtion="blupblup"/> 
    </Hobbies> 
</Test> 

Le classi per riempire

@interface Test : NSObject { 
    NSString *name; 
    Adress *adress; 
    NSArray *hobbies; 
    int uid; 
} 
@property (nonatomic, copy) NSString *name; 
@property (nonatomic, retain) Adress *adress; 
@property (nonatomic, retain) NSArray *hobbies; 
@property (nonatomic, readwrite) int uid; 
@end 

@interface Adress : NSObject { 
    NSString *street; 
    NSString *city; 
    int postCode; 
} 
@property (nonatomic, copy) NSString *street; 
@property (nonatomic, copy) NSString *city; 
@property (nonatomic, readwrite) int postCode; 
@end 

Come il serializzatore XML dovrebbe funzionare

NSError *error = nil; 
XMLSerializer *serializer = [[XMLSerializer alloc] init]; 
NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"TestFile" ofType:@"xml"]]; 
Test *test = [serializer deserializeWithData:data error:&error]; 

Per riempire la struttura dell'oggetto ha bisogno solo di una riga di codice:

Test *test = [serializer deserializeWithData:data error:&error]; 

Questo sarebbe così facile da usare che qualsiasi programmatore principiante potrebbe usarlo. Per un uso più avanzato, il serializzatore potrebbe essere configurabile.

Cosa ne pensi, sarebbe una libreria utile e popolare per iPhone e applicazioni OSX?

Modifica: È possibile vedere il progetto here, ma è lontano dal rilascio.

+0

Ecco qualcosa di simile che ho messo insieme: http://kpmattius.wordpress.com/2011/06/07/objective-c-serialization/ Se qualcuno ha tempo può farlo farlo di più ma funziona per me: D –

+0

Questo aiuterà ... http://code.google.com/p/wonderxml/ – hrishib

risposta

0

Questa è una buona idea, in termini di implementazione lo farei implementando NSXMLArchiver e NSXMLUnarchiver come sottoclassi di NSCoder. In questo modo qualsiasi classe conforme al protocollo NSCoding può essere facilmente serializzata da e verso XML.

Un colpo di prestazioni durante la serializzazione in XML saranno i valori primitivi come attributi, poiché non è possibile garantire l'ordine in cui un oggetto richiederà la codifica dei dati. Quindi se gli attributi sono ciò che si desidera, allora sarà abbastanza grande nei buffer di memoria. Ma sarebbe un esercizio divertente.

Per quanto popolare sarebbe? Non così popolare, penso. Il caso d'uso è troppo piccolo.

  • dispositivo a dispositivo - Semplicemente usando NSKeyedArchiver è il modo più semplice e molto più compatto.
  • Device-to-new server - Il nuovo server dovrebbe implementare lo stesso schema, serializzando su Java, C# o altro.
  • Server Device-to-existing: il formato XML è già stato risolto e molto probabilmente non è vicino a questo.
0

Quello che stai descrivendo è sepolto all'interno dello ObjectiveResourceimplementations e supporta sia JSON che XML. Dovrebbe essere abbastanza facile puntarlo e ridurlo al solo parsing eliminando tutta la gestione della connessione.

2

NSKeyedArchiver funziona esattamente perché non tenta di eseguire il mapping su uno schema XML. Molti schemi XML sono mal progettati (cioè stanno traducendo una struttura di oggetti in memoria in un formato di rappresentazione esterno). Il problema chiave è che i documenti dovrebbero essere progettati in modo da avere un senso dal punto di vista del documento e che quindi dovrebbero essere mappati su qualsiasi layout di memoria desiderato per i propri oggetti. Documenti XML mai visti con molti attributi 'refid' che si riferiscono ad altre parti del documento? Di solito vengono traslitterati da un database relazionale che sta semplicemente attaccando parentesi angolari sul set di risultati.

Quindi, iniziando assumendo una mappatura uno-a-uno tra un documento XML e la sua rappresentazione del codice è praticamente condannata in tutti i casi tranne i più semplici. Pensa a dove saremmo oggi con HTML se fosse stato progettato attorno agli oggetti C++ che sono stati usati per istanziare il documento nel primo browser ... (beh, più come Objective-C, ma hey ...)

Il punto su NSKeyedArchiver è che è possibile evolvere la struttura dati senza interrompere la possibilità di caricare versioni precedenti. È incredibilmente difficile farlo (correttamente) usando una sorta di mappatura automatica istanza-var-elemento.

+0

L'esempio di OP è un modello di dati con campi semplici che hanno senso essere serializzati. La domanda che mi sembra più su come serializzare/deserializzare XML in un formato diverso dal formato plist di Apple. Probabilmente, questo deve essere usato per comunicare dati a/da un servizio web che non esegue OSX (quindi non è stato progettato intorno a plists). Quindi idealmente si dovrebbe scrivere un oggetto modello con proprietà per ogni elemento nello schema e usarlo per serializzare i valori dei risultati XML dal servizio. – George

+0

Inoltre, l'esempio dell'OP è un documento XML che ha senso "dal punto di vista del documento". In questo caso è più probabile che siano stati creati oggetti Objective-C per supportare il formato di documento in uso. Che è perfettamente accettabile. Stanno cercando un modo semplice per tradurre il documento in una rappresentazione in memoria senza scrivere codice di analisi personalizzato per ciascun oggetto. – George

0

Sono stato alle prese con i requisiti in questo settore e penso che sarebbe stata una grande idea. Ho dovuto fare il prepotente con i miei servizi dot net per restituire a JSON un facile consumo su un iPhone. Una libreria di serializzazione decente sarebbe superba.

1

Ho avviato un progetto open source simile. L'ho chiamato SAMIXOS. puoi visitare questa pagina e provarla. È in fase di sviluppo iniziale. Funziona in modo simile a quello che ha chiesto Enyra.

Presto fornirò un codice di esempio.

http://sourceforge.net/projects/samixos/

Sami

+0

hi sami. . Sto riscontrando problemi nell'aggiungere la tua biblioteca al mio progetto. hai un progetto di esempio che lo fa ?? – thndrkiss

1

Ho aperto un correlato progetto open source, XML stream writer for iOS:

  • Scritto in Objective-C, un singolo .h. e il file .m
  • Uno @protocol per il supporto dello spazio dei nomi e una per senza

Esempio:

// allocate serializer 
XMLWriter* xmlWriter = [[XMLWriter alloc]init]; 

// start writing XML elements 
[xmlWriter writeStartElement:@"Root"]; 
[xmlWriter writeCharacters:@"Text content for root element"]; 
[xmlWriter writeEndElement]; 

// get the resulting XML string 
NSString* xml = [xmlWriter toString]; 

Questo produce la seguente stringa XML:

<Root>Text content for root element</Root> 

Nella mia esperienza, strumenti economicamente convenienti per mappare oggetti da un modello (oggetti in memoria) a un altro modello (alcuni Schemi XML) non esistono, poiché la logica deve ancora essere espressa in qualche modo. Stai meglio facendo il lavoro usando strumenti (codice !?) che conosci.

Ma se si insiste a utilizzare tale strumento, la strada da percorrere è quella di rendere il modello a oggetti lo stesso del modello XML.