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:
- The common dependency that defines the protocols
// In Swift
@objc
public protocol RemoteInterface {
func remoteFoo() -> Bar
}
@objc
public protocol RootObjectExtension {
func remoteInterface() -> RemoteInterface
}
- The service side implementation
class ActualImplementation: RemoteInterface {
func remoteFoo() -> Bar {
// Your actual implementation.
}
}
@objc
extension RootObject: RootObjectExtension {
// The client calling this method to require the remote object.
func remoteInterface() -> RemoteInterface {
return ActualImplementation()
}
}
- The client side retrieving the remote objects
let rootObject = EDOClientService<RootObjectExtension>.rootObject(withPort: portNumber)
let remote = rootObject.remoteInterface()
remote.remoteFoo()
In the code above, RootObject
is defined and implemented on the server side.
This will then be used as an entry point to return the protocol
RootObjectExtension
.
Working example is shown here.
Alternatively, you can extend the root object directly. It is up to the user how they want to organize their code structure.
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.