Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.2k views
in Technique[技术] by (71.8m points)

ios - iOS8 extension : share images between container and extension

I'm making an iOS 8 extension. Here's what I'm trying to do: Users select images from the photo library in the container app, and these images will be shared with the extension and for the further use.

Right now I'm doing it in this way (If you don't want to read this part, please skip below to read the actual codes): Use App Group and NSUserDefaults to share datas. Convert UIImage into NSData and then save all the images in a NSArray, then save the array into a NSDictionary (I have many arrays and this is the way I organize them - so I have to save them into dictionary), finally save the dictionary into user default.

Here's the coding:

  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
}

When I want to retrieve the images:

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

convertedArray would be the array of images I want to get.

Apparently, there are a lot of problems if I do it this way. For example, the two major issues:

  • Doing this takes a lot of resources including memory. It takes about half minute to actually finish the process.If I have a array with about 20 images, I'll get "didRecieveMemoryWarning" about 3 times (I'm using a iPad mini as a test device). Sometimes the datas are not saved correctly. After the viewController is popped out(which means it runs to the last line of my storing code), I get nil for the array I just saved into the UserDefault! I'm sure my coding all worked normal, and this issue is caused by low memory because if the array has less than 15 images, I can save and retrieve them perfectly.

  • It's hard to save new images into a previously saved array. When I want to do that, I have to retrieve the previous array and add new image datas into that array, and then save the new array into the UserDefault. As mentioned before, saving an array into the UserDefault takes a lot of memory.

So my questions are pretty straight foward and specific:

  1. Are there any other ways to transfer images from one target to another? In other words: How can I transfer images from the container app to the extension?
  2. If not, are there any ways to solve the issue in my codes? Is this a proper way to do it?

Those are all I want to ask, but if you could answer following questions for me also, it will be really nice:

  1. Why would I get more than one "didRecieveMemoryWarning" in one saving process? When the system received memory warning, will it stop the action immediately?
  2. (Just to make sure) Is that safe to use UIImagePNGRepresentation for all the images including PNG and JPG?

Thank you.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

From Apple's Documentation on App Extension Programming

Sharing Data with Your Containing App

The security domains for an app extension and its containing app are distinct, even though the extension bundle is nested within the containing app’s bundle. By default, your extension and its containing app have no direct access to each other’s containers.

You can, however, enable data sharing. For example, you might want to allow your app extension and its containing app to share a single large set of data, such as prerendered assets.

.....

When you set up a shared container, the containing app—and each contained app extension that you allow to participate in data sharing—have read and write access to the shared container. To avoid data corruption, you must synchronize data accesses. Use Core Data, SQLite, or Posix locks to help coordinate data access in a shared container.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...