MTE Relay Client for iOS using Swift
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
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
Swift Package Manager (Recommended)
- In Xcode, go to File > Add Packages...
- Enter the package URL:
https://github.com/Eclypses/mte-relay-client-ios.git - 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
- Set up and configure your MteRelay server API to receive and decode requests from your application.
- In your iOS app, import the MteRelay module:
import MteRelay
- Create a
Relayinstance 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 streamingRelayResponseDelegate: Protocol for receiving responses and errorsSettings: 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:
- GitHub Repository – Source code and comprehensive examples
- Release Notes – Latest updates and changes
All trademarks of Eclypses Inc. may not be used without Eclypses Inc.'s prior written consent.