nmfisher / thermion

3D rendering toolkit for Dart and/or Flutter
https://thermion.dev
Apache License 2.0
128 stars 10 forks source link

iOS app throws "No asset with id 'flutter_filament_plugin' found" when running in release or profile mode #21

Closed Hannnes1 closed 5 months ago

Hannnes1 commented 8 months ago

Hi! I got the following issue when I tried to run the app in profile mode on iOS. The same issue also appears in release mode. Development mode works as it should

flutter: The Dart VM service is listening on http://0.0.0.0:52034/BXTLKvOORVg=/
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Exception: No viewer available, ignoring
#0      FilamentControllerFFI.setRendering (package:flutter_filament/filament_controller_ffi.dart:123)
#1      _SizedFilamentWidgetState._handleStateChange (package:flutter_filament/widgets/filament_widget.dart:238)
#2      AppLifecycleListener.didChangeAppLifecycleState (package:flutter/src/widgets/app_lifecycle_listener.dart:259)
#3      WidgetsBinding.handleAppLifecycleStateChanged (package:flutter/src/widgets/binding.dart:799)
#4      List.forEach (dart:core-patch/growable_array.dart:416)
#5      ServicesBinding._handleLifecycleMessage (package:flutter/src/services/binding.dart:284)
#6      BasicMessageChannel.setMessageHandler.<anonymous closure> (package:flutter/src/services/platform_channel.dart:235)
#7      _DefaultBinaryMessenger.setMessageHandler.<anonymous closure> (package:flutter/src/services/binding.dart:603)
#8      _invoke2 (dart:ui/hooks.dart:344)
#9      _ChannelCallbackRecord.invoke (dart:ui/channel_buffers.dart:45)
#10     _Channel.push (dart:ui/channel_buffers.dart:135)
#11     ChannelBuffers.push (dart:ui/channel_buffers.dart:343)
#12     PlatformDispatcher._dispatchPlatformMessage (dart:ui/platform_dispatcher.dart:737)
#13     _dispatchPlatformMessage (dart:ui/hooks.dart:257)
flutter: Waiting for widget dimensions to become available..
flutter: Got widget dimensions : Rect.fromLTRB(0.0, 300.0, 1125.0, 2436.0)
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument(s): Couldn't resolve native function 'create_filament_viewer_ffi' in 'flutter_filament_plugin' : No asset with id 'flutter_filament_plugin' found. Available native assets: . Attempted to fallback to process lookup. dlsym(RTLD_DEFAULT, create_filament_viewer_ffi): symbol not found.

#0      Native._ffi_resolver.#ffiClosure0 (dart:ffi-patch/ffi_patch.dart)
#1      Native._ffi_resolver_function (dart:ffi-patch/ffi_patch.dart:1386)
#2      create_filament_viewer_ffi (package:flutter_filament/generated_bindings.dart)
#3      FilamentControllerFFI.createViewer (package:flutter_filament/filament_controller_ffi.dart:240)
<asynchronous suspension>
#4      _TestPageState.initState.<anonymous closure> (package:filament_playground/main.dart:38)
<asynchronous suspension>

I noticed the issue on the develop branch (newly cloned + git lfs pull). Below is a minimal reproducible sample. The error seems to be caused by await _filamentController.createViewer();, and the viewer never loads (the widget stays red).

import 'package:flutter/material.dart';
import 'package:flutter_filament/filament_controller.dart';
import 'package:flutter_filament/filament_controller_ffi.dart';
import 'package:flutter_filament/widgets/filament_widget.dart';

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

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: TestPage(),
    );
  }
}

class TestPage extends StatefulWidget {
  const TestPage({super.key});

  @override
  State<TestPage> createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  final FilamentController _filamentController = FilamentControllerFFI();

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

    Future(() async {
      await Future.delayed(const Duration(milliseconds: 100));

      await _filamentController.createViewer();

      await _filamentController.setRendering(true);

      final modelId = await _filamentController.loadGlb('assets/1.glb');

      await _filamentController.setPosition(modelId, 0, 0, -2);

      await _filamentController.loadIbl(
        'assets/default_env_ibl.ktx',
        intensity: 20000,
      );
    });
  }

  @override
  void dispose() {
    super.dispose();

    _filamentController.destroy();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Stack(
        children: [
          const Positioned.fill(
            child: ColoredBox(
              color: Colors.blueGrey,
            ),
          ),
          FilamentWidget(
            controller: _filamentController,
          ),
        ],
      ),
    );
  }
}
nmfisher commented 8 months ago

This is due to Xcode stripping symbols and moving to @Ffi annotations (rather than DynamicLibrary).

I can't fix it properly until I switch to native_assets to build everything (which is planned).

However, temporary workaround is to set "Enable Testability" in your Xcode Runner target to "True".

I think I added a note on the feature/instancing branch but haven't merged in yet.

Hannnes1 commented 8 months ago

Okay, thanks! "Enable Testability" works.

nmfisher commented 8 months ago

Great! Let's leave this issue open so I can come back after moving to native_assets for building and check that the problem is indeed solved.

Hannnes1 commented 5 months ago

Confirmed working now