Skip to content

Commit 0817b9e

Browse files
martinhaintzmar-haibuenaflorkahestlizokm
authored
Add multi-view troubleshooting guide for sentry dart (#11308)
* add multi-view troubleshooting guide for sentry dart * remove unused code * rephrase text and split up in general and example app related part. * add complete example application instead of sentry example app adaptation * Update docs/platforms/flutter/troubleshooting.mdx Co-authored-by: Giancarlo Buenaflor <[email protected]> * Update docs/platforms/flutter/troubleshooting.mdx Co-authored-by: Giancarlo Buenaflor <[email protected]> * Update includes/troubleshooting/flutter/enable_multi_view.mdx Co-authored-by: Karl Heinz Struggl <[email protected]> * Update docs/platforms/flutter/troubleshooting.mdx Co-authored-by: Karl Heinz Struggl <[email protected]> * Update docs/platforms/flutter/troubleshooting.mdx Co-authored-by: Liza Mock <[email protected]> * Update docs/platforms/flutter/troubleshooting.mdx Co-authored-by: Liza Mock <[email protected]> * Update docs/platforms/flutter/troubleshooting.mdx Co-authored-by: Liza Mock <[email protected]> * Update docs/platforms/flutter/troubleshooting.mdx Co-authored-by: Liza Mock <[email protected]> * Update includes/troubleshooting/flutter/enable_multi_view.mdx Co-authored-by: Liza Mock <[email protected]> * update to match the latest PR * revert changes to previous commit. --------- Co-authored-by: Martin Haintz <[email protected]> Co-authored-by: Giancarlo Buenaflor <[email protected]> Co-authored-by: Karl Heinz Struggl <[email protected]> Co-authored-by: Liza Mock <[email protected]>
1 parent 3711dd8 commit 0817b9e

File tree

2 files changed

+240
-0
lines changed

2 files changed

+240
-0
lines changed

docs/platforms/flutter/troubleshooting.mdx

+40
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,43 @@ There is an [issue with the Sentry Flutter SDK](https://github.com/getsentry/sen
6060
This is an [issue](https://github.com/flutter/flutter/issues/135245) with Flutter itself and should be fixed in [Flutter 3.15](https://github.com/flutter/flutter/labels/found%20in%20release%3A%203.15).
6161

6262
For prior versions, you can work around this by configuring the SDK only to take screenshots when the app is in the `resumed` state. To do this, set `SentryFlutterOptions.attachScreenshotOnlyWhenResumed` to `true`.
63+
64+
## Using Flutter Multi-view for Web
65+
66+
Multi-view embedding was introduced in Flutter 3.24. You'll find a detailed guide about it in the [Flutter docs](https://docs.flutter.dev/platform-integration/web/embedding-flutter-web) .
67+
68+
Using Sentry in a multi-view application is possible, but there are some limitations you should be aware of.
69+
The following features don't currently support multi-view:
70+
71+
- Screenshots via the `SentryScreenshotWidget` (which is part of the `SentryWidget`)
72+
- User interaction integration via the `SentryUserInteractionWidget` (which is part of the `SentryWidget`)
73+
- Window and Device events via the `WidgetsBindingIntegration`
74+
75+
To prevent the `WidgetsBindingIntegration` from loading by default, you'll need to remove the integration as shown below:
76+
77+
```dart
78+
// ignore: implementation_imports
79+
import 'package:sentry_flutter/src/integrations/widgets_binding_integration.dart';
80+
...
81+
SentryFlutter.init(
82+
(options) {
83+
...
84+
final integration = options.integrations
85+
.firstWhere((element) => element is WidgetsBindingIntegration);
86+
options.removeIntegration(integration);
87+
},
88+
// Init your App.
89+
appRunner: appRunner,
90+
);
91+
```
92+
93+
### Example Application
94+
95+
Copy the `main.dart` file into the `lib` folder of your existing project. This file already contains the code of the `multi_view_app.dart` from the [`flutter documentation`](https://docs.flutter.dev/platform-integration/web/embedding-flutter-web#handling-view-changes-from-dart).
96+
Next, copy the `flutter_bootstrap.js` file and the `index.html` file into the `web` folder.
97+
98+
Make sure you're using **Flutter 3.24** or newer and run the application.
99+
100+
Now you should be able to see **two** instances of the same application side by side, with different **ViewIds** in the `body`.
101+
102+
<Include name="troubleshooting/flutter/enable_multi_view.mdx" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
```dart {filename:main.dart}{tabTitle: lib/main.dart}
2+
import 'dart:async';
3+
import 'package:flutter/material.dart';
4+
import 'package:sentry_flutter/sentry_flutter.dart';
5+
import 'package:sentry_flutter/src/integrations/widgets_binding_integration.dart';
6+
import 'dart:ui' show FlutterView;
7+
8+
const String exampleDsn = '___DSN___';
9+
10+
Future<void> main() async {
11+
await SentryFlutter.init(
12+
(options) {
13+
options.dsn = exampleDsn;
14+
final integration = options.integrations
15+
.firstWhere((element) => element is WidgetsBindingIntegration);
16+
options.removeIntegration(integration);
17+
},
18+
// Init your App.
19+
appRunner: () => runWidget(
20+
MultiViewApp(
21+
viewBuilder: (BuildContext context) => DefaultAssetBundle(
22+
bundle: SentryAssetBundle(),
23+
child: const MyApp(),
24+
),
25+
),
26+
),
27+
);
28+
}
29+
30+
class MyApp extends StatefulWidget {
31+
const MyApp({super.key});
32+
33+
@override
34+
State<MyApp> createState() => _MyAppState();
35+
}
36+
37+
class _MyAppState extends State<MyApp> {
38+
@override
39+
Widget build(BuildContext context) {
40+
return MaterialApp(
41+
navigatorObservers: [
42+
SentryNavigatorObserver(),
43+
],
44+
home: Scaffold(
45+
body: Center(
46+
child: Text(
47+
'Sentry Flutter Example (ViewId:${View.of(context).viewId})'),
48+
),
49+
),
50+
);
51+
}
52+
}
53+
54+
// multi_view_app.dart
55+
56+
// Copyright 2014 The Flutter Authors. All rights reserved.
57+
// Use of this source code is governed by a BSD-style license that can be
58+
// found in the LICENSE file.
59+
60+
/// Calls [viewBuilder] for every view added to the app to obtain the widget to
61+
/// render into that view. The current view can be looked up with [View.of].
62+
class MultiViewApp extends StatefulWidget {
63+
const MultiViewApp({super.key, required this.viewBuilder});
64+
65+
final WidgetBuilder viewBuilder;
66+
67+
@override
68+
State<MultiViewApp> createState() => _MultiViewAppState();
69+
}
70+
71+
class _MultiViewAppState extends State<MultiViewApp>
72+
with WidgetsBindingObserver {
73+
@override
74+
void initState() {
75+
super.initState();
76+
WidgetsBinding.instance.addObserver(this);
77+
_updateViews();
78+
}
79+
80+
@override
81+
void didUpdateWidget(MultiViewApp oldWidget) {
82+
super.didUpdateWidget(oldWidget);
83+
// Need to re-evaluate the viewBuilder callback for all views.
84+
_views.clear();
85+
_updateViews();
86+
}
87+
88+
@override
89+
void didChangeMetrics() {
90+
_updateViews();
91+
}
92+
93+
Map<Object, Widget> _views = <Object, Widget>{};
94+
95+
void _updateViews() {
96+
final Map<Object, Widget> newViews = <Object, Widget>{};
97+
for (final FlutterView view
98+
in WidgetsBinding.instance.platformDispatcher.views) {
99+
final Widget viewWidget = _views[view.viewId] ?? _createViewWidget(view);
100+
newViews[view.viewId] = viewWidget;
101+
}
102+
setState(() {
103+
_views = newViews;
104+
});
105+
}
106+
107+
Widget _createViewWidget(FlutterView view) {
108+
return View(
109+
view: view,
110+
child: Builder(
111+
builder: widget.viewBuilder,
112+
),
113+
);
114+
}
115+
116+
@override
117+
void dispose() {
118+
WidgetsBinding.instance.removeObserver(this);
119+
super.dispose();
120+
}
121+
122+
@override
123+
Widget build(BuildContext context) {
124+
return ViewCollection(views: _views.values.toList(growable: false));
125+
}
126+
}
127+
```
128+
129+
```js {filename:flutter_bootstrap.js}{tabTitle: web/flutter_bootstrap.js}
130+
// flutter_bootstrap.js
131+
{{ flutter_js; }}
132+
{{ flutter_build_config; }}
133+
134+
_flutter.loader.load({
135+
onEntrypointLoaded: async function onEntrypointLoaded(engineInitializer) {
136+
let engine = await engineInitializer.initializeEngine({
137+
multiViewEnabled: true, // Enables embedded mode.
138+
});
139+
let app = await engine.runApp();
140+
// Make this `app` object available to your JS app.
141+
app.addView({ hostElement: document.querySelector("#left") });
142+
app.addView({ hostElement: document.querySelector("#right") });
143+
},
144+
});
145+
```
146+
147+
```html {filename:index.html}{tabTitle: web/index.html}
148+
<!doctype html>
149+
<html>
150+
<head>
151+
<!--
152+
If you're serving your web app in a path other than the root, change the
153+
href value below to reflect the base path you're serving from.
154+
155+
The path provided below has to start and end with a slash "/" in order for
156+
it to work correctly.
157+
158+
For more details:
159+
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
160+
161+
This is a placeholder for base href that will be replaced by the value of
162+
the `--base-href` argument provided to `flutter build`.
163+
-->
164+
<base href="$FLUTTER_BASE_HREF" />
165+
166+
<meta charset="UTF-8" />
167+
<meta content="IE=Edge" http-equiv="X-UA-Compatible" />
168+
<meta
169+
name="description"
170+
content="Demonstrates how to use the multiview feature with the sentry plugin."
171+
/>
172+
173+
<!-- iOS meta tags & icons -->
174+
<meta name="apple-mobile-web-app-capable" content="yes" />
175+
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
176+
<meta
177+
name="apple-mobile-web-app-title"
178+
content="sentry multiview example"
179+
/>
180+
<link rel="apple-touch-icon" href="icons/Icon-192.png" />
181+
182+
<!-- Favicon -->
183+
<link rel="shortcut icon" type="image/png" href="favicon.png" />
184+
185+
<title>sentry multiview example</title>
186+
<link rel="manifest" href="manifest.json" />
187+
</head>
188+
<body>
189+
<div style="width: 100%; height: 100%; position: absolute;">
190+
<div id="left" style="width: 50%; height: 100%; float: left;"></div>
191+
<div id="right" style="width: 50%; height: 100%; float: left;"></div>
192+
</div>
193+
<script
194+
src="flutter_bootstrap.js"
195+
type="application/javascript"
196+
async
197+
></script>
198+
</body>
199+
</html>
200+
```

0 commit comments

Comments
 (0)