Skip to content

Latest commit

 

History

History
87 lines (65 loc) · 2.83 KB

swift.md

File metadata and controls

87 lines (65 loc) · 2.83 KB

Swift Support

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.

1. Swift calling methods in Objective-C

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.

2. Objective-C calling methods in Swift

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.

3. Swift calling methods in Swift

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 closure

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.