managedObjectContext保存问题

时间:2011-03-28 20:45:33

标签: objective-c core-data

在过去的几天里,我进行了广泛的搜索,并遵循了我在网上找到的所有决议都没有成功。

基本上,我正在从网上提取的JSON数据中刷新Core Data实体。我可以清除以前从网络上提取的数据并加载新数据。当我尝试保存到Core Data“[self.managedObjectContext save:& error];”时发生问题。“。
该应用程序只是锁定。

我的视图控制器中的代码如下所示。我非常感谢任何帮助。

** 代码 ***

//
//  ChargeEntryViewController.m
//  pcc
//
//  Created by Tim Black on 3/14/11.
//  Copyright 2011 Mobile Intents. All rights reserved.
//

#import "ChargeEntryViewController.h"
#import "pccAppDelegate.h"
#import "ChargeEntryPatientViewController.h"
#import "CJSONDeserializer.h"

@interface ChargeEntryViewController (PrivateMethods)
- (NSString *)jsonFromURLString:(NSString *)urlString;
- (void)handleError:(NSError *)error;
@end

@implementation ChargeEntryViewController

@synthesize fetchedResultsController=fetchedResultsController_;
@synthesize managedObjectContext=managedObjectContext_;

@synthesize providerArray;
@synthesize clearBtn;
@synthesize setBtn;
@synthesize patientController;


#pragma mark - Button methods
-(IBAction) clearAll:(id)sender{
    selRow = -1;

    [providerList reloadData];
}

-(IBAction) setPatientView:(id)sender {
    if (self.patientController == nil) {
        ChargeEntryPatientViewController *tmpController = [[ChargeEntryPatientViewController alloc] initWithNibName:@"ChargeEntryPatientView" bundle:nil];
        self.patientController = tmpController;
        [tmpController release];
    }
    patientController.title = @"Patient Selection";

    [self.navigationController pushViewController:patientController animated:YES];
}

/*
 Used to refresh the providers list from nrhsportal
*/
-(void)refreshProviders {
    NSError *error = nil;

    // get provider code from app delegate
    pccAppDelegate *appDelegate = (pccAppDelegate *)[[UIApplication sharedApplication] delegate];

    // first, clear out current list stored locally
    NSFetchRequest *fetch = [[[NSFetchRequest alloc] init] autorelease];
    [fetch setEntity:[NSEntityDescription entityForName:@"Provider" inManagedObjectContext:self.managedObjectContext]];
    NSArray *result = [self.managedObjectContext executeFetchRequest:fetch error:&error];
    if (error != nil) {
        [self handleError:error];
        return;
    }
    for (id basket in result) {
        [self.managedObjectContext deleteObject:basket];
    }

    // add (My Patients) entry
    NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"Provider" inManagedObjectContext:self.managedObjectContext];
    [newManagedObject setValue:@"(My Patients)" forKey:@"fullname"];
    [self.managedObjectContext insertObject:newManagedObject];

    NSString *code = appDelegate.groupCode;

    // create remote source URI
    NSString *urlString = [NSString stringWithFormat:@"%s%@%s", "https://nrhsportal.nrh-ok.com/pccdata.svc/GetProviders?groupcode='", code, "'&$format=json"];
    NSLog(@"URL String %@", urlString);

    // Perform HTTP GET to the REST web service which returns JSON
    NSString *jsonString = [self jsonFromURLString:urlString];
    NSData *jsonData = [jsonString dataUsingEncoding:NSUTF32BigEndianStringEncoding];

    // Parse JSON results to convert to a dictionary
    CJSONDeserializer *jsonDeserializer = [CJSONDeserializer deserializer];
    error = nil;
    NSDictionary *resultsDictionary = [jsonDeserializer deserializeAsDictionary:jsonData error:&error];
    if (error != nil) {
        [self handleError:error];
        return;
    }

    // Traverse through returned dictionary to populate tweets model
    NSDictionary *topArray = [resultsDictionary objectForKey:@"d"];
    NSArray *resultsArray = [topArray objectForKey:@"results"];
    for (NSDictionary *resultDictionary in resultsArray) {
        // create the 
        NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"Provider" inManagedObjectContext:self.managedObjectContext];

        NSString *providerName = [resultDictionary objectForKey:@"fullname"];
        [newManagedObject setValue:providerName forKey:@"fullname"];

        [self.managedObjectContext insertObject:newManagedObject];
    }

    error = nil;
    [self.managedObjectContext save:&error];
    if (error != nil) {
        [self handleError:error];
        return;
    }

    [newManagedObject release];
    [result release];

}

// This will issue a request to a web service API via HTTP GET to the URL specified by urlString.
// It will return the JSON string returned from the HTTP GET.
- (NSString *)jsonFromURLString:(NSString *)urlString {
    NSURL *url = [NSURL URLWithString:urlString];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    [request setHTTPMethod:@"GET"];

    NSURLResponse *response = nil;
    NSError *error = nil;
    NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    [request release];
    [self handleError:error];
    NSString *resultString = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
    return [resultString autorelease];
}

// This shows the error to the user in an alert.
- (void)handleError:(NSError *)error {
    if (error != nil) {
        UIAlertView *errorAlertView = [[UIAlertView alloc] initWithTitle:@"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"Close" otherButtonTitles:nil];
        [errorAlertView show];
        [errorAlertView release];
    }  
}

#pragma mark - View lifecycle

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    selRow = -1;

    // refresh the provider list from remote data

    [self refreshProviders];

    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. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
         */
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }       

}

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {

    NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = [[managedObject valueForKey:@"fullname"] description];
    cell.textLabel.font=[UIFont systemFontOfSize:16.0];
    if ([cell.textLabel.text isEqualToString: @"(My Patients)"]) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
    else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark Table view methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [[self.fetchedResultsController sections] count];
}


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


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell.
    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:YES];

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    if (cell.accessoryType == UITableViewCellAccessoryNone) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        // Reflect selection in data model
    } else if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
        cell.accessoryType = UITableViewCellAccessoryNone;
        // Reflect deselection in data model
    }
}

#pragma mark - Fetched results controller

- (NSFetchedResultsController *)fetchedResultsController {

    if (fetchedResultsController_ != nil) {
        return fetchedResultsController_;
    }

    /*
     Set up the fetched results controller.
     */
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Provider" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"fullname" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    [aFetchedResultsController release];
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];

    return fetchedResultsController_;
}    

#pragma mark - Memory management
- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)dealloc
{
    [patientController release];
    [clearBtn release];
    [setBtn release];
    [providerArray release];
    [fetchedResultsController_ release];
    [managedObjectContext_ release];
    [super dealloc];
}


@end

1 个答案:

答案 0 :(得分:1)

您不需要该行

[self.managedObjectContext insertObject:newManagedObject];

因为你之前已经使用newManagedObject insertNewObjectForEntityForName