Load UICollectionView from Master Data

I am developing an iOS application, and at some point I store image images of the user in Core Data. Now I would like to upload all the recorded images to the UICollectionView so that the user can select one and share it on social networks. Everything in my application works, except for this last part. I followed all kinds of tutorials on the net, but all the examples that I could find in UICollectionView used images from Flickr or similar sites.

Here is my code at the moment:

#import "LibraryViewController.h" (The name of the class we're in) #import "SocialViewController.h" #import "CollectionViewCell.h" static NSString *cellIdentifier = @"MemeCell"; @implementation LibraryViewController { NSMutableArray *_objectChanges; NSMutableArray *_sectionChanges; } #pragma mark - View Controller LifeCycle - (void)awakeFromNib { [super awakeFromNib]; } - (void)viewDidLoad { [super viewDidLoad]; _objectChanges = [NSMutableArray array]; _sectionChanges = [NSMutableArray array]; self.title = @"Meme collection"; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"share"]) { NSIndexPath *indexPath = [[self.collectionView indexPathsForSelectedItems] lastObject]; NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath]; SocialViewController *destViewController = segue.destinationViewController; [destViewController setDetailItem:object]; } } #pragma mark - UICollectionView - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section]; return [sectionInfo numberOfObjects]; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; NSManagedObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath]; [cell setImage:[UIImage imageWithData:[object valueForKey:@"image"]]]; return cell; } #pragma mark - Fetched results controller - (NSFetchedResultsController *)fetchedResultsController { if (_fetchedResultsController != nil) { return _fetchedResultsController; } NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; // Edit the entity name as appropriate. NSEntityDescription *entity = [NSEntityDescription entityForName:@"Meme" inManagedObjectContext:self.managedObjectContext]; [fetchRequest setEntity:entity]; [fetchRequest setFetchBatchSize:20]; NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"]; aFetchedResultsController.delegate = self; self.fetchedResultsController = aFetchedResultsController; NSError *error = nil; if (![self.fetchedResultsController performFetch:&error]) { // Replace this implementation with code to handle the error appropriately. // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return _fetchedResultsController; } - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { NSMutableDictionary *change = [NSMutableDictionary new]; switch(type) { case NSFetchedResultsChangeInsert: change[@(type)] = @(sectionIndex); break; case NSFetchedResultsChangeDelete: change[@(type)] = @(sectionIndex); break; } [_sectionChanges addObject:change]; } - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { NSMutableDictionary *change = [NSMutableDictionary new]; switch(type) { case NSFetchedResultsChangeInsert: change[@(type)] = newIndexPath; break; case NSFetchedResultsChangeDelete: change[@(type)] = indexPath; break; case NSFetchedResultsChangeUpdate: change[@(type)] = indexPath; break; case NSFetchedResultsChangeMove: change[@(type)] = @[indexPath, newIndexPath]; break; } [_objectChanges addObject:change]; } - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { if ([_sectionChanges count] > 0) { [self.collectionView performBatchUpdates:^{ for (NSDictionary *change in _sectionChanges) { [change enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, id obj, BOOL *stop) { NSFetchedResultsChangeType type = [key unsignedIntegerValue]; switch (type) { case NSFetchedResultsChangeInsert: [self.collectionView insertSections:[NSIndexSet indexSetWithIndex:[obj unsignedIntegerValue]]]; break; case NSFetchedResultsChangeDelete: [self.collectionView deleteSections:[NSIndexSet indexSetWithIndex:[obj unsignedIntegerValue]]]; break; case NSFetchedResultsChangeUpdate: [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:[obj unsignedIntegerValue]]]; break; } }]; } } completion:nil]; } if ([_objectChanges count] > 0 && [_sectionChanges count] == 0) { [self.collectionView performBatchUpdates:^{ for (NSDictionary *change in _objectChanges) { [change enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, id obj, BOOL *stop) { NSFetchedResultsChangeType type = [key unsignedIntegerValue]; switch (type) { case NSFetchedResultsChangeInsert: [self.collectionView insertItemsAtIndexPaths:@[obj]]; break; case NSFetchedResultsChangeDelete: [self.collectionView deleteItemsAtIndexPaths:@[obj]]; break; case NSFetchedResultsChangeUpdate: [self.collectionView reloadItemsAtIndexPaths:@[obj]]; break; case NSFetchedResultsChangeMove: [self.collectionView moveItemAtIndexPath:obj[0] toIndexPath:obj[1]]; break; } }]; } } completion:nil]; } [_sectionChanges removeAllObjects]; [_objectChanges removeAllObjects]; } @end 

When I start and try to access this ViewController, the application crashes with this error message: Reason: '+ entityForName: nil is not a legitimate NSManagedObjectContext parameter to search for the entity name' Meme '' * First stack of throw calls:

and points to this line of code:

  NSEntityDescription *entity = [NSEntityDescription entityForName:@"Meme" inManagedObjectContext:self.managedObjectContext]; 

Obviously, self.managedObjectContext is zero. How do I assign it? And when the user launches the application for the first time, and the main data is empty, how do I manage it? Deny access until there are no images?

Otherwise, I know how to store image images in the file system. If someone knew how to load it into a UICollectionView, this could also be a decision I could make.

+4
source share
2 answers

You want to get a link to your ManagedObjectContext. Often this is created in the application deletion. In this case, you will need something like this -

 NSManagedObjectContext *aManagedObjectContext = ((AppDelegate *)[UIApplication sharedApplication].delegate).managedObjectContext; 

If you want, you can do this in your viewDidLoad and assign it self.managedObjectContext.

0
source

I would not recommend storing images in master data unless you use external storage functions. BLOBs are rarely something that you want to store inside something like master data. Of course, you can store file system paths or URLs on the main data objects that point to images in the file system.

To use basic data with a UICollectionView, take a look at the NSFetchedResultsController. Here's an example of using these two together to get you started.

+1
source

Source: https://habr.com/ru/post/1493533/


All Articles