2009-10-30 2 views
8

Я пытался получить NSKeyedArchiver выписывать мои данные в читаемом виде (т.е. не в виде двоичного файла) Я понимаю, что я могу использовать ...NSKeyedArchiver пишет XML (или другой читаемый человеком)?

setOutputFormat: NSPropertyListXMLFormat_v1_0 

Но ... Я просто похоже, не может получить синтаксис, может ли кто-нибудь указать мне в правильном направлении?

NSData *artistData; 

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

EDIT

Я добавил setOutputFormat (смотри ниже), но я получаю предупреждение во время компиляции, что мне не хватает?

warning: NSData may not respond to 'setOutputFormat:' 

Вот код, который я использовал.

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

Гэри

ответ

17

Это то, что вы должны сделать:

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]; 

Обратите внимание, что вы необходимо использовать [archiver encodeObject:artistCollection forKey:@"root"] вместо [archiver encodeRootObject:artistCollection]; как это было предложено Шона. Это связано с тем, что NSKeyedArchiver не переопределяет метод encodingRootObject: NSCoder. Я считаю это ошибкой и сообщаю об этом Apple.

Теперь, реальный вопрос, почему вы хотите написать XML вместо двоичного формата по умолчанию? Если это для цели отладки, я предлагаю вам использовать TextWrangler, который позволит вам прозрачно редактировать двоичные файлы plist, как если бы они были XML.

+0

А вот это, как и вы, и Шон указывают, что я использовал метод класса, а не создавал экземпляр, конечно, где я ошибался. Кроме того, ваше право, моя основная причина заключалась в том, чтобы помочь отладить то, что действительно было в файле, просмотр с помощью BBEdit или TextWrangler идеально подходит для того, что мне нужно. Очень признателен. – fuzzygoat

+0

+1 для предложения TextWrangler. Я не знал, что он может читать двоичный формат! –

+0

Эта часть ответа TextWrangler является удивительной. Определенно сэкономили массу усилий - я и не подозревал, что это можно сделать! – savvyx4

0
[artistData setOutputFormat: NSPropertyListXMLFormat_v1_0]; 
+2

'setOutputFormat:' - метод NSKeyedArchiver. Отправка такого сообщения объекту NSData не будет работать. –

+0

поэтому я должен смотреть на что-то вроде [NSKeyedArchiver setOutputFormat: NSPropertyListXMLFormat_v1_0]; Сейчас я не на своем компьютере, сегодня вечером мне будет лучше. – fuzzygoat

+0

fuzzygoat: Нет, потому что 'setOutputFormat:' - это метод экземпляра, поэтому отправка его в класс NSKeyedArchiver тоже не будет работать. Вы должны создать экземпляр NSKeyedArchiver и отправить сообщение на это. –

1

'archivedDataWithRootObject:' представляет собой метод класса, в то время как 'setOutputFormat' является методом экземпляра. Из документации для 'archivedDataWithRootObject:':

Объект NSData, содержащий кодированную форму графа объектов, корневым объектом которого является rootObject. Формат архива - NSPropertyListBinaryFormat_v1_0.

Что вам нужно сделать, это создать NSKeyedArchiver и закодировать корневой объект. Кроме того, убедитесь, что все содержимое вашей коллекции реализует «encodeWithCoder» и «initWithCoder». См. Encoding and Decoding Objects

Проблема с этим подходом заключается в том, что вам необходимо вручную назначить ключи для каждого объекта, который вы кодируете, что не похоже на то, что вы хотите, поскольку у вас уже есть коллекция. Оба массива и словари содержат методы для записи в XML-файл, что намного проще.

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

Обсуждение этого метода (как для NSDictionary и NSArray):

Если содержимое приемника являются все объекты списка свойств (NSString, NSData, NSArray или NSDictionary объекты), файл, написанный этот метод можно использовать для инициализации нового массива с помощью метода класса arrayWithContentsOfFile: или метода экземпляра initWithContentsOfFile :. Этот метод рекурсивно проверяет, что все содержащиеся объекты являются объектами списка свойств перед записью файла и возвращает НЕТ, если все объекты не являются объектами списка свойств, так как результирующий файл не будет действительным списком свойств. Blockquote

+0

Все классы кодирования свойств кодируются, и вы можете кодировать коллекцию, содержащую объекты не-свойств, тогда как вы не можете сделать данные списка свойств из одного. –

2

Вы должны сначала создать экземпляр NSKeyedArchiver вместо того, чтобы использовать метод удобный класс, который будет только возвращать 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]; 

Отказ от ответственности: Я написал этот код в поле ввода здесь и фактически не протестировал его.

+0

Не используйте '[archiver encodeRootObject: artistCollection];' Пожалуйста, прочитайте мой ответ, чтобы понять, почему. – 0xced

Смежные вопросы