2011-10-20 16 views
12

मैं अपने ऐप के अंदर नई प्रबंधित ऑब्जेक्ट्स बना सकता हूं, एक अलग दृश्य में मेरे पास एक टेबल व्यू है जो मेरे पास मौजूद सभी ऑब्जेक्ट्स दिखाता है।NSFetchedResultsController डेटा रीफ्रेश करें?

जब मैं एक नया प्रबंधित ऑब्जेक्ट (पूरी तरह से अलग दृश्य में) बनाता हूं, तो मैं एक अधिसूचना भेज रहा हूं जो मेरे तालिका दृश्य को नए डेटा के साथ पुनः लोड करने का प्रयास कर रहा है जिसमें मैंने जो नई वस्तु बनाई है, वह शामिल है।

मैं तालिका दृश्य संपादित नहीं कर रहा हूं।

केवल एक प्रबंधित संदर्भ है।

मैं समझ नहीं पा रहा हूं कि मैं क्या गलत कर रहा हूं। अगर मैं ऐप बंद करता हूं और अपनी नई ऑब्जेक्ट को फिर से लॉन्च करता हूं तो टेबल व्यू में होता है। जब मैं अधिसूचना प्राप्त करता हूं, तो मैं पुनः लोडडेटा को कॉल करने की कोशिश कर रहा हूं, और मैंने फिर से लाने का प्रयास किया है, लेकिन मैं जो कुछ भी समाप्त करता हूं वह एक खाली तालिका दृश्य है।

कोड के संदर्भ में, मेरी ListViewController:

@interface MyNotesViewController : UIViewController 
{ 
    NSManagedObjectContext * __managedObjectContext; 
    UITableView * _notesTableView; 
    MyNotesTableViewDelegate_DataSource * _tableDelegate_DataSource; 
} 

मेरे viewDidLoad इस तरह दिखता है:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    _tableDelegate_DataSource = [[MyNotesTableViewDelegate_DataSource alloc] init]; 
    _tableDelegate_DataSource.managedObjectContext = __managedObjectContext; 
    [_notesTableView setDataSource:_tableDelegate_DataSource]; 

    NSError * _coreDataError; 
    BOOL success = [[_tableDelegate_DataSource fetchedResultsController] performFetch:&_coreDataError]; 

    if(success){ 
     [_notesTableView reloadData]; 
    } 
} 

मेरी प्रतिनिधि/डेटा स्रोत वस्तु में मेरे पास है:

@interface MyCommutesTableViewDelegate_DataSource : NSObject 

<UITableViewDataSource, NSFetchedResultsControllerDelegate> 
{ 
    NSManagedObjectContext * __managedObjectContext; 
    NSFetchedResultsController * __fetchedResultsController; 
} 

@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; 

@end 

कार्यान्वयन अंश :

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 
    id <NSFetchedResultsSectionInfo> sectionInfo = 
    [[__fetchedResultsController sections] objectAtIndex:section]; 
    return [sectionInfo numberOfObjects]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *CellIdentifier = @"NotesTableViewCell"; 

    NotesTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) {   
     NSArray * topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NotesTableViewCell" owner:nil options:nil]; 
     for(id currentObject in topLevelObjects){ 
      if([currentObject isKindOfClass:[UITableViewCell class]]){ 
       cell = (NotesTableViewCell*) currentObject; 
       break; 
      } 
     } 

    } 

// Configure the cell. 
    Note * _note = [__fetchedResultsController objectAtIndexPath:indexPath]; 

    [...] 

    return cell; 
} 

अद्यतन

मैं बस सभी वस्तुओं का अनुरोध करने के लिए, क्योंकि मैं त्वरित सुधार मेरी समस्या पड़ा को वापस लाया गया, और उसके बाद मुझे एहसास हुआ, के बाद:

-(NSFetchedResultsController*)fetchedResultsController{ 
    if(!__fetchedResultsController){ 
     NSFetchRequest * request = [[NSFetchRequest alloc] init]; 
     [request setEntity:[NSEntityDescription entityForName:@"Note" inManagedObjectContext:__managedObjectContext]]; 

     [request setFetchBatchSize:10]; 

     NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"noteDate" ascending:NO]; 
     [request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
     [sortDescriptor release]; 

     __fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:__managedObjectContext sectionNameKeyPath:nil cacheName:nil]; 


     __fetchedResultsController.delegate = self; 
     [request release]; 

    } 
    return __fetchedResultsController; 
} 

मैं stander UITableView डेटा स्रोत यहाँ तरीकों मैं अपना संदर्भ सहेजता हूं, मेरे fetch अनुरोध का मैंने पहले ऐप लॉन्च पर उपयोग किया था, अब कोई डेटा नहीं देता है, कोई त्रुटि नहीं है लेकिन यह कुछ भी नहीं देता है।

तो मुझे लगता है कि मैं NSFetchResultsController को कार्यान्वित करने के तरीके में कोई समस्या नहीं है। लेकिन जब मैं एक नई वस्तु को सहेजने के बाद अनुरोध वापस नहीं कर सकता हूं?

नोट अगर मैं फिर से लॉन्च करता हूं, तो मैंने अभी भी अपनी सभी ऑब्जेक्ट्स प्राप्त की हैं, जिसमें नए जोड़े गए हैं।

मानक अनुरोध:

-(NSArray*)getNotes{ 
    NSFetchRequest * request = [[NSFetchRequest alloc] init]; 

    NSEntityDescription * entity = [NSEntityDescription entityForName:@"Note" inManagedObjectContext:[self managedObjectContext]]; 
    [request setEntity:entity]; 

    NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"noteDate" ascending:NO]; 
    [request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
    [sortDescriptor release]; 

    NSError * coreDataError; 
    NSArray * fetchedObjects = [[self managedObjectContext] executeFetchRequest:request error:&coreDataError]; 
    [request release]; 

    if(fetchedObjects != nil){ 
     return fetchedObjects; 
    } else { 
     NSLog(@"ERR: %@", coreDataError); 
     return nil; 
    } 
} 

मैं एक अधिसूचना मुझे एक नई वस्तु कोर डाटा में जोड़ा गया है बताने के लिए इंतज़ार कर रहा हूँ, और फिर मैं उपरोक्त विधि बोल रहा हूँ और फिर मेरी tableview पर reloadData बुला ...

उत्तर

26

आप UITableViewController को NSFetchedResultsControllerDelegate के रूप में सेट कर रहे हैं। अच्छी बात है। अब तो जैसे TableViewController में controllerDidChangeContent: विधि को लागू करने का प्रयास करें:

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView reloadData]; 
} 

आपका NSFetchedResultsController कोर डाटा में निकाले जा चुके या नई वस्तुओं को सुनने और परिवर्तन के अपने प्रतिनिधि (अपने TableViewController) को सूचित करेंगे। UITableView में ऐड और हटाने एनिमेशन के साथ इसे बेहतर बनाने के लिए एक्सकोड में कोर डेटा टेम्पलेट प्रोजेक्ट की जांच करें।

+0

बेशक आप अपने मामले में _notesTableView को फिर से लोड करना चाहते हैं के लागू। – huesforalice

+10

यह भी न भूलें कि 'NSFetchedResultsController' केवल '-SaveanagedObjectContext' पर कॉल किया जा रहा है 'पर प्रतिक्रिया करेगा। इसलिए यदि आप नव निर्मित इकाई को सहेज नहीं रहे हैं तो आप इस विधि को आग नहीं देख सकते हैं। –

+0

धन्यवाद, मैं नियंत्रक DidChangeContent को कार्यान्वित कर रहा हूं: NSFetchedResultsControllerDelegate प्रोटोकॉल से, मेरे tableview पर reloadData को कॉल करना। मैंने ब्रेकपॉइंट्स जोड़े हैं और इस विधि को बुलाया जा रहा है, लेकिन टेबलव्यू खाली रीलोडिंग है। अगर मैं ऐप को फिर से लॉन्च करता हूं, तो मैं अपने सभी रिकॉर्ड देख सकता हूं जिसमें नया शामिल है। मैं क्या खो रहा हूँ? पीएस: क्या मुझे नियंत्रक को कार्यान्वित करना है: didChangeObject: atIndexPath: forChangeType: newIndexPath? – Daniel

2

didChangeObject विधि जोड़ना सुनिश्चित करें:

- (void)controller:(NSFetchedResultsController *)controller 
    didChangeObject:(id) anObject 
     atIndexPath:(NSIndexPath *)indexPath 
    forChangeType:(NSFetchedResultsChangeType)type 
     newIndexPath:(NSIndexPath *)newIndexPath 
{ 
    switch(type) 
    { 
    case NSFetchedResultsChangeInsert: 
     [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] 
          withRowAnimation:UITableViewRowAnimationFade]; 
     break; 
    case NSFetchedResultsChangeDelete: 
     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
          withRowAnimation:UITableViewRowAnimationFade]; 
     break; 
    case NSFetchedResultsChangeUpdate: 
     [self configureCell:[self.tableView 
    cellForRowAtIndexPath:indexPath] 
       atIndexPath:indexPath]; 
     break; 
    case NSFetchedResultsChangeMove: 
     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
          withRowAnimation:UITableViewRowAnimationFade]; 
     [self.tableView insertRowsAtIndexPaths:[NSArray 
          arrayWithObject:newIndexPath] 
          withRowAnimation:UITableViewRowAnimationFade]; 
     break; 
    } 
} 

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 
{ 
    NSManagedObject *note = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
    cell.textLabel.text = [note valueForKey:@"title"]; 
} 

नए प्रबंधित वस्तु इस के बाद तालिका दृश्य में दिखाया।

0

यदि किसी के पास एक ही समस्या है, जैसा कि मैंने अभी किया था। मैंने हरे रंग की टिक के साथ उपर्युक्त समाधान की कोशिश की है, लेकिन यह मेरे लिए काम नहीं करेगा। मैंने Apple's code का पालन किया है और सब कुछ ठीक हो गया है।

बस, सिर्फ तीन "Fetchcontroller" प्रतिनिधि कार्यों

func controllerWillChangeContent(controller: NSFetchedResultsController) { 
      self.tableView.beginUpdates() 
     } 


    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) { 

      switch type { 
      case .Insert: 
       self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade) 
      case .Delete: 
       self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade) 
      case .Update: 
       print("") 
       self.configureCell(self.tableView.cellForRowAtIndexPath(indexPath!)!, indexPath: indexPath!) 
      case .Move: 
       self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade) 
       self.tableView.insertRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade) 
      } 
     } 


func controllerDidChangeContent(controller: NSFetchedResultsController) { 
      self.tableView.endUpdates() 
     } 
संबंधित मुद्दे