Search code examples
iphoneobjective-cipadcore-data

Detect string or integer in Core Data


I have built in some Core Data support into my app from the Core Data Books example. The example uses Dates and Strings. However I have tried adding the ability to add and edit an Integer value.

//If the value is a string
if ([[editedObject valueForKey:editedFieldKey] isKindOfClass:[NSString class]]) {
        textField.hidden = NO;
        datePicker.hidden = YES;
        textField.text = [editedObject valueForKey:editedFieldKey];
        textField.placeholder = self.title;
        [textField becomeFirstResponder];
    }
    //If the value is a number
    else {
        textField.hidden = NO;
        datePicker.hidden = YES;
        textField.text = [[editedObject valueForKey:editedFieldKey] stringValue];
        textField.placeholder = self.title;
        [textField becomeFirstResponder];
    }

The first if statement is the in example code (without the check if its a string, I added that) and I added the else statement to run when its not a string but an integer. It works, however now when I edit a string it skips the if statement, so the line: if ([[editedObject valueForKey:editedFieldKey] isKindOfClass:[NSString class]]) isn't working somehow.

If you do look at the CoreDataBooks example from Apple, my code is the same, only I added a field which takes an Integer 16.

Edit

When putting a breakpoint on the first if statement and returning po [editedObject valueForKey:EditedFiledKey] in the console I get: Can't print the description of a NIL object.

I assume this is because it's before the object is made? This happens when the view appears (the view to enter a new string).

It's upon pressing the save button that this code is run:

- (IBAction)save {

    // Set the action name for the undo operation.
    NSUndoManager * undoManager = [[editedObject managedObjectContext] undoManager];
    [undoManager setActionName:[NSString stringWithFormat:@"%@", editedFieldName]];

    // Pass current value to the edited object, then pop.
    if ([[editedObject valueForKey:editedFieldKey] isKindOfClass:[NSString class]]) {
        [editedObject setValue:textField.text forKey:editedFieldKey];
    }
    else {
        [editedObject setValue:[NSNumber numberWithInteger:[[textField text] integerValue]] forKey:editedFieldKey];
    }

    [self.navigationController popViewControllerAnimated:YES];
}

When this runs, its skips the first if statement and runes the else statement, then crashing and showing the error: Unacceptable type of value for attribute: property = "firstName"; desired type = NSString; given type = __NSCFNumber; value = 0.

firstName is the string attribute in my data model. Im guessing because that first if statement fails, its goes forward an expects an integer? Im really unsure.


Solution

  • I tackled the same problem with more Core Data app. I also adapted the Core Data Books app. If you notice, in the original app, they use a BOOL variable (editingDate) to decide whether to show the date picker or not. I created a second BOOL variable, ('editingTextView`) and just change those BOOL variables depending on what needs to be edited. It may not be the most efficient way, but it is easy to program, and easy to follow what is already there in Core Data Books.