Skip to content

Commit

Permalink
swift: add library response interfaces (#273)
Browse files Browse the repository at this point in the history
Adds Swift interfaces for responses within Envoy. These should be at parity with the interfaces being added for Kotlin in envoyproxy/envoy-mobile#265.

Replaces envoyproxy/envoy-mobile#261.

Resolves envoyproxy/envoy-mobile#118.
Also resolves envoyproxy/envoy-mobile#247.

Signed-off-by: Michael Rebello <[email protected]>
Signed-off-by: JP Simard <[email protected]>
  • Loading branch information
rebello95 authored and jpsim committed Nov 29, 2022
1 parent 97bc3c2 commit 3d1e1ad
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 1 deletion.
2 changes: 1 addition & 1 deletion mobile/examples/swift/hello_world/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Envoy
import UIKit

private enum ConfigLoadError: Error {
private enum ConfigLoadError: Swift.Error {
case noFileAtPath
}

Expand Down
4 changes: 4 additions & 0 deletions mobile/library/swift/src/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ load("//bazel:swift_static_framework.bzl", "swift_static_framework")
swift_static_framework(
name = "ios_framework",
srcs = [
"Client.swift",
"Envoy.swift",
"Error.swift",
"LogLevel.swift",
"Request.swift",
"RequestBuilder.swift",
"RequestMethod.swift",
"ResponseHandler.swift",
"RetryPolicy.swift",
"StreamEmitter.swift",
],
module_name = "Envoy",
objc_includes = ["//library/objective-c:EnvoyEngine.h"],
Expand Down
12 changes: 12 additions & 0 deletions mobile/library/swift/src/Client.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/// Client that is able to send and receive requests through Envoy.
@objc
public protocol Client {
/// Start a new stream.
///
/// - parameter request: The request for opening a stream.
/// - parameter handler: Handler for receiving stream events.
///
/// - returns: Emitter for sending streaming data outward.
func startStream(request: Request, handler: ResponseHandler)
-> StreamEmitter
}
17 changes: 17 additions & 0 deletions mobile/library/swift/src/Error.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Foundation

@objcMembers
public final class Error: NSObject, Swift.Error {
/// Error code associated with the exception that occurred.
public let errorCode: Int
/// A description of what exception that occurred.
public let message: String
/// Optional cause for the error.
public let cause: Swift.Error?

init(errorCode: Int, message: String, cause: Swift.Error?) {
self.errorCode = errorCode
self.message = message
self.cause = cause
}
}
39 changes: 39 additions & 0 deletions mobile/library/swift/src/ResponseHandler.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import Foundation

/// Callback interface for receiving stream events.
@objc
public protocol ResponseHandler {
/// Called when response headers are received by the stream.
///
/// - parameter headers: The headers of the response.
/// - parameter statusCode: The status code of the response.
func onHeaders(_ headers: [String: [String]], statusCode: Int)

/// Called when a data frame is received by the stream.
///
/// - parameter data: Bytes in the response.
/// - parameter endStream: True if the stream is complete.
func onData(_ data: Data, endStream: Bool)

/// Called when response metadata is received by the stream.
///
/// - parameter metadata: The metadata of the response.
/// - parameter endStream: True if the stream is complete.
func onMetadata(_ metadata: [String: [String]], endStream: Bool)

/// Called when response trailers are received by the stream.
///
/// - parameter trailers: The trailers of the response.
func onTrailers(_ trailers: [String: [String]])

/// Called when an internal Envoy exception occurs with the stream.
///
/// - parameter error: The error that occurred with the stream.
func onError(_ error: Error)

/// Called when the stream is canceled.
func onCanceled()

/// Called when the stream has been completed.
func onCompletion()
}
50 changes: 50 additions & 0 deletions mobile/library/swift/src/StreamEmitter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import Foundation

/// Interface allowing for sending/emitting data on an Envoy stream.
@objc
public protocol StreamEmitter {
/// Returns whether the emitter is still active and can
/// perform communications with the associated stream.
///
/// - returns: True if the stream is active.
func isActive() -> Bool

/// Send data over the associated stream.
///
/// - parameter data: Data to send over the stream.
///
/// - throws: `Envoy.Error` when the stream is inactive or data can't be sent.
///
/// - returns: The stream emitter, for chaining syntax.
func sendData(_ data: Data) throws -> StreamEmitter

/// Sent metadata over the associated stream.
///
/// - parameter metadata: Metadata to send over the stream.
///
/// - throws: `Envoy.Error` when the stream is inactive or data can't be sent.
///
/// - returns: The stream emitter, for chaining syntax.
func sendMetadata(_ metadata: [String: [String]]) throws -> StreamEmitter

/// End the stream after sending any provided trailers.
///
/// - parameter trailers: Trailers to send over the stream.
///
/// - throws: `Envoy.Error` when the stream is inactive or data can't be sent.
func close(trailers: [String: [String]]) throws

/// Cancel and end the associated stream.
///
/// - throws: `Envoy.Error` when the stream is inactive or data can't be sent.
func cancel() throws
}

extension StreamEmitter {
/// Convenience function for ending the stream without sending any trailers.
///
/// - throws: `Envoy.Error` when the stream is inactive or data can't be sent.
public func close() throws {
try self.close(trailers: [:])
}
}

0 comments on commit 3d1e1ad

Please sign in to comment.