Skip to main content
Version: 5.x

Migrating the Flutter plugin from v4

This page takes an app from any 4.x release of the Flutter plugin to 5.3.0. For a fresh integration, use the Flutter guide instead.

Upgrade the client and the relay together

5.3.0 speaks frame version 2 and needs a v5 relay. A v4 plugin cannot talk to a v5 relay (the relay answers 478), and 5.3.0 cannot talk to a v4 relay. Plan the app release alongside the relay upgrade.

Dependency, package name and import​

The repository and the package were renamed:

dependencies:
# was:
# mte_relay_client_plugin:
# git:
# url: https://github.com/Eclypses/mte-relay-client-flutter.git
# ref: 4.2.11
mte_relay:
git:
url: https://github.com/Eclypses/relay-client-plugin-flutter.git
ref: v5.3.0
// was: package:mte_relay_client_plugin/mte_relay_client_plugin.dart
// and package:mte_relay_client_plugin/mte_relay_response_model.dart
import 'package:mte_relay/mte_relay.dart';

The CocoaPods variant (mte-relay-client-flutter-pod) is discontinued; 5.3.0 uses Swift Package Manager on iOS.

Platform minimums​

v45.3.0
iOS14.016.0
Android minSdk—28
Xcode14.015.0

On iOS, set IPHONEOS_DEPLOYMENT_TARGET to 16.0 in Build Settings on the Runner project, where the Flutter template sets it, and on the Runner target too if it overrides the value.

If your app uses package:http: the whole migration​

5.3.0 adds RelayHttpClient, an http.Client. Swap the construction and point the URL at your relay; your http.Response handling stays as it is, and no setup call is needed:

// was: final client = http.Client(); (or a MteRelayClientPlugin call per request)
final client = RelayHttpClient();

Failures, the relay's own included, arrive as http.ClientException. If this covers your app, the typed-API changes below do not apply to you.

headersToEncrypt is now unencryptedHeaders, and means the opposite​

v4 encrypted only the headers you listed. 5.3.0 encrypts every header and leaves in the clear only those you list. Porting a v4 list unchanged would send exactly the headers you meant to protect in the clear, so in most cases drop the argument.

Content-Type, Content-Length, Host, X-MTE-Relay-Route and X-MTE-Relay-Client are reserved and always encrypted; listing one throws.

The typed API​

MteRelayClient replaces MteRelayClientPlugin as the main class, with typed request and response models in place of Map arguments.

v45.3.0
MteRelayClientPluginMteRelayClient; MteRelayClientPlugin only to write an upload's body
initializeRelay()initialize() — optional; the first request initializes
relayDataTask(Map args)send(RelayRequest) → RelayResponse, or stream(RelayRequest)
Result.fromMap(response)the RelayResponse that send() returns
'url' / 'body' in the args mapserverUrl / body (Uint8List) on RelayRequest, or RelayRequest.text(...)
relayDownloadFile(Map args)startDownload(RelayFileDownloadRequest)
'downloadLocation'destinationPath — required; the app chooses it
relayUploadFile(Map args)startUpload(RelayFileUploadRequest), body written through MteRelayClientPlugin (sendChunk/closeStream)
rePair({url, pathnamePrefix})repair(serverUrl, pathnamePrefix: ...)
adjustRelaySettings({url, pairPoolSize})updateSettings(serverUrl, RelayClientSettings(...))
enableFileLogging({'url': ..., 'isEnabled': ...})enableFileLogging(bool)
readLogFile({'url': ...}) / clearLogFile({'url': ...})readLogFile() / clearLogFile()
several callback streamsone events stream of RelayOperationEvent
final relay = MteRelayClient();

final response = await relay.send(RelayRequest.text(
serverUrl: 'https://your-relay-server.com',
route: '/api/login',
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'email': 'user@example.com', 'password': 'P@ssw0rd!'}),
));

await relay.repair('https://your-relay-server.com');

await relay.updateSettings(
'https://your-relay-server.com',
RelayClientSettings(minPairs: 5, basePairs: 8, maxPairs: 15,
keepAliveIntervalSeconds: 300, acquisitionWaitTime: 1.0),
);

The stream chunk size and pair persistence settings are gone.

File transfer notes​

  • Leave unencryptedHeaders empty for uploads: the multipart framing headers travel encrypted, and listing Content-Type or Content-Length throws.
  • The relay's advertised request-body limit now applies to streamed uploads too; an upload over it is refused before anything is sent.
  • A download needs a non-empty, writable destinationPath. The plugin does not pick a directory for you.