3

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?

Ian Bytchek
  • 8,804
  • 6
  • 46
  • 72
  • Both of them (app and XPC service) must know about your Foo class yes, that doesn't mean Foo must live in a shared library. You can simply include Foo when building each of them. Why do you believe error ```4097``` has to do with that? – pfandrade Apr 09 '18 at 22:32
  • Because I eliminated all other options. Also didn't mention that this is Swift, which turned out to be the cause in the end. Thanks for looking into this! – Ian Bytchek Apr 10 '18 at 06:00

1 Answers1

3

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.

Ian Bytchek
  • 8,804
  • 6
  • 46
  • 72