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

[Bug]: sharePositionOrigin crash although a valid Rect is being used #3338

Closed
8 tasks done
kaciula opened this issue Oct 29, 2024 · 6 comments
Closed
8 tasks done

[Bug]: sharePositionOrigin crash although a valid Rect is being used #3338

kaciula opened this issue Oct 29, 2024 · 6 comments
Labels
bug Something isn't working triage

Comments

@kaciula
Copy link

kaciula commented Oct 29, 2024

Platform

iPadOS 17.6.1, macOS 18

Plugin

share_plus

Version

10.1.0

Flutter SDK

3.24.2

Steps to reproduce

I'm getting crash reports but I cannot reproduce it on my own. It works correctly on the iPad simulators. The sharePositionOrigin Rect that I am sending is within bounds (as you can see in the error messages) but the error happens nonetheless.

Here are some examples of errors:

MethodChannelShare.shareXFiles:

PlatformException(error, sharePositionOrigin: argument must be set, {{222, 739}, {300, 92}} must be non-zero and within coordinate space of source view: {{0, 0}, {1133, 744}}, null, null)

MethodChannelShare.shareFilesWithResult:

PlatformException(error, sharePositionOrigin: argument must be set, {{362, 701}, {300, 92}} must be non-zero and within coordinate space of source view: {{0, 0}, {1024, 768}}, null, null)

Code Sample

// This is how I am computing the sharePositionOrigin Rect

final RenderBox? box = context.findRenderObject() as RenderBox?;
final Rect sharePositionOrigin = box!.localToGlobal(Offset.zero) & box.size;

Logs

--

Flutter Doctor

[✓] Flutter (Channel stable, 3.24.2, on macOS 14.2.1 23C71 darwin-arm64, locale en-RO)
    • Flutter version 3.24.2 on channel stable at /Users/ka/dev/tools/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 4cf269e36d (8 weeks ago), 2024-09-03 14:30:00 -0700
    • Engine revision a6bd3f1de1
    • Dart version 3.5.2
    • DevTools version 2.37.2

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

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

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

[✓] Android Studio (version 2024.1)
    • 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.10+0-17.0.10b1087.21-11609105)

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

Checklist before submitting a bug

  • I searched issues in this repository and couldn't find such bug/problem
  • I Google'd a solution and I couldn't find it
  • I searched on StackOverflow for a solution and I couldn't find it
  • I read the README.md file of the plugin
  • I'm using the latest version of the plugin
  • All dependencies are up to date with flutter pub upgrade
  • I did a flutter clean
  • I tried running the example project
@kaciula kaciula added bug Something isn't working triage labels Oct 29, 2024
@miquelbeltran
Copy link
Member

miquelbeltran commented Oct 29, 2024

Rect that I am sending is within bounds (as you can see in the error messages)

Not really, 701 + 92 > 768 so it is out of bounds according to the logs. CGRectContainsRect will return false and so throw the exception.

If the controller.view.frame coordinates are correct or not, it's another question.

See:

activityViewController.popoverPresentationController.sourceView =
controller.view;
BOOL isCoordinateSpaceOfSourceView =
CGRectContainsRect(controller.view.frame, origin);
// If device is e.g. an iPad then hasPopoverPresentationController is true
BOOL hasPopoverPresentationController =
[activityViewController popoverPresentationController] != NULL;
if (hasPopoverPresentationController &&
(!isCoordinateSpaceOfSourceView || CGRectIsEmpty(origin))) {
NSString *sharePositionIssue = [NSString
stringWithFormat:
@"sharePositionOrigin: argument must be set, %@ must be non-zero "
@"and within coordinate space of source view: %@",
NSStringFromCGRect(origin),
NSStringFromCGRect(controller.view.bounds)];
result([FlutterError errorWithCode:@"error"
message:sharePositionIssue
details:nil]);
return;
}

@kaciula
Copy link
Author

kaciula commented Oct 29, 2024

@miquelbeltran I was assuming the coordinates from the error log were the corners of the Rect.

Any suggestion for a better way to get a valid sharePositionOrigin? I'd prefer not to give a static Rect in the middle of the screen but a Rect close to the widget that was clicked.

@miquelbeltran
Copy link
Member

I'd prefer not to give a static Rect in the middle of the screen but a Rect close to the widget that was clicked.

I think wrapping the target widget with a builder and obtaining the coordinates from the inmediate render object, just like the example project.

@kaciula
Copy link
Author

kaciula commented Oct 29, 2024

I think wrapping the target widget with a builder and obtaining the coordinates from the inmediate render object, just like the example project.

This is what I am currently doing (wrapping with a Builder) but I get the crash reports so it seems this approach does not work in all cases.

@miquelbeltran
Copy link
Member

miquelbeltran commented Oct 29, 2024

1024 x 768 (which was is reported as the controller.view in the iOS obj-c code) look like iPad mini & 2nd Gen iPads. Can you try your app on a simulator for those smaller devices?

edit: Do you have the device model from the error report? Also iPads can split-screen if I remember correctly. I'd try playing with that see if a specific resolution breaks the share functionality.

@kaciula
Copy link
Author

kaciula commented Nov 28, 2024

@miquelbeltran I have managed to reproduce this by placing the share button in a scroll view at the edge of the screen.

I've updated the code that computes the sharePositionOrigin to fall back to a rectangle in the middle of the screen if the computed rectangle does not fit the available screen.

Rect sharePositionOrigin(BuildContext context) {
  final RenderBox? box = context.findRenderObject() as RenderBox?;
  final Rect candidatePositionOrigin =
      (box!.localToGlobal(Offset.zero) & box.size);
  final double width = MediaQuery.sizeOf(context).width;
  final double height = MediaQuery.sizeOf(context).height;
  if (candidatePositionOrigin.left >= 0 &&
      candidatePositionOrigin.right < width &&
      candidatePositionOrigin.top >= 0 &&
      candidatePositionOrigin.bottom < height) {
    return candidatePositionOrigin;
  } else {
    return Rect.fromCenter(
      center: Offset(width / 2, height / 2),
      width: 100,
      height: 100,
    );
  }
}

@kaciula kaciula closed this as completed Nov 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triage
Projects
None yet
Development

No branches or pull requests

2 participants