Flutter setup
Set up a project for building a Viam app that runs across iOS, Android, and desktop platforms from a single codebase: a tablet operator interface, a warehouse kiosk, a phone app for technicians in the field. This page covers the project scaffolding with Flutter, the Viam Flutter SDK install, and the iOS/macOS and Android platform configuration. For the connection patterns your app will actually use, see Connect to a machine.
Prerequisites
- Flutter SDK 3.0.0 or later (install Flutter)
- Platform tooling for at least one of your targets:
- iOS: Xcode and an Apple Developer account (or the iOS Simulator)
- Android: Android Studio with Android SDK 23 or later and Kotlin
1.8.20or later - Linux, macOS, Windows: the desktop tooling for your target (Flutter desktop setup)
- Web: a Chromium-based browser for development (Flutter web setup)
- A configured Viam machine
- The machine’s address, an API key, and an API key ID
Get the credentials from the machine’s CONNECT tab in the Viam app: click CONNECT, select Flutter, and copy the address, API key ID, and API key from the generated code sample.
Create a project
flutter create my_viam_app
cd my_viam_app
flutter create generates a project that targets all six Flutter platforms. To narrow the targets, pass --platforms=ios,android (or any subset) to the command.
Add the Viam SDK
flutter pub add viam_sdk flutter_dotenv
flutter_dotenv loads environment variables from a .env file at runtime, which keeps credentials out of source code.
Configure iOS and macOS (if targeting Apple platforms)
The Viam SDK uses WebRTC and mDNS, both of which require explicit permissions on iOS and macOS.
Add the following to ios/Runner/Info.plist and macos/Runner/Info.plist, inside the top-level <dict>:
<key>NSLocalNetworkUsageDescription</key>
<string>This app needs access to the local network to connect to your Viam machine.</string>
<key>NSBonjourServices</key>
<array>
<string>_rpc._tcp</string>
</array>
Set the minimum iOS deployment target to 13.0 in ios/Podfile:
platform :ios, '13.0'
Configure Android (if targeting Android)
In android/app/build.gradle, confirm that the minimum SDK version is 23 or higher:
defaultConfig {
minSdkVersion 23
// ...
}
If your Kotlin version is lower than 1.8.20, bump it in android/build.gradle:
ext.kotlin_version = '1.8.20'
Configure environment variables
Create a .env file in your project root:
MACHINE_ADDRESS=my-robot-main.xxxx.viam.cloud
API_KEY_ID=your-api-key-id
API_KEY=your-api-key-secret
Replace the three values with what you copied from the CONNECT tab.
Add .env to your .gitignore:
echo ".env" >> .gitignore
Register .env as an asset in pubspec.yaml so Flutter bundles it with the app:
flutter:
assets:
- .env
Verify the connection
Replace the contents of lib/main.dart with:
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:viam_sdk/viam_sdk.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await dotenv.load();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(body: Center(child: StatusText())),
);
}
}
class StatusText extends StatefulWidget {
const StatusText({super.key});
@override
State<StatusText> createState() => _StatusTextState();
}
class _StatusTextState extends State<StatusText> {
String _status = 'Connecting...';
@override
void initState() {
super.initState();
_connect();
}
Future<void> _connect() async {
try {
final address = dotenv.env['MACHINE_ADDRESS']!;
final apiKeyId = dotenv.env['API_KEY_ID']!;
final apiKey = dotenv.env['API_KEY']!;
final robot = await RobotClient.atAddress(
address,
RobotClientOptions.withApiKey(apiKeyId, apiKey),
);
setState(() {
_status = 'Connected. Found ${robot.resourceNames.length} resources.';
});
} catch (e) {
setState(() {
_status = 'Connection failed: $e';
});
}
}
@override
Widget build(BuildContext context) {
return Text(_status);
}
}
Run the app
Run the app on a connected device or simulator:
flutter run
If multiple targets are available, Flutter prompts you to choose. Select your device. The app builds, launches, and shows:
Connected. Found N resources.
where N is the number of components and services on your machine.
If you see Connection failed:, the most common causes are:
- iOS or macOS permissions not granted. The app prompts the user for local network access on first run; declining blocks WebRTC. Verify the
Info.plistentries are present on bothios/Runner/Info.plistandmacos/Runner/Info.plistif you target macOS. - Android minimum SDK too low. The Viam Flutter SDK requires Android SDK 23 or later. Raise
minSdkVersioninandroid/app/build.gradle. .envnot bundled. Confirm.envis listed underflutter.assetsinpubspec.yamland that the file exists at the project root.- Credentials wrong. Compare the three values in
.envto the CONNECT tab output.
Next
- Connect to a machine for the connection patterns your app will actually use, including the
Viamclass for multi-machine access - Handle disconnection and reconnection for reconnection and UI indicators
- The Flutter SDK reference for per-component API details and widget documentation
Was this page helpful?
Glad to hear it! If you have any other feedback please let us know:
We're sorry about that. To help us improve, please tell us what we can do better:
Thank you!