Can't add readwrite to property in bridging header, it seems

Using Xcode 10.1 (Swift 4.2), it seems I can't do this:

//  Obj.h

@interface Obj : NSObject

@property (copy, readonly)  NSString* foo;

//  Obj+Private.h

@interface Obj()

 @property (copy, readwrite)  NSString* foo;

//  BridgingHeader.h

#import "Obj.h"
#import "Obj+Private.h"
//  Obj.swft

extension Obj
    public convenience init(object inObject: MarshaledObject)
        self.init() = inObject.value(for: "someKey")
        //  'let' property 'foo' may not be initialized directly; use "self.init(...)" or "self = ..." instead

If I remove the readonly and readwrite attributes, it compiles fine.

Is this a bug in Xcode/Swift? I tried googling for this but only came up with articles about Obj-C interop.

We need a better way to diagnose it, but if the nullability of the property doesn't match between the original declaration and the redeclaration in the class extension (nameless category), the Swift compiler will just drop it because it doesn't know which nullability is the "real" one. (I forget if there's a reason it can't just assume the readonly one is the "real" one.) I suspect that's what's happening to your actual case, possibly via NS_ASSUME_NONNULL_BEGIN/_END.

1 Like

Yeah, seems like it could just inherit the nullability, and issue an error if an explicit nullability doesn't match.