[url_launcher] Add a workaround for Uri encoding (#3817)
`Uri`'s constructor doesn't handle query parameters correctly for
non-http(s) schemes, so the `mailto` example in the README is
misleading. This updates the README to show using a simple method
to work around that bug, and a warning about the need to use it.
Fixes https://github.com/flutter/flutter/issues/75552
Fixes https://github.com/flutter/flutter/issues/73717
diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md
index 03a3f6f..697b7c7 100644
--- a/packages/url_launcher/url_launcher/CHANGELOG.md
+++ b/packages/url_launcher/url_launcher/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 6.0.7
+
+* Update the README to describe a workaround to the `Uri` query
+ encoding bug.
+
## 6.0.6
* Require `url_launcher_platform_interface` 2.0.3. This fixes an issue
diff --git a/packages/url_launcher/url_launcher/README.md b/packages/url_launcher/url_launcher/README.md
index 31fed9a..20ee0a5 100644
--- a/packages/url_launcher/url_launcher/README.md
+++ b/packages/url_launcher/url_launcher/README.md
@@ -10,10 +10,10 @@
## Installation
-### iOS
+### iOS
Add any URL schemes passed to `canLaunch` as `LSApplicationQueriesSchemes` entries in your Info.plist file.
-Example:
+Example:
```
<key>LSApplicationQueriesSchemes</key>
<array>
@@ -73,25 +73,35 @@
### Encoding URLs
-URLs must be properly encoded, especially when including spaces or other special characters. This can be done using the [`Uri` class](https://api.dart.dev/stable/2.7.1/dart-core/Uri-class.html):
+URLs must be properly encoded, especially when including spaces or other special
+characters. This can be done using the
+[`Uri` class](https://api.dart.dev/stable/2.7.1/dart-core/Uri-class.html).
+For example:
```dart
-import 'dart:core';
-import 'package:url_launcher/url_launcher.dart';
+String? encodeQueryParameters(Map<String, String> params) {
+ return params.entries
+ .map((e) => '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
+ .join('&');
+}
-final Uri _emailLaunchUri = Uri(
+final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: 'smith@example.com',
- queryParameters: {
+ query: encodeQueryParameters(<String, String>{
'subject': 'Example Subject & Symbols are allowed!'
- }
+ }),
);
-// ...
-
-// mailto:smith@example.com?subject=Example+Subject+%26+Symbols+are+allowed%21
-launch(_emailLaunchUri.toString());
+launch(emailLaunchUri.toString());
```
+**Warning**: For any scheme other than `http` or `https`, you should use the
+`query` parameter and the `encodeQueryParameters` function shown above rather
+than `Uri`'s `queryParameters` constructor argument, due to
+[a bug](https://github.com/dart-lang/sdk/issues/43838) in the way `Uri`
+encodes query parameters. Using `queryParameters` will result in spaces being
+converted to `+` in many cases.
+
## Handling missing URL receivers
A particular mobile device may not be able to receive all supported URL schemes.
@@ -113,4 +123,4 @@
If you do this for a URL of a page containing JavaScript, make sure to pass in
`enableJavaScript: true`, or else the launch method will not work properly. On
iOS, the default behavior is to open all web URLs within the app. Everything
-else is redirected to the app handler.
\ No newline at end of file
+else is redirected to the app handler.
diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml
index 00cfc21..a2facbd 100644
--- a/packages/url_launcher/url_launcher/pubspec.yaml
+++ b/packages/url_launcher/url_launcher/pubspec.yaml
@@ -3,7 +3,7 @@
web, phone, SMS, and email schemes.
repository: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22
-version: 6.0.6
+version: 6.0.7
environment:
sdk: ">=2.12.0 <3.0.0"