Skip to content

[camera] regression: startImageStream throws MissingPluginException on iOS #147702

Closed
flutter/packages
#8733
@PerLycke

Description

@PerLycke

Steps to reproduce

  1. Create a new Flutter App
  2. Install camera package camera 0.10.5+9
  3. Add the following in your Info.plist:
	<key>NSCameraUsageDescription</key>
	<string>your usage description here</string>
	<key>NSMicrophoneUsageDescription</key>
	<string>your usage description here</string>
  1. Use the code below as your main.dart
  2. 'flutter run --release' using macos terminal with example code on an iPhone with iOS 17.4.1

Expected results

You should, on every run, see "STREAM" printed in console, and not get a MissingPluginException.

Actual results

Occasionally there is a MissingPluginException(No implementation found for method listen on channel plugins.flutter.io/camera_avfoundation/imageStream) thrown. We had this issue on earlier camera_avfoundation versions: #109910

It was fixed back then, but issue is back. The example code I provide is just a slightly modified version seen in the linked issue.

The issue doesn't happen all the time. However I did upload a build to TestFlight and the issue was persistent on that occasion. I, as much as you, hate bugs you cannot reproduce 100% of the time, but this is a serious issue and it can find its way into all apps using image stream on iOS, which I guess a lot of apps use these days.

This is the exact error I see, when it actually occurs, when running the example code:

flutter run --release
Running Xcode build...
└─Compiling, linking and signing... 1,312ms
Xcode build done. 21.5s
Installing and launching... 3.4s

Flutter run key commands.
h List all available interactive commands.
c Clear the screen
q Quit (terminate the application on the device).
[ERROR:flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm(42)] Using the Impeller rendering backend.
flutter: MissingPluginException(No implementation found for method listen on channel plugins.flutter.io/camera_avfoundation/imageStream)
flutter: #0 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:332)
flutter:
flutter: #1 EventChannel.receiveBroadcastStream. (package:flutter/src/services/platform_channel.dart:676)
flutter:

Code sample

Code sample
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:wakelock_plus/wakelock_plus.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Cam issue',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  late CameraController controller;
  List<CameraDescription>? cameras;

  @override
  void initState() {
    loadCameras();
    super.initState();
  }

  loadCameras() async {
    try {
      cameras = await availableCameras();
      setState(() {});
    } on CameraException catch (e) {
      print('Error: ${e.code}\nError Message: ${e.description}');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Cam issue"),
      ),
      body: body(),
    );
  }

  body() {
    if (cameras?.isNotEmpty ?? false) {
      return Center(
        child: MyCameraPreview(cameras: cameras!),
      );
    }
    return const Center(
      child: Text("Loading"),
    );
  }
}

class MyCameraPreview extends StatefulWidget {
  final List<CameraDescription> cameras;

  const MyCameraPreview({
    Key? key,
    required this.cameras,
  }) : super(key: key);

  @override
  State<MyCameraPreview> createState() => _MyCameraPreviewState();
}

class _MyCameraPreviewState extends State<MyCameraPreview> {
  late CameraController controller;
  bool isDetecting = false;

  @override
  void initState() {
    initController();
    super.initState();
  }

  @override
  void dispose() {
    WakelockPlus.disable();
    super.dispose();
  }

  Future<void> initController() async {
    controller = CameraController(
      widget.cameras[0],
      ResolutionPreset.high,
      enableAudio: false,
    );
    await controller.initialize();
    final maxZoomValue = await controller.getMaxZoomLevel();
    await controller.lockCaptureOrientation();
    if (!mounted) {
      return;
    }

    await controller.startImageStream((CameraImage img) async {
      print("STREAM");
    });

    await WakelockPlus.enable();

    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return CameraPreview(controller);
  }
}

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.19.6, on macOS 14.4.1 23E224 darwin-arm64, locale en-GB)
    • Flutter version 3.19.6 on channel stable at /Users/per/dev/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 54e66469a9 (2 weeks ago), 2024-04-17 13:08:03 -0700
    • Engine revision c4cd48e186
    • Dart version 3.3.4
    • DevTools version 2.31.1

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/per/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15E204a
    • CocoaPods version 1.15.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2023.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874)

[✓] VS Code (version 1.88.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.88.0

[✓] Connected device (3 available)
    • Per’s iPhone (mobile) • xxx-xxx • ios            • iOS 17.4.1 21E236
    • macOS (desktop)       • macos                     • darwin-arm64   • macOS 14.4.1 23E224 darwin-arm64
    • Chrome (web)          • chrome                    • web-javascript • Google Chrome 124.0.6367.118

[✓] Network resources
    • All expected network resources are available.

• No issues found!

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: crashStack traces logged to the consolec: regressionIt was better in the past than it is nowfound in release: 3.19Found to occur in 3.19found in release: 3.22Found to occur in 3.22has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: cameraThe camera pluginpackageflutter/packages repository. See also p: labels.platform-iosiOS applications specificallyr: fixedIssue is closed as already fixed in a newer versionteam-iosOwned by iOS platform teamtriaged-iosTriaged by iOS platform team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions