omchiii / model_viewer_plus.dart

A Flutter widget for rendering interactive 3D models in the glTF and GLB formats.
https://pub.dev/packages/model_viewer_plus
Apache License 2.0
89 stars 51 forks source link

Issue with iOS 16 #50

Open pd-mis opened 1 year ago

pd-mis commented 1 year ago

Describe the bug Same code used to work fine on iOS up to 15. However, users who recently updated their iOS to 16 reported that they no longer see the AR icon in the model anymore. So the modal still shows fine, but the AR button at the bottom of the view disappeared. We verified this by running same code on iPhone/iPad versions 13,14,15 with no problem, however, when we test with iOS 16, the icon disappears.

To reproduce Steps to reproduce the behavior:

  1. Run your code example on any iOS 16 machine
  2. The viewer should open fine and you should be able to see the model fine
  3. The AR icon that is supposed to appear in the view no longer shows up. Hence you cannot view the model in AR using your camera.

Expected behavior Model viewer should show the AR button

Screenshots

Smartphone (please complete the following information):

Panyeczky commented 1 year ago

I have the same issue and I'm interested in any follow up information.

pd-mis commented 1 year ago

@Panyeczky I am still waiting for a response from the authors of this plugin. It still does not work on iOS 16+

Foldblade commented 1 year ago

Sorry for a late reply. I'm not an iOS developer, so I want to add a "help wanted" label for this issue.

After some searching, here are some information I can provide:

Because this package uses webview_flutter to display a web page (you can see here), on iOS webview_flutter uses WKWebView.

According to an issue's comment on WebKit Bugzilla :

AR Quick Look is not supported directly in WKWebView clients (this is a bug we want to fix). Some browsers might implement their own code to intercept the navigation and display their own "Quick Look" view, but there is no API for those clients to tell the WKWebView they are doing it.

According to a comment under USDZ AR QuickLook support in WKWebView inconsistencies:

AR Quick Look isn't yet supported in WKWebView

This PR of model-viewer gave us an test website. I use webview_flutter to open it, it turns out that the WKWebView used by webview_flutter does not support "Quick Look" view -- that's why the AR button disappear.

Simulator Screen Shot - iPhone 14 Pro Max - 2022-12-12 at 20 47 43

Currently I have no idea about how to solve the issue😢

References:

pd-mis commented 1 year ago

@Foldblade thanks for update. This should help plugin developers tackle the issue. I still cannot understand how this works just fine on iOS <16

Foldblade commented 1 year ago

Before iOS 16, due to the bug of WKWebView, <model-viewer> thinks WKWebView supports AR, so the AR button will be displayed.

After iOS 16 and some updates of <model-viewer>, currently <model-viewer> thinks WKWebView does not support AR.

There was one issue related with AR on iOS 15: #8, you may take a look and know how I solved it in commit 7974cd. I used url_launcher to open the usdz file in SFSafariViewController, so user can view the model in AR Quick Look. But now since the AR button shows no more, this solution is also ineffective.😥

omchiii commented 1 year ago
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart'
    show ByteData, NetworkAssetBundle, rootBundle;
import 'package:path_provider/path_provider.dart';
import 'package:quick_look/quick_look.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
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('QuickLook for iOS'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              TextButton(
                  onPressed: () async {
                    const path = 'Astronaut.usdz';
                    final ByteData byteData = await NetworkAssetBundle(Uri.parse(
                            "https://developer.apple.com/augmented-reality/quick-look/models/nike-air-force/sneaker_airforce.usdz"))
                        .load("");
                    final String directory =
                        (await getApplicationDocumentsDirectory()).path;
                    final tempFile = await File('$directory/$path')
                        .writeAsBytes(byteData.buffer.asUint8List(
                            byteData.offsetInBytes, byteData.lengthInBytes));
                    await QuickLook.openURL(tempFile.path);
                  },
                  child: const Text('Open single demo usdz',
                      style: TextStyle(fontSize: 36),
                      textAlign: TextAlign.center)),
            ],
          ),
        ),
      ),
    );
  }
}

This is the answer using 'quick_look' package you can use local or .usdz from web. You can add buttons beneath model viewer model by checking Platform.isIOS .

Abdelaty commented 12 months ago

any updates here?

omar-alshyokh commented 11 months ago

any updates?

Ahmadre commented 4 months ago
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart'
    show ByteData, NetworkAssetBundle, rootBundle;
import 'package:path_provider/path_provider.dart';
import 'package:quick_look/quick_look.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
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('QuickLook for iOS'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              TextButton(
                  onPressed: () async {
                    const path = 'Astronaut.usdz';
                    final ByteData byteData = await NetworkAssetBundle(Uri.parse(
                            "https://developer.apple.com/augmented-reality/quick-look/models/nike-air-force/sneaker_airforce.usdz"))
                        .load("");
                    final String directory =
                        (await getApplicationDocumentsDirectory()).path;
                    final tempFile = await File('$directory/$path')
                        .writeAsBytes(byteData.buffer.asUint8List(
                            byteData.offsetInBytes, byteData.lengthInBytes));
                    await QuickLook.openURL(tempFile.path);
                  },
                  child: const Text('Open single demo usdz',
                      style: TextStyle(fontSize: 36),
                      textAlign: TextAlign.center)),
            ],
          ),
        ),
      ),
    );
  }
}

This is the answer using 'quick_look' package you can use local or .usdz from web. You can add buttons beneath model viewer model by checking Platform.isIOS .

This solution works, but you have to convert usdz files correctly, otherwise your output 3d object will be rubbish.

jesulo commented 2 months ago

still not working in ios 17+