Detecting iOS Simulators Reliably in Flutter with is_ios_simulator
Why environment detection matters for biometric, camera, and APNS push notification testing, and how is_ios_simulator simplifies simulator logic.
Published on • October 30, 2026
AI Assistant

When building iOS apps in Flutter, developers frequently need to branch their code depending on whether the app is executing on a physical iPhone or inside the macOS Xcode iOS Simulator.
Features such as Apple Push Notification service (APNS), camera capture, FaceID/TouchID biometrics, and Metal hardware acceleration exhibit subtle differences between physical silicon and x86_64/ARM64 virtualized simulators.
The lightweight package is_ios_simulator provides a clean, zero-overhead way to identify simulator execution.
Why device_info_plus Isn’t Always the Answer
While device_info_plus is the standard plugin for full hardware telemetry, fetching device info requires an asynchronous platform channel call:
// Heavyweight and requires awaiting asynchronous platform channels
final deviceInfo = DeviceInfoPlugin();
final iosInfo = await deviceInfo.iosInfo;
final isSimulator = !iosInfo.isPhysicalDevice;
If your app needs this check synchronously inside a dependency injection container (like GetIt) or during early startup before runApp() executes, asynchronous platform channels can introduce startup latency.
Instant Detection with is_ios_simulator
The is_ios_simulator package leverages compile-time environment flags and ultra-fast POSIX system inspection:
dependencies:
is_ios_simulator: ^1.0.0
Practical Implementation
import 'package:flutter/material.dart';
import 'package:is_ios_simulator/is_ios_simulator.dart';
void configureServices() {
if (isIosSimulator) {
// Provide mocked biometric authentication
setupMockBiometrics();
print('Running on iOS Simulator: Mocking hardware peripherals');
} else {
// Configure production APNS and hardware camera
setupProductionHardware();
}
}
class BiometricPrompt extends StatelessWidget {
const BiometricPrompt({super.key});
@override
Widget build(BuildContext context) {
if (isIosSimulator) {
return const Banner(
message: 'SIMULATOR',
location: BannerLocation.topStart,
child: Text('Simulated FaceID Passed'),
);
}
return const Text('Scan FaceID on Device');
}
}
Common Use Cases
- Mocking Push Notifications: Xcode simulators historically lacked full background APNS VoIP channels.
- Camera Fallbacks: Automatically substituting file pickers when running on desktop simulator harnesses lacking physical camera sensors.
- In-App Purchase (StoreKit) Sandbox: Directing simulator environments to local StoreKit test configuration files.
Using targeted detection utilities keeps your test suites fast and your code structure tidy.