CoreData expects a string when returning an array and NSData when returning a string
-
14-11-2019 - |
Question
I have a simple NSValueTransformer
that should convert a comma-separated string first, second, third
into an array. So in my CoreData schema I have the attribute options
which I set to Transformed
and specify my Transformer.
This is my Transformer:
-(id)transformedValue:(id)value{
// convert it to an array
if(!value){
return nil;
} else{
NSString *languages = value;
NSArray *result = [languages componentsSeparatedByString: @", "];
// return result;
return @"test Result";
}
}
Now when I return the variable result
I get the following error (length
looks like it's expecting an NSString
):
... 'NSInvalidArgumentException', reason: '-[__NSArrayI length]: unrecognized selector sent to instance 0x6cc59a0'
If I return the test string above instead I get this error (bytes
looks like it's expecting an NSData
object):
... 'NSInvalidArgumentException', reason: '-[__NSCFConstantString bytes]: unrecognized selector sent to instance 0xf0780'
It looks like there is a conceptual problem which I don't seem to grasp. Also curiously +(Class)transformedValueClass
and +(BOOL)allowsReverseTransformation
are never "touched" when using the Debugger.
Solution
There are no errors in code you provide. The problem lays in your CoreData approach.
When you use transformed property in CoreData, the value is storing in database as NSData object. And length in your errors is related to NSData length method.
Therefore you should provide NSValueTransformer with transformation from NSData to NSArray and reverse to put concatenated arrays to CoreData as NSData.
If you want to keep the possibility to store property as NSString, you can implement special accessor to NSString property of your managed object, which will transform the NSString to NSArray value or use your NSValueTransformer outside your CoreData model like this:
NSValueTransformer *transformer = [NSValueTransformer valueTransformerForName:@"StringToArrayValueTransformer"];
NSArray *array = [transformer transformedValue:yourEntityItem.yourStringProperty];
OTHER TIPS
The value needs to be cast to a NSString try this
-(id)transformedValue:(id)value{
// convert it to an array
if(!value){
return nil;
} else{
NSString *languages = (NSString*)value;
NSArray *result = [languages componentsSeparatedByString: @", "];
return result;
}
}