saving pictures in Core Data in 'to-many relationship' environment
I'm working on my small project which take pictures and save them, very simple, using Core Data. I have two entities; one is 'Person' and the other is 'Image'. the relationship from Person to Image is to-many and from Image to Person I got inverse relationship as well.
All I need at the moment is to add multiple number of images (taken from iphone camera or chosen from library) to one Person entity.
I'd like to know whether there is any kind of sample code that deals with to-many relationship with UIImage using Core Data.
many thanks.
=====================
Actually I wish I could specify the problem. What i'm trying to do is using access methods that are given for free in to-many relationship to add object such as
- (void)addPersonImageObject:(PersonImage *)value;
and also I've implemented methods related to ImageToDataTransformer.
I spent almost a week on this matter and I think I need a guidin开发者_StackOverflow中文版g sample code that I can study first for my add project.
Besides converting the UIImage
to NSData
and back there is nothing special by having a to-many relationship with UIImage
s. So any core data tutorial that includes a to-many relationship should suffice. If you need sample code you can check out Apple's iPhoneCoreDataRecipes.
A few pointers to help you get started. Let's pretend we have a PersonViewController
that inherits from a `UITableViewController' that gets called with something like:
PersonViewController *personViewController = [[[PersonViewController alloc] init] autorelease];
personViewController.person = ... // get the selected person
personViewController.managedObjectContext = self.managedObjectContext;
[self.navigationController pushViewController:personViewController animated:YES];
PersonViewController has the following properties:
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) Person *person;
@property (nonatomic, copy) NSArray *images;
There is add button which would shod the image picker
- (void)insertNewObject {
UIImagePickerController *imagePicker = [[[UIImagePickerController alloc] init] autorelease];
imagePicker.delegate = self;
[self presentModalViewController:imagePicker animated:YES];
}
Then in the callback imagePickerController:didFinishPickingMediaWithInfo:
we can:
// Get the image from the picker
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// Transform the image to NSData
ImageToDataTransformer *transformer = [[[ImageToDataTransformer alloc] init] autorelease];
NSData *imageData = [transformer transformedValue:image];
// Create a new PersonImage entity and assign the image data
PersonImage *personImage = [NSEntityDescription insertNewObjectForEntityForName:@"PersonImage" inManagedObjectContext:self.managedObjectContext];
personImage.imageData = imageData;
// This is where we are adding the image to our person
[self.person addImagesObject:personImage];
// Core data save, however you want to do it.
NSError *error = nil;
if (![self.managedObjectContext save:&error]) {
abort();
}
// simple trick to update the table view data source
self.images = nil;
[self.tableView reloadData];
// don't forget to dismiss the picker
[self dismissModalViewControllerAnimated:YES];
The implementation of images
just to keep it simple
- (NSArray *)images {
if (images_) {
return images_;
}
// since we set self.images = nil when adding a new image we will get the list
// of all images from our person object.
images_ = [[self.person.images allObjects] retain];
return images_;
}
The table view data source methods would just be:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.images.count;
}
and however the cell is created doesn't really matter. At then if we wanted to do something with the images we can do something in tableView:didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// get the tapped person image
PersonImage *personImage = [self.images objectAtIndex:indexPath.row];
// get the image
ImageToDataTransformer *transformer = [[[ImageToDataTransformer alloc] init] autorelease];
UImage *image = [transformer reverseTransformedValue:personImage.imageData];
// do something with the image.
}
Images from the camera could be really big. General rule to images in Core Data is below 1 MB. You might want to store the image in a directory and store the path in Core Data.
精彩评论