swiftcocoaxpcnsxpcconnectionnssecurecoding

Must NSSecureCoding-implementing classes be in shared framework to work with XPC?


While following Creating XPC Services guide in Swift and trying to pass custom Foo class I found that in order for this to work it must be in a dynamic library. When it's embedded into both targets the connection to service fails with 4097 code. Same happens if Foo is in a static lib.

I can't seem any references to this requirement and guessing this is due to the fact that security identifies them as different objects while decoding. Is this true? Any more concrete info on this?


Solution

  • The problem lays with Swift name mangling, which results in different class names in different targets, so when XPC decoder tries to securely decode a received object it sees a different class name from specified and fails.

    With obj.io XPC example compiled Swift @objc class Foo: NSObject, NSSecureCoding class in app and service targets has @class Foo : NSObject<NSSecureCoding> and @class _TtC15ImageDownloader3Foo : NSObject<NSSecureCoding> signatures, respectively.

    To avoid this simply add explicit Objective-C name in @objc(Foo) tag, which will produce the same @class Foo : NSObject<NSSecureCoding> class signature in both targets.