Francis
Francis

Reputation: 279

Core Data: Automatically Trim String Properties

For my Core Data NSManagedObject, I would like to ensure any NSString properties only contain strings that have been trimmed of whitespace.

I'm aware that I could achieve this by overriding each setter method, like so:

- (void)setSomeProperty:(NSString *)someProperty
{
    someProperty = [someProperty stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

    if ((!someProperty && !self.someProperty) || [someProperty isEqualToString:self.someProperty]) return;

    [self willChangeValueForKey:@"someProperty"];
    [self setPrimitiveValue:someProperty forKey:@"someProperty"];
    [self didChangeValueForKey:@"someProperty"];
}

However, this seems like a lot of code to have to write, especially since my managed object is likely to have quite a few NSString properties.

Is there an easier way?

Upvotes: 4

Views: 392

Answers (3)

Simon
Simon

Reputation: 25993

You could do it during property validation:

- (BOOL)validateSomeProperty:(id *)inOutValue error:(NSError **)error
{
    if (inOutValue)
    {
        NSString *value = *inOutValue;
        *inOutValue = [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    }

    return YES;
}

Core data will automatically call validateSomeProperty:error: before saving your record, so this will make sure that any data that gets saved is trimmed. It won't stop the on-change events firing if someone changes it from, say, foo to \n\nfoo\n\n, but it does mean that you don't have to fire them by hand.

Upvotes: 1

Marcus Adams
Marcus Adams

Reputation: 53870

You could create a custom NSValueTransformer for NSString and assign all of your NSString properties to the new transformer in the model editor:

@interface StringTransformer: NSValueTransformer {}
@end

@implementation StringTransformer
+ (Class)transformedValueClass { 
  return [NSString class]; 
}

+ (BOOL)allowsReverseTransformation { 
    return YES;
}

- (id)transformedValue:(id)value {
    return value;
}

- (id)reverseTransformedValue:(id)value {
    return [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
@end

Upvotes: 5

Wain
Wain

Reputation: 119041

If you only need to ensure that the saved data is trimmed then you can implement willSave and use changedValues to check only the changed values. This will also make it easy to do in a loop to minimise code duplication.

Upvotes: 2

Related Questions