Search code examples
objective-ccore-datauibuttonnsmanagedobjectnsmanagedobjectcontext

Check if single attribute in managedObjectContext is *not* nil


I have a ServicesViewController with a number of UIButtons. The user can tap a button and has a choice to enter "Further Details" via an UIAlertView with UIAlertViewStylePlainTextInput. If the user chooses not to add "Further Details", the UIButton state stays selected and the key is saved as Yes in my managedObjectContext. If they choose to add "Further Details", the key is still saved as Yes, and the "Further Details" key is saved as whatever string they enter.

The user can then navigate to another ViewController and back to the ServicesViewController when they like. I need to perform a check in the viewDidLoad method in the ServicesViewController, on the keys on my managedObjectContext. If the UIButton key is saved as "Yes", then the UIButton state must be highlighted. Whereas if the "Further Details" key is not nil, then the button must change state to disabled and can also change colour for user feedback.

Code to select the button:

- (IBAction)asbBtnPressed:(UIButton *)sender {
    if ([sender isSelected]) {
        [sender setSelected:NO];
        [_managedObjectNGLS setValue:@"" forKey:@"asb"];
    } else {
        [sender setSelected:YES];
        [_managedObjectNGLS setValue:@"Yes" forKey:@"asb"];
    }

    UIAlertView *qConfirm = [[UIAlertView alloc]initWithTitle:@"Additional Information"
                                                       message:@"Would you like to give additional information?"
                                                      delegate:self
                                             cancelButtonTitle:@"Cancel"
                                             otherButtonTitles:@"Proceed", nil];
    qConfirm.alertViewStyle = UIAlertViewStylePlainTextInput;
    qConfirm.tag = 2;
    if (sender.isSelected == YES) {
        [qConfirm show];
    }
}

If user enters "Further Details", disable button and change colour:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    // ASB
    if (alertView.tag == 2) {
        if (buttonIndex == 1) {
            NSString *asbDetails = [alertView textFieldAtIndex:0].text;
            [_managedObjectNGLS setValue:asbDetails forKeyPath:@"asbDetails"];
            if (asbDetails.length > 1) {
                [_asbBtn setSelected:NO];
                _asbBtn.backgroundColor = [UIColor colorWithRed:(55/255.0) green:(200/255.0) blue:(0/255.0) alpha:1];
                _asbBtn.enabled = FALSE;
            }
        }
    }

Code attempting to check for nil value:

// If UIButton has been selected
if ([[_managedObjectNGLS valueForKey:@"asb"] isEqual: @"Yes"]) {
    _asbBtn.selected = YES;

    // If "Further Details" is empty
} else if ([_managedObjectNGLS valueForKey:@"asbDetails"] == nil) {
    // Do nothing
} else {
    // Else "Further Details" must be populated, so change colour & disable button
    _asbBtn.backgroundColor = [UIColor colorWithRed:(55/255.0) green:(200/255.0) blue:(0/255.0) alpha:1];
    _asbBtn.enabled = FALSE;
    NSLog(@"asbDetails not empty");
}

I realise this is not the best approach (mainly because it isn't working!), idealy I would like to check if the key isn't nil by perfoming a != test, but this doesn't work either. I didn't want to go down the road of a fetchRequest because I have many buttons and many keys to test, and each button must stay separate, so I don't think I can use a for loop either as that would alter all buttons? Correct me if I'm wrong. Thanks in advance!


Solution

  • After some research, I have had to come up with somewhat of a workaround. There is probably a better solution, but this will work for now:

    - (void)isInterested {
        // If valueForKey is "yes", keep button in selected state
        // If ...Details key isn't empty, disable button & change colour
    
        // ASB
        if ([[_managedObjectNGLS valueForKey:@"asb"] isEqual: @"Yes"]) {
            _asbBtn.selected = YES;
        }
        NSString *asbDetails = [_managedObjectNGLS valueForKey:@"asbDetails"];
        if (asbDetails.length > 0) {
            _asbBtn.selected = NO;
            _asbBtn.backgroundColor = [UIColor colorWithRed:(55/255.0) green:(200/255.0) blue:(0/255.0) alpha:1];
            _asbBtn.enabled = FALSE;
            // NSLog(@"asbDetails is not empty");
        }
    
        // More buttons
    }
    

    I am calling the isInterested method in my ServicesViewController viewDidLoad - this means that every time this view is loaded, the isInterested method will perform the required checks and set the UIButton in it's correct state.