iPhone приложение отклонены, поскольку принципы хранения данных iCloud
Критическое исправление одного из моих приложений было недавно отклонено из-за предполагаемого нарушения правил хранения данных iCloud.
Вот как мое приложение хранит данные (не было проблем с момента утверждения первой версии моего приложения в 2009 году):
- при запуске он копирует базу данных" starter " SQLite3 из пакета приложений в папку Documents.
- база данных содержит базовую схему и некоторые примеры данных, чтобы пользователь мог видеть, как использовать приложение. Он маленький - чуть меньше 3 МБ.
- дальнейшая работа пользователя сохраняется только в этом файле базы данных. Они могут удалить или сохранить образцы, они могут добавить тонны своих собственных данных, но этот файл базы данных всегда будет там.
И даже если в базе данных не было образцов данных, любое приложение, поддерживающее базу данных, все равно будет генерировать пустую базу данных при запуске, даже если единственное, что она содержит, - это схема базы данных приложения.
Это должно быть очень распространенное явление. проблема, но, к сожалению, это не нормально для меня, чтобы просто отключить резервное копирование-пользователи вкладывают много работы в данные, которые они хранят в моем приложении, и резервное копирование iCloud очень важно для них.
Какие варианты у меня есть на данный момент? Вот что я вижу:
-
Снова свяжитесь с Apple и попытайтесь объяснить, что происходит.
-
Могу ли я установить атрибут резервного копирования файла в значение нет, а затем переключить его только на Да, когда пользователь делает свое первое изменение? Это нормально технически и нормально с яблоком?
-
Удалите мой пример данных из базы данных. Это будет очень плохо для удобства использования и увеличит мою нагрузку на поддержку, но я готов сделать это, если мое обновление будет одобрено. Однако мне все равно придется создать заглушку базы данных при запуске, чтобы сохранить пустую схему базы данных, поэтому я не уверен, что это даже повлияет на процесс утверждения.
-
Плачь.
У кого-нибудь есть советы? Я должен представить, что есть много других приложения, которые используют базу данных так же, как и моя, но не имеют возможности просто отключить резервное копирование.
Также очень удручает, что любые изменения, которые я внесу, потребуют еще одного раунда тестирования и обзора приложения, что отложит мое критическое обновление на дополнительные 2-3 недели. : /
UPDATE : может быть, есть другой вариант: можно ли просто сохранить файл в Library/
вместо Documents/
, поскольку их проблема, похоже, связана именно с использованием папки Documents? Будет ли файл резервное копирование, если оно хранится в Library/
?
Обновление 2 : больше всего меня смущает то, что любое приложение с поддержкой баз данных (даже если оно использует основные данные, я полагаю) должно будет создать файл базы данных, содержащий по крайней мере схему приложения. Проблема только в том, что размер моей базы данных слишком велик? Потому что я не вижу, как любое приложение с поддержкой баз данных может избежать необходимости создавать базу данных при запуске.
UPDATE 3 : я использую пользовательский уровень взаимодействия SQLite-нет основные данные. Кроме того, данные примера состоят из начальных изображений, которые пользователь, вероятно, в конечном итоге удалит, когда они начнут использовать приложение.
8 ответов:
3 МБ похоже на довольно много образцов данных, хранящихся в базе данных. Если вы вытащите изображения и сохраните ссылки на изображения в базе данных вместо этого, вы сможете значительно сократить это использование. Затем вы можете изменить код средства получения изображений в базе данных на что-то вроде этого:
- (UIImage *)image { NSString *imageName = self.imageName; UIImage *image = [UIImage imageNamed:imageName]; if (!image) { NSString *imageLibraryPath = ...; image = [UIImage imageWithPath:[imageLibraryPath stringByAddingPathComponent:imageName]]; } return image; } - (void)setImage:(UIImage *)image { [self setImageData:UIImagePNGRepresentation(image)]; } - (void)setImageData:(NSData *)imageData { NSString *imageLibraryPath = ...; NSString *fileName = self.uniqueId; //or something else, UUID maybe? NSString *filePath = [imageLibraryPath stringByAddingPathComponent:imageName]; [imageData writeToFile:filePath atomically:YES]; // maybe dispatch_async this into the background? self.fileName = fileName; }
self.fileName
будет поддерживаться вашей базой данных.Сократив таким образом объем хранилища данных, вы сможете получить одобрение, так как вы не храните относительно большие объемы данных на телефон. Изображения также могут быть в пакете приложений таким образом, и их не нужно дублировать вообще.
У меня есть очень глупая идея. Но, может быть, это действительно так.
Вы можете показать всплывающее окно при запуске с вопросом "не хотите ли вы, чтобы я создал некоторые демонстрационные данные". Когда пользователь нажимает "да", его данные генерируются пользователем.
Одним из обходных путей было бы чтение файла SQL из пакета, пока пользователь не попытается что-то изменить. Тогда перепишите его. Так как файл маленький, он не должен даже требовать спиннера.
У меня была именно такая проблема с Приложение недавно. В нашем случае мы использовали основные данные и скопировали файл SQL при запуске.
К сожалению, вы должны ориентироваться на iOS 5.
Https://developer.apple.com/library/ios/qa/qa1719/_index.html
Просто добавьте следующий атрибут, и Apple позволит вам пройти (если вы не используете
#include <sys/xattr.h> ... - (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL { int result = -1; @try { const char* filePath = [[URL path] fileSystemRepresentation]; const char* attrName = "com.apple.MobileBackup"; u_int8_t attrValue = 1; result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0); } @catch (NSException * e) { DebugLog(@"Exception: %@", e); } return result == 0; } - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { ... NSURL *storeUrl = [NSURL fileURLWithPath:storePath]; [self addSkipBackupAttributeToItemAtURL:storeUrl]; ...
CoreData и два постоянных магазина должны быть способом пойти. Но для вас, при первом копировании файла установите com.яблоко.Атрибут файла MobileBackup. Снимите его после того, как пользователь внесет свою первую модификацию
В качестве окончательного решения я предлагаю использовать CoreData, с вашими законсервированными данными в качестве дополнительного постоянного хранилища только для чтения.
Тем не менее, в то же время, вам нужно простое и быстрое решение. Создайте простой экран, который загружает образцы данных в базу данных пользователя. Поместите ссылку на экран" система "или" инструмент", чтобы это можно было сделать в любое время.В частности, поднимите его при первом запуске приложения. Вы спрашиваете пользователя, хотят ли они получить образцы данных в своем документе, с помощью размер данных, поэтому именно они создают документ. Также следует отметить, что образцы данных могут быть удалены или заменены в любое время.
Это должно помочь вам пройти проверку.
Использование вашего "частного" уровня доступа к данным SQL
Поскольку вы используете не основные данные, а пользовательский уровень доступа, я могу только предложить не помещать базу данных" initial seed " в папку iCloud, а написать пользовательскую процедуру, которая генерирует ее во время выполнения (например. при первом запуске приложения).
Наилучшим подходом будет размещение вашего реального файла SQL в общем пакете приложений, вне общей папки iCloud. Через вашу процедуру вы должны будете прочитать все содержание этот файл и воссоздать клон в общей папке, так что этот новый файл будет отображаться как пользовательский контент, а не в комплекте контента. Это потребует немного бесполезных накладных расходов, но я думаю, что это необходимо, чтобы избежать отказа Apple от вашего приложения.
Я предлагаю вам не делать резервные копии всех изображений и оставить их в основном пакете, если это возможно, так как они уже присутствуют в каждом загруженном приложении, а затем будут бесполезно занимать драгоценное пространство на iCloud. Попробуйте разместить в iCloud только то, что строго необходимо.
На случай, если вы планируете использовать Core Data и iCloud вместе.
Во-первых, размещение пользовательского файла базы данных SQLite3 в iCloud опасно по нескольким причинам, первая из которых заключается в том, что вы никогда не сможете должным образом обрабатывать проблемы слияния между различными данными, если ваше приложение используется на разных устройствах одновременно. Я не могу дать вам здесь полное решение, так как оно потребует слишком много времени и пространства. Но Я предлагаю вам посмотреть на сессию 227 talk от Apple WWDC в этом году. Они говорят об использовании основных данных и iCloud вместе, а также о решении той же проблемы, с которой вы столкнулись прямо сейчас (например, начальное заполнение базы данных и синхронизация через iCloud). Если вы зайдете на страницу WWDC через портал разработчика Apple, вы сможете получить полную копию образца проекта.
Если вы используете основные данные, вы можете сохранить образцы данных в пакете приложений. Откройте его как постоянное хранилище только для чтения на том же координаторе, что и хранилище чтения / записи в каталоге docs, и основные данные будут уверены, что все останется в правильном месте при сохранении. Об этом говорится в видеоролике WWDC 2012 "рекомендации по использованию основных данных".
Если вы используете SQLite напрямую, это не так просто, но вы можете реализовать свою собственную логику для этого.