2009-10-30 24 views
8

que han estado tratando de conseguir el NSKeyedArchiver para escribir mis datos en un formato legible por humanos (es decir, no como un archivo binario) Entiendo que puedo usar ...NSKeyedArchiver escribir XML (u otra legible para humanos)?

setOutputFormat: NSPropertyListXMLFormat_v1_0 

Pero ... solo Parece que la sintaxis no es correcta, ¿alguien puede señalarme en la dirección correcta?

NSData *artistData; 

NSLog(@"(*) - Save All"); 
artistData = [NSKeyedArchiver archivedDataWithRootObject:artistCollection ]; 
[artistData writeToFile:@"/Users/fgx/Desktop/stuff" atomically:YES]; 

EDITAR

añadí setOutputFormat (véase más adelante), pero recibo una advertencia durante la compilación, lo que me estoy perdiendo?

warning: NSData may not respond to 'setOutputFormat:' 

Aquí está el código que utilicé.

NSLog(@"(*) - Save All"); 
artistData = [NSKeyedArchiver archivedDataWithRootObject:artistCollection ]; 
[artistData setOutputFormat: NSPropertyListXMLFormat_v1_0]; 
[artistData writeToFile:@"/Users/fgx/Desktop/stuff" atomically:YES]; 

Gary

Respuesta

17

Esto es lo que tiene que hacer:

NSMutableData *data = [NSMutableData data]; 
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 
[archiver setOutputFormat:NSPropertyListXMLFormat_v1_0]; 
[archiver encodeObject:artistCollection forKey:@"root"]; 
[archiver finishEncoding]; 
[data writeToFile:@"/Users/fgx/Desktop/stuff" atomically:YES]; 
[archiver release]; 

Tenga en cuenta que necesidad uso [archiver encodeObject:artistCollection forKey:@"root"] en lugar de [archiver encodeRootObject:artistCollection]; como se sugiere por Sean. Esto se debe a que NSKeyedArchiver no anula el método NSCoder encodeRootObject :. Considero que esto es un error y lo reportaré a Apple.

Ahora, la verdadera pregunta es ¿por qué quiere escribir XML en lugar del formato binario predeterminado? Si es para fines de depuración, le sugiero que use TextWrangler, que le permitirá editar de forma transparente archivos plist plinarios como si fueran XML.

+0

Ah, eso es todo, ya que tanto usted como Sean señalan que estaba usando el método de clase en lugar de crear una instancia, ciertamente es donde me estaba yendo mal. También a la derecha, mi razón principal fue ayudar a depurar lo que realmente estaba entrando en el archivo, verlo con BBEdit o TextWrangler es perfecto para lo que necesito. Muy apreciado. – fuzzygoat

+0

+1 por sugerir TextWrangler. ¡No sabía que podría leer el formato binario! –

+0

La parte de TextWrangler de esta respuesta es increíble. Definitivamente ahorré un montón de esfuerzo, ¡no tenía idea de que podría hacer esto! – savvyx4

0
[artistData setOutputFormat: NSPropertyListXMLFormat_v1_0]; 
+2

'setOutputFormat:' es un método NSKeyedArchiver. El envío de dicho mensaje a un objeto NSData no va a funcionar. –

+0

así que debería estar mirando algo así como [NSKeyedArchiver setOutputFormat: NSPropertyListXMLFormat_v1_0]; No estoy en mi computadora en este momento, la veré mejor esta noche. – fuzzygoat

+0

fuzzygoat: No, porque 'setOutputFormat:' es un método de instancia, por lo que enviarlo a la clase NSKeyedArchiver tampoco funcionará. Debe crear una instancia de NSKeyedArchiver y enviar el mensaje a eso. –

1

'archivedDataWithRootObject:' es un método de clase, mientras que 'setOutputFormat' es un método de instancia. De la documentación para 'archivedDataWithRootObject:':

Objeto NSData que contiene la forma codificada del objeto gráfico cuyo objeto raíz es rootObject. El formato del archivo es NSPropertyListBinaryFormat_v1_0.

Lo que necesita hacer es crear un NSKeyedArchiver y codificar el objeto raíz. Además, asegúrese de que todos los contenidos de su colección implementen 'encodeWithCoder' e 'initWithCoder'. Ver Encoding and Decoding Objects

El problema con este enfoque es que hay que asignar manualmente las claves para cada objeto codificar, lo que no suena como lo que usted desee, ya que ya tiene una colección. Ambas matrices y diccionarios contienen métodos para escribir en un archivo xml, que es un enfoque mucho más fácil.

[artistCollection writeToFile:@"/Users/fgx/Desktop/stuff" atomically:YES]; 

La discusión sobre este método (por tanto NSDictionary y NSArray):

Si el contenido del receptor son todos los objetos de la lista propiedad (NSString, NSData, NSArray, u objetos NSDictionary), el archivo escrito por este método se puede utilizar para inicializar una nueva matriz con el método de clase arrayWithContentsOfFile: o el método de instancia initWithContentsOfFile :. Este método valida recursivamente que todos los objetos contenidos son objetos de la lista de propiedades antes de escribir el archivo, y devuelve NO si todos los objetos no son objetos de la lista de propiedades, ya que el archivo resultante no sería una lista de propiedades válida. cita en bloque

+0

Las clases de lista de propiedades son todas codificables, y puede codificar una colección que contiene objetos que no son de propiedad, mientras que no puede hacer que los datos de la lista de propiedades se obtengan de uno. –

2

Usted necesita crear primero una instancia de NSKeyedArchiver lugar de utilizar el método de la clase práctica que sólo devolverá un NSData.

NSMutableData *data = [NSMutableData new]; 
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 

// set the one property you specifically wanted 
[archiver setOutputFormat:NSPropertyListXMLFormat_v1_0]; 

// now encode (and finalize) the actual object - note that encodeRootObject: is inherited 
// from NSCoder. I assume this works :) 
[archiver encodeRootObject:artistCollection]; 
[archiver finishEncoding]; 

// now finally write it out - the resulting encoded stuff should be waiting in the data object 
[data writeToFile:@"/Users/fgx/Desktop/stuff" atomically:YES]; 

// cleanup after ourselves 
[archiver release]; 
[data release]; 

exención de responsabilidad: Escribí este código en el cuadro de entrada aquí y en realidad no probarlo.

+0

No use '[archiver encodeRootObject: artistCollection];' Por favor, lea mi respuesta para comprender por qué. – 0xced

Cuestiones relacionadas