eDistantObject supports Swift as Swift is fundamentally interoperable with Objective-C. More details in Apple doc around MixAndMatch. However, pure Swift calls are statically linked, therefore, invocations are not through the Objective-C runtime. There are three different scenarios when working with Swift.
This works naturally when importing Objective-C headers as Swift will invoke those methods already in an Objective-C manner and trigger the runtime to forward invocations. As is usual with Swift, these method definitions must be exposed in a bridging header.
The methods need to be annotated with @objc
so that it can be exported to Objective-C and is visible. Once the invocation is fired in Objective-C, it will properly be forwarded to the remote site.
The above two scenarios should work as long as the methods are tagged with @objc.
In the Objective-C case, the compiler needs to see the header in order to know how to run your code. However, there is no header in Swift. The workaround is to define a protocol, to serve as a header, and then expose the object to work with as a protocol.
For example:
// In Swift @objc public protocol RemoteInterface { func remoteFoo() -> Bar } @objc public protocol StubbedClassExtension { func remoteInterface() -> RemoteInterface } class ActualImplementation : RemoteInterface { func remoteFoo() -> Bar { // Your actual implementation. } } @objc extension AlreadyStubbedClass : StubbedClassExtension { // The client calling this method to require the remote object. func remoteInterface() -> RemoteInterface { // return the actual implementation of RemoteInterface } }
// In Objective-C // Define a Objective-C bridge so Swift can extend. @interface AlreadyStubbedClass @end
In the code above, AlreadyStubbedClass
is defined in Objective-C and will be imported as a regular eDistantObject in both Swift files. This will then be used as an entry point to return the protocol RemoteInterface
. The remote invocation will be:
RemoteInterface remote = unsafeCast(AlreadyStubbedClass.sharedClass, to:StubbedClassExtension.self).remoteInstance remote.remoteFoo()
Here the unsafeCast
lets the compiler know the AlreadyStubbedClass
has the extension. Working example is shown here.
The block is also supported but it may confuse the compiler and the runtime as the calling convention can be different. Adding @escaping to let both the runtime and the compiler to know how to handle the block scope. For example.