2013-07-25 2 views
4

iOS 앱을 개발 중이며 특정 시점에 코어 데이터에 사용자가 그린 이미지를 저장합니다. 이제 UICollectionView에 기록 된 모든 이미지를로드하여 소셜 네트워크에서 하나를 선택하고 공유 할 수 있습니다. 내 마지막 부분을 제외하고 내 앱의 모든 항목이 작동합니다. 나는 그물에 모든 자습서를 따랐다 그러나 나가 UICollectionView에 찾아 낼 수 있던 모든보기는 Flickr 또는 유사한 웹 사이트에서 심상을 사용하고 있었다. 여기 코어 데이터의 UICollectionView를로드하십시오.

이 시점에서 내 코드입니다 :

#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 

내가 실행하고이 오류 메시지와 함께이의 ViewController, 응용 프로그램 충돌에 액세스하려고 : 2013년 7월 25일 23 : 08 : 11.832 MemeGen [ 87259 : C07] * 인해 캐치되지 않는 예외 'NSInvalidArgumentException'응용 프로그램 종료, 이유는 : '+ entityForName : 전무는 엔티티 이름을 검색 법적 NSManagedObjectContext 매개 변수 아니다'밈 '' * 먼저 던져 호출 스택 :

및 다음 코드 행을 가리 킵니다.

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

분명히 self.managedObjectContext는 nil입니다. 어떻게 지정해야합니까? 그리고 사용자가 애플리케이션을 처음 실행하고 핵심 데이터가 비어 있으면 어떻게 관리해야합니까? 이미지가없는 한 액세스를 금지 하시겠습니까?

그렇지 않으면 파일 시스템에 그리기 이미지를 저장하는 방법을 알고 있습니다. 누군가 UICollectionView에서로드 할 수있는 방법을 알고 있다면 받아 들일 수있는 솔루션이 될 수도 있습니다.

답변

0

ManagedObjectContext에 대한 참조를 얻고 싶을 것입니다. 종종 이것은 응용 프로그램 대리인에서 만들어집니다. 당신이 당신의 viewDidLoad에서이 작업을 수행하고 self.managedObjectContext에 할당 할 수 있습니다 원하는 경우

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

- 어떤 경우에 당신은 이런 일을 할 것입니다.

+0

도움 주셔서 감사합니다. 누락 된 부분을 발견했는데 이제는 저장된 이미지가로드되고 더 이상 충돌하지 않습니다 ... fetchedResultsController 메서드에서 다음 줄을 추가해야했습니다. NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey : @ "image"ascending : NO]; NSArray * sortDescriptors = @ [sortDescriptor]; – lweingart

+0

또한이 메서드를 추가하려면 - (NSManagedObjectContext *) managedObjectContext { NSManagedObjectContext * context = nil; id delegate = [[UIApplication sharedApplication] delegate]; if ([delegate performSelector : @selector (managedObjectContext)]) { context = [delegate managedObjectContext]; } 반송 문맥; } – lweingart

1

외부 저장소 기능을 사용하지 않는 한 코어 데이터에 이미지를 저장하지 않는 것이 좋습니다. 대형 바이너리 객체는 코어 데이터와 같은 객체 내부에 저장하려는 경우는 거의 없습니다. 물론 파일 시스템의 이미지를 가리키는 핵심 데이터 객체에 파일 시스템 경로 또는 URL을 저장할 수 있습니다.

코어 데이터를 UICollectionView와 함께 사용하려면 NSFetchedResultsController를 살펴보십시오. 여기에 두 가지를 함께 사용하여 시작하게하는 example이 있습니다.

+0

답장을 보내 주셔서 감사합니다. 사실 나는 내 코드에서 부족한 것을 발견했다. (그러나 나는 8 시간 전에 그것을 게시 할 수 없다 :-)). 핵심 데이터에 개체를 만들 때 외부 저장소를 선택하면 충분합니까? 그렇지 않으면, 나는이 이미지를 응용 프로그램의 Document 폴더에서로드하는 방법을 배우게되어 기쁩니다. 제공된 링크를 살펴 보겠습니다. 당신의 도움을 주셔서 대단히 감사합니다 ! – lweingart

+0

당신이 제공 한 링크를 보러갔습니다. Ash Furrow가 작성한 파일은 제가이 수업을 쓰기에 많은 도움을 준 자습서 중 하나에 속합니다. (당신인가요?) 다시 한번 감사드립니다. – lweingart