2016-02-03 8 views
1

У меня есть приложение ObjC iOS, в котором я архивирую/разархивирую данные. Данные, о которых идет речь, исходят от сопутствующего сервера. Каждый пользователь получает другой набор данных.Как предотвратить сбои в поврежденном файле с помощью [NSKeyedUnarchiver unarchiveObjectWithFile]?

В то время как я никогда не имел пользователя жалобу, я вижу, очень небольшое число аварий сообщенных через Crashlytics на этой линии:

NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; 

Детали аварии:

Fatal Exception: NSInvalidArgumentException 
*** -[NSKeyedUnarchiver initForReadingWithData:]: incomprehensible archive (0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30) 

Катастрофа происходит где-то около 0,002% сеансов, но наиболее часто встречается среди небольшого числа неизвестных пользователей.

Я нашел этот вопрос: Archiving/Unarchiving results in initForReadingWithData incomprehensible archive. В обсуждении приводятся две разумные теории причины; тот, который в архиве содержит символы «bplist» (звучит очень разумно), а другой - размер архива (маловероятно, учитывая типичный размер набора данных).

Я ищу предложения о том, как обнаружить эту ситуацию и действовать каким-то образом, не дожидаясь столкновения. NSKeyedArchiver, похоже, не возвращает метод ошибки - неудавшийся архив является сбоем.

В идеале я предпочитаю какой-либо механизм для обнаружения основной причины проблемы до ее возникновения. Частота этой проблемы не оправдывает того, что я пишу свой собственный парсер архивов, и не оправдывает риск добавления каких-либо сумасшедших, которые будут выполняться всеми пользователями.

Я избегаю @try блоки из практики. Очевидно, что это возможно. Приложение читает этот архив гораздо чаще, чем писать, поэтому я думаю, что нужно попытаться прочитать (внутри @try) сразу после записи, а если чтение не поможет сделать отчет о состоянии. Мне также нужно найти другой способ кэширования данных для этих пользователей, но это легкая часть.

ответ

0

В то время как использование try/catch должно быть несколько редкими, это вполне допустимый прецедент для его использования. Это плохо для вашего приложения, чтобы сбой из-за неожиданного файла. Это то, к чему ваше приложение должно работать и с которым легко справиться. Поймай исключение от попытки разобрать плохой файл и сообщить пользователю соответствующую ошибку или обработать ее каким-либо другим способом.

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

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