String.self isn't compatible with AnyClass in ValueTransformer

Tracking down some errors in ValueTransformers in an old project. It seems that String.self can't be returned as AnyClass since it is a value type.

So this works in Xcode 12.5:
Code Block
func test() -> AnyClass
{
// just for checking
    type(of: NSString.self)
    type(of: String.self)
    type(of: NSNumber.self)
    return NSString.self
}


But this doesn't:
Code Block
func test2() -> AnyClass
{
    return String.self
}


Cannot convert return expression of type 'String.Type' to return type 'AnyClass' (aka 'AnyObject.Type')

So back to the ValueTransformer. This was the code that seemed to compile circa 2016. Now has a warning that it will fail.

Code Block
override class func transformedValueClass() -> AnyClass
{
  return String.self as! AnyClass
}


String is a struct not a class.

And doing this produces an error - because String is a struct

Code Block
override class func transformedValueClass() -> AnyClass
{
  return String.self
}

So is the correct approach to work with NSStrings in ValueTransformers? Simply cast the last return with:

Code Block
return swiftNSString(utf8String:string)

Similarly, Bool is also a struct and has the same issues. But BOOL isn't available so it looks like NSNumber.

This was the code that seemed to compile circa 2016.

As far as I know, none of the Swift compilers accepted String.self as AnyClass.
And at least in Xcode 8.3.3 (early 2017, I think), it does not compile.

You may be confused with something else.

So is the correct approach to work with NSStrings in ValueTransformers?

It is not clear what you really want to do so not sure if it is correct or not.
But usually NSString in Objective-C side would automatically converted to String in Swift.

If you could clarify what you were trying to do, I would be able to show some example.


It was written 5 years ago so it's possible that things were more confused back then 😃

Worked through cleaning up the code.

Thanks for the response.

Yes, NSStrings are converted back to String so internal to the ValueTransformer you can simply pass a String value back where the ValueTransformer is defined to return NSString.self.

So there is no need to wrap a conversion from String to NSString.

Code Block
override class func transformedValueClass() -> AnyClass
{  
return NSString.self
}
override func transformedValue(_ value: Any?) -> Any?
{
        let str = convert(value) // returns a String
        return str
}

This needs to be within the Objective-C side since the string is being handed back to a Cocoa Binding. So have to return NSObjects. So using NSNumbers for bool conversion works too.

What was also less obvious what that there was a work around that generated a string for the Entity directly, bypassing the ValueTransformer. So buried in the IB Bindings inspector you could see that but not obvious just from reading the code. Alas, the importance of documenting code work arounds and explaining which code isn't actually working.


String.self isn't compatible with AnyClass in ValueTransformer
 
 
Q