Client-Side Swift Mapping for Operations
Mapping for Operations
As we saw in the Client-Side Swift Mapping for Interfaces, for each operation on an interface, the generated proxy protocol extension contains a method with the same name. To invoke an operation, you call this method on the proxy. For example, let’s take the generated code from the greeter example:
module VisitorCenter
{
interface Greeter
{
string greet(string name);
}
}
The proxy protocol generated from the Greeter interface, after removing extra details, is as follows:
public protocol GreeterPrx: Ice.ObjectPrx {}
public extension GreeterPrx {
func greet(
_ iceP_name: Swift.String,
context: Ice.Context? = nil
) async throws -> Swift.String {
// ...
}
}
public extension NodePrx {
func name(context: Ice.Context? = nil) async throws -> String {
...
}
}
Given a proxy to an object of type Greeter, the client can invoke the greet operation as follows:
let greeter = try makeProxy(
communicator: communicator, proxyString: "greeter:tcp -h localhost -p 4061",
type: GreeterPrx.self)
let greeting = try await greeter.greet("Alice") // Get name via RPC
This code asynchronously calls greet on the proxy, which sends the request to the server, waits until the operation is complete, and then unmarshals the return value and returns it to the caller.
Async Methods
All proxy methods generated by the Slice compiler are async which align with Swift's structured concurrency and async/await model. Therefore, synchronous invocations are not supported.
Exception Handling
Any operation invocation may throw a runtime exception and, if the operation has an exception specification, may also throw user exceptions. Suppose we have the following simple interface:
exception Tantrum
{
string reason;
}
interface Child
{
void askToCleanUp() throws Tantrum;
}
Slice exceptions are thrown as Swift exceptions, so you can simply enclose one or more operation invocations in a do-catch block:
let child: ChildPrx = ... // Get child proxy...
do {
try await child.askToCleanUp()
} catch let t as Tantrum {
print("The child says: \(t.reason)")
}