---
title: "Flutter-SDK – Relyo"
description: "Relyo in eine Flutter-App einbauen: Abhängigkeit, Relyo.init, RelyoScope, Support-Eintrag, Maskierung, Router und Grenzen."
lang: de
canonical: https://relyo.de/docs/flutter
---

# Flutter-Apps

So baust du Co-Browsing für den Support in eine Flutter-App ein. Das Flutter-SDK `relyo_flutter` läuft auf iOS (ab 15), Android (ab 8) und Flutter Web mit demselben Code. Es überträgt die Flutter-Oberfläche als Bildfolge: Nur geänderte Bildbereiche werden geschickt, bis zu 10 Bilder pro Sekunde. Eine Berechtigung des Betriebssystems braucht es dafür nicht.

## Mit einem Coding-Agent einbauen

Kopiere diesen Prompt in deinen Coding-Agent (Claude Code, Cursor, Copilot …) und ergänze den Projekt-Key, falls du einen hast:

```text
Baue Relyo-Co-Browsing-Support in diese Flutter-App ein (iOS und Android).
Lies zuerst die Anleitung https://relyo.de/.well-known/agent-skills/relyo-integrate/SKILL.md
und die Flutter-Doku https://relyo.de/docs/flutter.md, dann:

1. relyo_flutter als Git-Abhängigkeit in pubspec.yaml eintragen (Abschnitt „Abhängigkeit“), mit festem Commit.
2. iOS-Deployment-Target auf mindestens 15.0 setzen (Podfile und Xcode-Projekt), Android: INTERNET-Berechtigung prüfen.
3. Relyo.init in main() vor runApp aufrufen: relayUrl 'wss://relyo.de', connect: RelyoConnect.lazy,
   appVersion aus der pubspec, projectKey: 'PROJEKT_KEY' (weglassen, wenn keiner vorhanden ist).
4. RelyoScope außen um MaterialApp bzw. CupertinoApp legen, genau einmal.
5. In den Einstellungen am Ende einen Eintrag „Support“ ergänzen, der Relyo.instance.showCode(context) aufruft.
6. Sensible Ansichten (Konto-, Gesundheits-, persönliche Daten) mit RelyoRedact maskieren; Passwortfelder sind automatisch maskiert.
7. Bei go_router oder einem anderen Router die Navigation wie im Abschnitt „Navigation“ anbinden.
8. flutter analyze und die Tests ausführen und zusammenfassen, was geändert wurde.
Starte selbst keine Support-Session und gib keine Support-Codes ein.
```

Danach in der App auf „Support“ tippen und den Code auf [relyo.de](/) eingeben.

## Abhängigkeit

Das Paket liegt nicht auf pub.dev, sondern im Relyo-Repository:

```yaml
# pubspec.yaml
dependencies:
  relyo_flutter:
    git:
      url: https://github.com/justcode049/Relyo.git
      path: packages/flutter-sdk
      ref: main # besser: einen festen Commit eintragen
```



> Das Repository ist noch nicht öffentlich. Bis dahin bekommst du den Zugang per E-Mail an [mail@jochen-maurer.com](mailto:mail@jochen-maurer.com?subject=Relyo%20Flutter-SDK).


Voraussetzung ist Flutter 3.38 oder neuer.

- **iOS:** Deployment-Target 15.0 (`platform :ios, '15.0'` im `Podfile`).
- **Android:** `android.permission.INTERNET` im Manifest; für einen lokalen Server per `ws://` während der Entwicklung zusätzlich `android:usesCleartextTraffic="true"`.

## Einrichten

```dart
import 'package:relyo_flutter/relyo_flutter.dart';

void main() {
  Relyo.init(
    relayUrl: 'wss://relyo.de',
    projectKey: 'pk_deineapp', // entfällt im offenen Dienst
    connect: RelyoConnect.lazy,
    appVersion: '1.4.0',
  );
  runApp(RelyoScope(child: const MyApp()));
}
```

`RelyoScope` gehört **außen um** `MaterialApp` bzw. `CupertinoApp` und darf nur einmal vorkommen. Die Dialoge des SDK und die Statusleiste liegen in einem eigenen Overlay außerhalb des übertragenen Bereichs und erscheinen deshalb nie im Bild beim Supporter.

## Support-Eintrag

Am besten in den Einstellungen, unauffällig am Ende der Liste:

```dart
TextButton(
  onPressed: () => Relyo.instance.showCode(context),
  child: const Text('Support'),
)
```

`showCode` zeigt den Code-Dialog, danach führt das SDK durch Freigabe, Session und Ende. Während der Session vergrößert es den oberen Rand der App um die Höhe der Statusleiste (36 Pixel), damit die Leiste keine Bedienelemente verdeckt.

## Optionen

| Parameter     | Standard            | Bedeutung                                                                                                                 |
| ------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `relayUrl`    | –                   | Pflicht. Adresse des Servers, zum Beispiel `wss://relyo.de`.                                                              |
| `projectKey`  | –                   | Projekt-Key der App. Ohne Key ordnet ein Server mit offenem Dienst die App ihrer App-ID zu (Bundle-ID bzw. Package-Name). |
| `user`        | –                   | Angemeldeter Nutzer, `RelyoUser(id: …, name: …)`. Nur zur Anzeige, nicht geprüft.                                         |
| `connect`     | `RelyoConnect.auto` | `auto`: mit `user` sofort verbinden, sonst erst bei `showCode`; `eager`: immer sofort; `lazy`: nur bei `showCode`.        |
| `appVersion`  | `''`                | Version der App; erscheint in der Konsole.                                                                                |
| `fps`         | `5`                 | Ziel-Bildrate, 2 bis 10. Bei knapper Bandbreite regelt das SDK selbst herunter.                                           |
| `consentText` | –                   | Eigener Erklärtext im Freigabe-Dialog; `{agent}` wird durch den Namen des Supporters ersetzt.                             |

Weitere Aufrufe:

```dart
Relyo.instance.identify(const RelyoUser(id: 'u_123', name: 'Max M.')); // nach dem Login
Relyo.instance.identify(null); // beim Logout
Relyo.instance.end(); // Session beenden, sonst „Beenden“ in der Statusleiste
```

Vor der ersten Verbindung legt das SDK nichts auf dem Gerät ab, auch keine Kennung.

## Maskierung

Maskiert wird auf dem Gerät, bevor ein Bild es verlässt:

- **Immer:** jedes Feld mit `obscureText: true`.
- **`RelyoRedact`:** alles innerhalb dieses Widgets.

```dart
RelyoRedact(
  child: TextField(decoration: InputDecoration(labelText: 'IBAN')),
)
```

Maskierte Bereiche werden schwarz übermalt, bevor das Bild kodiert wird. Kann das SDK den Bildschirm einmal nicht vollständig prüfen, schwärzt es das ganze Bild. Ferngesteuerte Eingaben in maskierte Felder lehnt das SDK ab.

## Navigation

Damit der Supporter sieht, wo der Nutzer gerade ist, und Zeichnungen beim Seitenwechsel verschwinden:

```dart
MaterialApp(
  navigatorObservers: [RelyoNavigatorObserver()],
  // …
)
```

Mit **GoRouter** zusätzlich für Wechsel, die keinen Navigator-Push auslösen (`go()`, `ShellRoute`):

```dart
final router = GoRouter(observers: [RelyoNavigatorObserver()], routes: [/* … */]);

router.routerDelegate.addListener(() {
  Relyo.instance.reportRoute(router.routerDelegate.currentConfiguration.uri.path);
});
```

## Steuerung

Nach der zweiten Freigabe kann der Supporter tippen, wischen und scrollen, Text in das gerade fokussierte Feld schreiben sowie Enter und Rücktaste senden. Jede eigene Berührung des Nutzers oder eine Hardware-Taste beendet die Steuerung sofort.

## Grenzen

- Platform-Views (WebView, Karten, Kamera) erscheinen als graue Fläche mit „Eingebettete Ansicht“.
- System-Dialoge (Berechtigungen, Teilen) und die Bildschirmtastatur sind nicht im Bild.
- Ferngesteuerter Text nur in Flutter-Textfeldern (`TextField`, `CupertinoTextField` und alles auf Basis von `EditableText`).
- Geht die App in den Hintergrund, pausiert die Übertragung und läuft beim Zurückkehren weiter.
- Die Dialoge sind bisher nur auf Deutsch.

## Testen

Für eigene Widget-Tests ohne Server gibt es `package:relyo_flutter/testing.dart` mit einem Test-Server im Speicher (`RelyoTesting.install`, `FakeRelyoServer`).
