2013-09-28 84 views
0

所以我有一個實用程序的應用程序,我試圖將一些文本保存到Flipside View Controller的「To」和「Message:」文本字段中,但是我的數據不會保存。客觀C和我一直在使用多個不同的教程的地步,我已經完全糊塗了我自己。希望你能幫助我。不知道還有什麼在這一點上做的......核心數據問題。數據不會保存

FlipsideViewController.m

#import "CCCFlipsideViewController.h" 
#import "CCCAppDelegate.h" 
#import "CCCMainViewController.h" 
#import "MessageDetails.h" 

@interface CCCFlipsideViewController() 
{ 
    // NSManagedObjectContext *context; 
} 
@end 

@implementation CCCFlipsideViewController 
@synthesize allMessageDetails; 
@synthesize managedObjectContext; 

- (void)awakeFromNib 
{ 
    [super awakeFromNib]; 

    CCCAppDelegate *appDelegateController = [[CCCAppDelegate alloc]init]; 
    self.managedObjectContext = appDelegateController.managedObjectContext; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // Do any additional setup after loading the view, typically from a nib. 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription 
            entityForName:@"MessageDetails" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    NSError *error; 

    self.allMessageDetails = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

    /* 
    NSManagedObject *managedObject; = [_fetchedResultsController valueForKey:@"to"]; 
    self.toTextField.text = managedObject to; 

    messageDetails.to = [allMessageDetails firstObject]; 
    self.toTextField.text = messageDetails.to; 

    messageDetails.message = [allMessageDetails valueForKey:@"message"]; 
    self.messageTextField.text = messageDetails.message; 
    */ 
    NSLog(@"The 'to' is currently at %@ after viewdidload", self.toTextField.text); 

    } 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

- (BOOL)textFieldShouldReturn:(UITextField *)textField 
{ 
    return [textField resignFirstResponder]; //function says that if (bool) the text field is open and the keyboard hits return, text field is to resign first responder. 
} 

#pragma mark - Actions 
- (IBAction)done:(id)sender 
{ 
    [self.delegate flipsideViewControllerDidFinish:self]; 
} 

- (IBAction)resignFirstResponder:(id)sender { 

    [self.toTextField resignFirstResponder]; 
    [self.messageTextField resignFirstResponder]; 
    NSLog(@"Resigned First Responder"); 
} 


- (IBAction)save:(id)sender { 

    // Create a new instance of the entity managed by the fetched results controller. 
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext]; 
    NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity]; 
    NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context]; 

    // If appropriate, configure the new managed object. 
    [newManagedObject setValue:self.toTextField.text forKey:@"to"]; 
    [newManagedObject setValue:self.messageTextField.text forKey:@"message"]; 

    // Save the context. 
    NSError *error = nil; 
    if (![context save:&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(); 
    } 


} 


#pragma mark - 
#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:@"MessageDetails" 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:@"to" ascending:NO]; 
    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; 


    NSError *error = nil; 
    if (![_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(); 
    } 

    return _fetchedResultsController; 
} 


@end 
+0

您的NSlog在保存功能中是否打印任何內容? –

+0

當我在頁面上時,它會告訴我「到」文本字段中的內容。但是,只要我切換到主視圖控制器並回來,到文本字段顯示爲空... –

+0

我問的是,當您調用save:函數時,任何記錄到控制檯,像一個錯誤的描述? –

回答

1

我沒有看所有的代碼,因爲在頂端附近出現了一個問題,否定了你之後做的所有事情。不要在awakeFromNib或其他任何地方分配/初始化你的應用程序委託。您的應用程序委託的實例已經存在(我不知道當有多個應用程序委託時會發生什麼)。

CCCFlipsideViewController需要通過另一種方式訪問​​受管對象上下文。也許CCCMainViewController(或另一個視圖控制器)可以設置CCCFlipsideViewController的managedObjectContext屬性。如果CCCMainViewController無法訪問託管對象上下文,請讓應用程序委託將該上下文傳遞給它。

示例: 應用程序委託在根視圖控制器上設置managedObjectContext屬性;反過來,根視圖控制器設置子視圖控制器上的managedObjectContext屬性(如你的flipside VC)等。

+0

謝謝你。顯然從教程中選錯了。我不知道如何將管理的對象上下文傳遞給它。如果沒有早期的應用程序崩潰。你有任何想法如何從主視圖控制器傳遞它?如果你有時間,會非常感謝你的幫助。謝謝你,先生! –

+0

我建議你下載BASE或添加sqlite文件擴展插件,你將需要然後提前。 –

+0

蠟筆小新,你很有雄心,很快就能處理Core Data。在嘗試解決Core Data問題之前,我花了整整一年的時間進行iOS編程。 Apple在此處提供了核心數據先決條件列表:[https://developer.apple.com/library/ios/referencelibrary/GettingStarted/GettingStartedWithCoreData/index.html#//apple_ref/doc/uid/TP40005316-CH1-SW3] – bilobatum

0

你似乎沒有真正設置self.messageTextField.text或self.toTextField.text任何事情 - 你已經注意到你的viewDidLoad方法中設置這些字段的代碼。 bilobatum是關於你的AppDelegate問題完全正確的,以及 - 你也可以使用類似

[((NSObject*)[UIApplication sharedApplication].delegate) valueForKey: @"managedObjectContext"]; 

獲得應用程序的委託爲您的應用程序,如果你想修復快,但長期bilobatum的解決方案,這是更好設計。

+0

我只是想把這些字段留空。我希望用戶輸入文本並保存。我正在通過打印變量 –

+0

來檢查它是否保存在控制檯日誌中。如果視圖控制器已關閉並重新打開,則您的措辭似乎意味着要重新填充這些字段 - 您說要「保存」,而不是「保存」文本字段的內容。我的錯。 –

0

老實說,我認爲你做了相當多的此代碼...;)

OK,首先,在您保存方法,不創建另一個NSManagedObjectContext中,使用實例變量你已經聲明,「managedObjectContext」。

其次,我覺得你的方式做事情自己太複雜了......存儲核心數據實際上是驚人的簡單,一旦你創建了NSManagedObject子類,並設置了一切在App代表...

看起來好像你不需要在代碼中的「fetchedResultsController」中的任何信息,因爲你正在保存,而不是提取。也許嘗試改變你的保存方法是這樣的:

- (IBAction)save:(id)sender { 

    NSEntityDescription *entity = [NSEntityDescription insertNewObjectForEntityForName:@"MessageDetails" inManagedObjectContext:self.managedObjectContext]; 

    // If appropriate, configure the new managed object. 
    [entity setValue:self.toTextField.text forKey:@"to"]; 
    [entity setValue:self.messageTextField.text forKey:@"message"]; 

    // Save the context. 
    NSError *error = nil; 
    [self.managedObjectContext save:&error] 

    if (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(); 
    } 

}


編輯:而且獲得來自應用程序的委託管理對象場景...

右後你@合成的,爲App Delegate創建一個變量。

AppDelegate* appDelegateController; 

而且在viewDidLoad中,初始化:

appDelegateController = (AppDelegate*)[[UIApplication sharedApplication] delegate]; 

右viewDidLoad中(或任何你想要的),你可以在一個方法堅持申報管理對象上下文後:

- (NSManagedObjectContext*)managedObjectContext { 
    return appDelegateController.managedObjectContext; 
} 

然後回到viewDidLoad中,調用該方法:

self.managedObjectContext = [self managedObjectContext]; 
+0

感謝您的幫助。我嘗試了你的功能,但我回到了控制檯的以下錯誤... 由於未捕獲的異常'NSInvalidArgumentException',原因:'+ entityForName:nil不是合法的NSManagedObjectContext參數搜索實體名'MessageDetails'' 任何想法? –

+0

謝謝您的額外編輯。不幸的是,我仍然得到錯誤'終止應用程序由於未捕獲的異常'NSInvalidArgumentException',原因:'+ entityForName:nil不是合法的NSManagedObjectContext參數搜索實體名'MessageDetails''' –

+0

[self managedObjectContext]可能返回零在這種情況下......這可能是你在App Delegate中設置的方式的問題...... –