Skip to main content
Version: 4.4.x

MTE Relay Client for iOS using Swift

Latest Release

Introduction

This Swift Package provides the Eclypses MteRelay Mobile Client for iOS. It enables secure, encrypted HTTP(S) communication between your iOS app and your backend via an MteRelay server. You must have licensed access to an MteRelay server instance. More Info

Purpose of MteRelay:

  • Securely relay HTTP requests to your server
  • Protect sensitive headers and data with MTE encryption
  • Stream large files efficiently
Comprehensive Documentation

This guide provides a quick-start for experienced developers. For detailed examples, troubleshooting, and in-depth explanations, see the complete documentation on GitHub.

Prerequisites

  • iOS 14.0 or later
  • Swift 5.5 or later
  • Access to a licensed MteRelay server instance

Installation

  1. In Xcode, go to File > Add Packages...
  2. Enter the package URL: https://github.com/Eclypses/mte-relay-client-ios.git
  3. Follow the prompts to add the package to your project.

CocoaPods

Add the following to your Podfile:

pod 'MteRelay', :git => 'https://github.com/Eclypses/mte-relay-client-ios.git'

Run pod install to install the package.

Setup

  1. Set up and configure your MteRelay server API to receive and decode requests from your application.
  2. In your iOS app, import the MteRelay module:
import MteRelay
  1. Create a Relay instance and set its delegate:
class YourClass: RelayResponseDelegate {
var relay: Relay!

func relayResponse(success: Bool, responseStr: String, errorMessage: String?) {
// Handle relay callback responses and errors
}

init() async throws {
try await instantiateMteRelay()
}

func instantiateMteRelay() async throws {
relay = try await Relay()
relay.relayResponseDelegate = self
}
}

Usage

Routing Requests through MteRelay

For any request you want to secure, update your code to use the Relay instance:

await relay.dataTask(with: request, headersToEncrypt: headersToEncrypt, pathnamePrefix: pathnamePrefix) { (data, response, error) in
if let error = error {
// Handle the error
}
guard let data = data else {
// Handle the lack of data
}
// Use the response and data as needed
}
  • headersToEncrypt: [String]? – List of header keys to encrypt (optional)
  • pathnamePrefix: String? – Optional path prefix for the relay server

Streamed File Upload

Before uploading, ensure your class conforms to the necessary streaming delegates:

class YourClass: RelayResponseDelegate, RelayStreamResponseDelegate, RelayStreamCompletionDelegate, RelayStreamDelegate {
// Implement required delegate methods:

func getRequestBodyStream(outputStream: OutputStream) {
// Write your multipart file data to the output stream
// Close the stream when done
}

func relayStreamResponse(from relayServerUrl: String, data: Data?, response: URLResponse?, error: Error?) {
// Handle upload response
}

func streamCompletionPercentage(from relayServerUrl: String, bytesCompleted: Double, totalBytes: Double) {
// Update progress indicator
let percentage = (bytesCompleted / totalBytes) * 100
}
}

Then call the upload function (note: synchronous but throws):

try relay.uploadFileStream(request: request, headersToEncrypt: headersToEncrypt, pathnamePrefix: pathnamePrefix)

Streamed File Download

Before downloading, ensure your class conforms to the streaming delegates:

class YourClass: RelayResponseDelegate, RelayStreamResponseDelegate, RelayStreamCompletionDelegate {
func relayStreamResponse(from relayServerUrl: String, data: Data?, response: URLResponse?, error: Error?) {
// Handle download response
}

func streamCompletionPercentage(from relayServerUrl: String, bytesCompleted: Double, totalBytes: Double) {
// Update progress indicator
let percentage = (bytesCompleted / totalBytes) * 100
}
}

Important: Pre-create an empty file at the download location before calling this method:

FileManager.default.createFile(atPath: downloadUrl.path, contents: nil)

Then call the download function (synchronous but throws):

try relay.downloadFileStream(request: request, downloadUrl: downloadUrl, headersToEncrypt: headersToEncrypt, pathnamePrefix: pathnamePrefix)

Re-pair with Server

try await relay.rePairwithRelayServer(your_relay_server_url, pathnamePrefix: pathnamePrefix)

Adjust Relay Settings

try await relay.adjustRelaySettings(serverUrl: Settings.actualServerPath, pathnamePrefix: Settings.pathnamePrefix, newStreamChunkSize: 1048576, newPairPoolSize: 3, persistPairs: false)

Logging

Relay.enableFileLogging(true) // Enable file logging (default: false)

let logContents = try Relay.readLogFile()
Relay.clearLogFile()

API Reference

See the source code and inline documentation for full API details. Key classes:

  • Relay: Main entry point for secure requests and file streaming
  • RelayResponseDelegate: Protocol for receiving responses and errors
  • Settings: Configuration for server URL, chunk size, etc.

Support

Email: info@eclypses.com
Web: www.eclypses.com

Additional Resources

For more detailed examples and advanced implementation patterns, visit the library documentation:


All trademarks of Eclypses Inc. may not be used without Eclypses Inc.'s prior written consent.