2013-07-14 2 views
1

Я использую BTLE для записи данных в одну из характеристик периферийных устройств. Я хотел отправить NSDictionary в эти характеристики. Поскольку существует ограничение на 130 байтов данных, отправляемых через BTLE, я хочу эффективный способ сжатия NSDictionary в NSData, а затем отправить его через. Я использую ниже фрагмент кода, который превышает лимит. Есть идеи?Эффективный способ сжатия NSDictionary в NSData

NSDictionary *aDict = @{ @"Value1": @"sadsadasdasdsadqwwqsadasd", 
         @"Value2": @"10", 
         @"Value3": @"12" }; 
NSData *aData = [NSKeyedArchiver archivedDataWithRootObject:aDict]; 
NSLog(@"Data Size = %@", 
     [NSByteCountFormatter stringFromByteCount:aData.length 
             countStyle:NSByteCountFormatterCountStyleFile]); 
+0

Проверьте это. Это должно помочь. http: // stackoverflow.com/questions/3157356/conversion-nsdictionary-object-to-nsdata-object-and-vice versa –

+0

Вы можете попытаться сжать NSData, как описано здесь: http://stackoverflow.com/a/234099/475052 –

+0

Don Не знаю, какое представление использует NSKeyedArchiver - вероятно, JSON будет более компактным. В любом случае в представлении вряд ли будет много «газа», поэтому вам придется прибегать к сжатию данных, если вы действительно хотите сжать все вместе. –

ответ

6

Я не думаю, что пытается использовать любую форму сжатия будет эффективным, или даже улучшение на всех в таком масштабе, поскольку все алгоритмы сжатия работают лучше, когда у них есть много данных для работы с, и, следовательно, много дубликатов и шаблонов для поиска. Когда весь размер данных составляет 130 байт, любая форма сжатия zip не является реальной альтернативой.


Если ваш словарь будет содержать только свойство-список значений (массивы, словари, строки, числа), то вы можете использовать JSON сериализации вместо NSKeyedArchiver:

NSData *JSONData = [NSJSONSerialization dataWithJSONObject:anObject 
                options:0 
                error:nil]; 

Это сразу делает выходные данные намного короче в вашем случае:

NSDictionary *aDict = @{ @"Value1": @"sadsadasdasdsadqwwqsadasd", 
         @"Value2": @"10", 
         @"Value3": @"12" }; 

NSData *aData = [NSKeyedArchiver archivedDataWithRootObject:aDict]; 
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:aDict 
                options:0 
                error:nil]; 

NSLog(@"NSKeyedArchiver Data Size = %@, JSON Data Size = %@", 
     [NSByteCountFormatter stringFromByteCount:aData.length 
            countStyle:NSByteCountFormatterCountStyleFile], 
     [NSByteCountFormatter stringFromByteCount:jsonData.length 
            countStyle:NSByteCountFormatterCountStyleFile] 
    ); 
Размер

NSKeyedArchiver Data = 380 байт, JSON данных Размер = 66 байт

Как вы можете видеть, сериализованные данные JSON является почти в 6 раз меньше чем NSKeyedArchiver сериализованными данных, и легко помещается в пределе 130 байт. И самое лучшее, это только одна строка кода.

UPDATE: Просто втирать в некоторых больше :), вот данные, которые NSKeyedArchiver производит (добавлено как изображение, так как он содержит много «незаконных» символов, которые я не мог скопировать и вставить):

NSKeyedArchiver Data

Как вы можете видеть, он содержит много ненужных данных, которые вы действительно не нужно (выделено синим цветом), что в основном просто дать NSKeyedUnarchiver достаточно информации, чтобы иметь возможность разархивировать его позже.

Теперь давайте посмотрим на данные JSON:

{"Value3":"12","Value2":"10","Value1":"sadsadasdasdsadqwwqsadasd"}

Вот и все. Одна линия. 66 байт. Из них 19 байт не являются вашими значениями. Другими словами, 71% данных JSON - это ваши значения, а остальное - разметка, так сказать. Между тем, в данных NSKeyedArchiver, ваши значения составляют, дождитесь его, 12% результата. Я думаю, вы можете четко видеть, какая из них более эффективна для хранения здесь.

+0

Делает прекрасный смысл. Спасибо, что объяснил это так изящно! – Abhinav

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