Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ios zoomBy crash: Foundation/NSNumber.swift:467: Fatal error: Unable to bridge NSNumber to Float #873

Closed
4 tasks done
robert-virkus opened this issue Jun 5, 2021 · 4 comments
Labels
bug Something isn't working

Comments

@robert-virkus
Copy link

Environment

Technology Version
Flutter version Flutter 2.2.1 • channel stable
Plugin version flutter_inappwebview: ^5.3.2
Android version n/a
iOS version 14.5 and 14.6
Xcode version Version 12.5 (12E262)

Device information:
Apple/iPhone Xs (real device)
iPhone 11 Pro, 12 Pro (Simulator)

Description

When calling InAppWebViewController.zoomBy(zoomFactor: 0.64) within the onLoadStop callback, the app crashes with Foundation/NSNumber.swift:467: Fatal error: Unable to bridge NSNumber to Float.
These are my initialOptions:

ios: IOSInAppWebViewOptions(
          allowsBackForwardNavigationGestures: false,
          minimumZoomScale: 0.2,
          maximumZoomScale: 10.0,
       ),

Expected behavior:

  • the web view zooms out

Current behavior:

  • The app crashes

Steps to reproduce

  1. have HTML that is wider than the view port
  2. measure the document width in onLoadStop
  3. call the controller.zoomBy() method to zoom out, ie have a factor less than 1.0
  4. observe crash

Here's the full InAppWebView code:

InAppWebView(
      key: ValueKey(_htmlData),
      initialData: InAppWebViewInitialData(data: _htmlData!),
      initialOptions: InAppWebViewGroupOptions(
        crossPlatform: InAppWebViewOptions(
          useShouldOverrideUrlLoading: true,
          verticalScrollBarEnabled: false,
          transparentBackground: isDark,
        ),
        android: AndroidInAppWebViewOptions(
          useWideViewPort: false,
          loadWithOverviewMode: true,
          useHybridComposition: true,
          forceDark: isDark
              ? AndroidForceDark.FORCE_DARK_ON
              : AndroidForceDark.FORCE_DARK_OFF,
        ),
        ios: IOSInAppWebViewOptions(
          allowsBackForwardNavigationGestures: false,
          minimumZoomScale: 0.2,
          maximumZoomScale: 10.0,
        ),
      ),
      onWebViewCreated: widget.onWebViewCreated,
      onLoadStop: (controller, url) async {
        if (widget.adjustHeight) {
          var scrollHeight = await controller.evaluateJavascript(
              source: 'document.body.scrollHeight');
          // print('scrollHeight: $scrollHeight');
          if (scrollHeight != null) {
            final size = MediaQuery.of(context).size;
            // final scrollWidth = size.width;
            final scrollWidth = await controller.evaluateJavascript(
                source: 'document.body.scrollWidth');
            // print('scrollWidth: $scrollWidth');
            // print('size: ${size.height}x${size.width}');
            if (_isHtmlMessage && scrollWidth > size.width) {
              var scale = (size.width / scrollWidth);
              if (scale < 0.2) {
                scale = 0.2;
              } else {
                scale = (scale * 100.0).floorToDouble() / 100.0;
              }
              print('zoomBy with scale=$scale');
              await controller.zoomBy(zoomFactor: scale, iosAnimated: true);
              scrollHeight = (scrollHeight * scale).ceil();
              final callback = widget.onZoomed;
              if (callback != null) {
                callback(controller, scale);
              }
            }
            setState(() {
              _webViewHeight = (scrollHeight + 10.0);
              // print('webViewHeight set to $_webViewHeight');
            });
          }
        }
      },
      shouldOverrideUrlLoading: shouldOverrideUrlLoading,
      androidOnPermissionRequest: (controller, origin, resources) {
        // print('androidOnPermissionRequest for $resources');
        return Future.value(
          PermissionRequestResponse(
              resources: resources,
              action: PermissionRequestResponseAction.GRANT),
        );
      },
      gestureRecognizers: widget.adjustHeight
          ? {
              Factory<LongPressGestureRecognizer>(
                  () => LongPressGestureRecognizer()),
              // The scale gesture recognizer interferes with scrolling on Flutter 2.2
              // Factory<ScaleGestureRecognizer>(() => ScaleGestureRecognizer()),
            }
          : null,
    )

Note that in the above code (scale = (scale * 100.0).floorToDouble() / 100.0;) I tried to limit the value's complexity in a vain attempt to be a float number. Did not make a difference, though

Stacktrace/Logcat

flutter: zoomBy with scale=0.64
Foundation/NSNumber.swift:467: Fatal error: Unable to bridge NSNumber to Float

Thanks for this great project again, keep up the good work!

@robert-virkus robert-virkus added the bug Something isn't working label Jun 5, 2021
@github-actions
Copy link

github-actions bot commented Jun 5, 2021

👋 @robert-virkus

NOTE: This comment is auto-generated.

Are you sure you have already searched for the same problem?

Some people open new issues but they didn't search for something similar or for the same issue. Please, search for it using the GitHub issue search box or on the official inappwebview.dev website, or, also, using Google, StackOverflow, etc. before posting a new one. You may already find an answer to your problem!

If this is really a new issue, then thank you for raising it. I will investigate it and get back to you as soon as possible. Please, make sure you have given me as much context as possible! Also, if you didn't already, post a code example that can replicate this issue.

In the meantime, you can already search for some possible solutions online! Because this plugin uses native WebView, you can search online for the same issue adding android WebView [MY ERROR HERE] or ios WKWebView [MY ERROR HERE] keywords.

Following these steps can save you, me, and other people a lot of time, thanks!

@robert-virkus
Copy link
Author

I digged a bit deeper and found that the problem is in line 292 of InAppWebViewMethodHandler.swift:

                let zoomFactor = arguments!["zoomFactor"] as! Float

The whole code chunk is this:

            case "zoomBy":
                let zoomFactor = arguments!["zoomFactor"] as! Float
                let animated = arguments!["iosAnimated"] as! Bool
                webView?.zoomBy(zoomFactor: zoomFactor, animated: animated)
                result(true)
                break

@Manuito83
Copy link
Contributor

Should be fixed with the PR above

Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 11, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants