This document will provide an overview of the gRPC API for Swift. It follows a standard form used by each language-platform implementation.
The following examples use echo.proto to demonstrate basic gRPC operation and generated code.
Swift gRPC client and server code is generated by the protoc-gen-swiftgrpc
plugin.
The plugin is called from protoc
and can be invoked for echo.proto
like this:
protoc Examples/Echo/echo.proto --proto_path=Examples/Echo --swiftgrpc_out=.
var requestMessage = Echo_EchoRequest(text:message)
print("Sending: " + requestMessage.text)
let responseMessage = try service.get(requestMessage)
print("get received: " + responseMessage.text)
// get returns requests as they were received.
func get(request : Echo_EchoRequest) throws -> Echo_EchoResponse {
return Echo_EchoResponse(text:"Swift echo get: " + request.text)
}
let requestMessage = Echo_EchoRequest(text:message)
print("Sending: " + requestMessage.text)
let expandCall = try service.expand(requestMessage)
var running = true
while running {
do {
let responseMessage = try expandCall.Receive()
print("Received: \(responseMessage.text)")
} catch Echo_EchoClientError.endOfStream {
print("expand closed")
running = false
}
}
// expand splits a request into words and returns each word in a separate message.
func expand(request : Echo_EchoRequest, session : Echo_EchoExpandSession) throws -> Void {
let parts = request.text.components(separatedBy: " ")
var i = 0
for part in parts {
try session.Send(Echo_EchoResponse(text:"Swift echo expand (\(i)): \(part)"))
i += 1
sleep(1)
}
}
var done = NSCondition()
let echoProvider = EchoProvider()
var echoServer: Echo_EchoServer!
if useSSL {
print("Starting secure server")
let certificateURL = URL(fileURLWithPath:"ssl.crt")
let keyURL = URL(fileURLWithPath:"ssl.key")
echoServer = Echo_EchoServer(address:"localhost:8443",
certificateURL:certificateURL,
keyURL:keyURL,
provider:echoProvider)
} else {
print("Starting insecure server")
echoServer = Echo_EchoServer(address:"localhost:8081",
provider:echoProvider)
}
echoServer.start()
// Block to keep the main thread from finishing while the server runs.
// This server never exits. Kill the process to stop it.
done.lock()
done.wait()
done.unlock()
let collectCall = try service.collect()
let parts = message.components(separatedBy:" ")
for part in parts {
let requestMessage = Echo_EchoRequest(text:part)
print("Sending: " + part)
try collectCall.Send(requestMessage)
sleep(1)
}
let responseMessage = try collectCall.CloseAndReceive()
// collect collects a sequence of messages and returns them concatenated when the caller closes.
func collect(session : Echo_EchoCollectSession) throws -> Void {
var parts : [String] = []
while true {
do {
let request = try session.Receive()
parts.append(request.text)
} catch Echo_EchoServerError.endOfStream {
break
} catch (let error) {
print("\(error)")
}
}
let response = Echo_EchoResponse(text:"Swift echo collect: " + parts.joined(separator: " "))
try session.SendAndClose(response)
}
var done = NSCondition()
let updateCall = try service.update()
DispatchQueue.global().async {
var running = true
while running {
do {
let responseMessage = try updateCall.Receive()
print("Received: \(responseMessage.text)")
} catch Echo_EchoClientError.endOfStream {
print("update closed")
done.lock()
done.signal()
done.unlock()
break
} catch (let error) {
print("error: \(error)")
}
}
}
let parts = message.components(separatedBy:" ")
for part in parts {
let requestMessage = Echo_EchoRequest(text:part)
print("Sending: " + requestMessage.text)
try updateCall.Send(requestMessage)
sleep(1)
}
try updateCall.CloseSend()
// Wait for the call to complete.
done.lock()
done.wait()
done.unlock()
// update streams back messages as they are received in an input stream.
func update(session : Echo_EchoUpdateSession) throws -> Void {
var count = 0
while true {
do {
let request = try session.Receive()
count += 1
try session.Send(Echo_EchoResponse(text:"Swift echo update (\(count)): \(request.text)"))
} catch Echo_EchoServerError.endOfStream {
break
} catch (let error) {
print("\(error)")
}
}
try session.Close()
}