Расширение iOS8: обмен изображениями между контейнером и расширением

Я делаю расширение iOS 8. Вот что я пытаюсь сделать: пользователи выбирают изображения из библиотеки фотографий в приложении-контейнере, и эти изображения будут переданы расширению и для дальнейшего использования.

Прямо сейчас я делаю это следующим образом (если вы не хотите читать эту часть, пожалуйста, пропустите ниже, чтобы прочитать фактические коды): Используйте группу приложений и NSUserDefaults для обмена данными. Преобразуйте UIImage в NSData, а затем сохраните все изображения в NSArray, затем сохраните массив в NSDictionary (у меня много массивов, и именно так я их организую, поэтому мне нужно сохранить их в словарь), наконец, сохранить словарь в пользователь по умолчанию.

Вот кодировка:

  NSArray *imageArray = ... 
 //this array contains all the images.
 //photoDataArray is a NSMutableArray;
  photoDataArray = [[NSMutableArray alloc]init];
for (UIImage *images in imageArray) {
    [photoDataArray addObject:UIImagePNGRepresentation(images)];
}
    NSThread * creationThread = [[NSThread alloc] initWithTarget:self selector:@selector(handleData) object:nil];
    [creationThread start];
     -(void)handleData{
        NSDictionary *dic = [[NSDictionary alloc]init];
        [dic SetObject:photoDataArray forKey:@"testImageArray"];
        NSUserDefaults *   def = [[NSUserDefaults alloc] initWithSuiteName:@"group.myCompany.myApp"];
        [def setObject:dic forKey:@"dataDic"];
//done with saving data
        [self.navigationController popViewControllerAnimated:YES];
//Navigation
}

Когда я хочу получить изображения:

NSUserDefaults *   def = [[NSUserDefaults alloc] initWithSuiteName:@"group.myCompany.myApp"];
NSDictionary *dic = [def ObjectForKey:@"dataDic"];

  NSArray *dataArray = [dic objectForKey:@"testImageArray"];
    NSMutableArray *convertedArray = [[NSMutableArray alloc] init];
    for (NSData *imageData in dataArray) {
        [convertedArray addObject:[UIImage imageWithData:imageData]];
    }

convertArray будет массивом изображений, которые я хочу получить.

Видимо, есть много проблем, если я сделаю это таким образом. Например, две основные проблемы:

  • Для этого требуется много ресурсов, включая память. На самом деле для завершения процесса требуется около полминуты. Если у меня есть массив с примерно 20 изображениями, я получу «didRecieveMemoryWarning» примерно 3 раза (я использую iPad mini в качестве тестового устройства). Иногда данные сохраняются неправильно. После того, как viewController выскочил (что означает, что он работает до последней строки моего кода хранения), я получаю nil для массива, который я только что сохранил в UserDefault! Я уверен, что мой код работал нормально , и эта проблема вызвана нехваткой памяти, потому что если в массиве меньше 15 изображений, я могу без проблем сохранять и извлекать их.

  • Сложно сохранять новые изображения в ранее сохраненный массив. Когда я хочу это сделать, мне нужно получить предыдущий массив и добавить новые данные изображения в этот массив, а затем сохранить новый массив в UserDefault. Как упоминалось ранее, сохранение массива в UserDefault занимает много памяти.

Итак, мои вопросы довольно прямолинейны и конкретны:

  1. Есть ли другие способы передачи изображений с одной цели на другую? Другими словами: как передать изображения из приложения-контейнера в расширение?
  2. Если нет, есть ли способы решить проблему в моих кодах? Это правильный способ сделать это?

Это все, что я хочу спросить, но если бы вы могли также ответить мне на следующие вопросы, было бы очень приятно:

  1. Почему я должен получить более одного «didRecieveMemoryWarning» в одном процессе сохранения? Когда система получит предупреждение о памяти, она немедленно остановит действие?
  2. (Просто чтобы убедиться) Безопасно ли использовать UIImagePNGRepresentation для всех изображений, включая PNG и JPG?

Спасибо.


person NSError    schedule 13.01.2015    source источник


Ответы (1)


Из Документация Apple по программированию расширений приложений

Обмен данными с вашим содержащим приложением

Домены безопасности для расширения приложения и содержащего его приложения различны, даже если пакет расширения вложен в пакет содержащего приложения. По умолчанию ваше расширение и содержащее его приложение не имеют прямого доступа к контейнерам друг друга.

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

.....

При настройке общего контейнера содержащее его приложение и каждое расширение содержащегося приложения, которому вы разрешаете участвовать в совместном использовании данных, имеют доступ на чтение и запись к общему контейнеру. Во избежание повреждения данных необходимо синхронизировать доступ к данным. Используйте блокировки Core Data, SQLite или Posix для координации доступа к данным в общем контейнере.

person Lefteris    schedule 13.01.2015
comment
Другой вопрос: когда я использую ContentOfDirectoryAtPath из NSDictionary, должен ли я использовать относительный или абсолютный путь? - person NSError; 13.01.2015
comment
Посмотрите здесь : если вам нужно предоставить больше данных, чем на самом деле работает для пользовательских настроек по умолчанию, вы можете получить доступ к общему каталогу группы напрямую через NSFileManager NSURL *groupURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier: @"group.com.atomicbird.demonotes"]; А здесь - person Lefteris; 16.01.2015