This repository was archived by the owner on Feb 22, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[url_launcher] Replace primary APIs with cleaner versions #5310
Merged
fluttergithubbot
merged 17 commits into
flutter:main
from
stuartmorgan-g:url-launch-uri-revisit
Apr 22, 2022
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
c02f540
Move legacy API
stuartmorgan-g 6bf91b5
Add new APIs
stuartmorgan-g 3484b03
Move existing tests
stuartmorgan-g 3a1a01d
Minor impl adjustment
stuartmorgan-g 66f75d6
Add new tests
stuartmorgan-g 9661bb8
Deprecate old APIs, update example
stuartmorgan-g b441f42
Update, and rearrange, README
stuartmorgan-g fa44fe1
Bump verion, update CHANGELOG
stuartmorgan-g bea5ff5
Update canLaunchUrl docs and README to better cover web
stuartmorgan-g 45e6415
Document the other deprecation
stuartmorgan-g 7c98887
Fix Link unit test expectations of ignored params
stuartmorgan-g e257e6f
Update packages/url_launcher/url_launcher/lib/src/types.dart
stuartmorgan-g 1e89cbc
Use Uri.parse in example
stuartmorgan-g be531c2
Typo fix
stuartmorgan-g fac125e
Remove export of Uri version from String version
stuartmorgan-g e67e2cc
Typo
stuartmorgan-g 338b439
Typo in code comment
stuartmorgan-g File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,23 +18,23 @@ To use this plugin, add `url_launcher` as a [dependency in your pubspec.yaml fil | |
import 'package:flutter/material.dart'; | ||
import 'package:url_launcher/url_launcher.dart'; | ||
|
||
const String _url = 'https://flutter.dev'; | ||
final Uri _url = Uri.parse('https://flutter.dev'); | ||
|
||
void main() => runApp( | ||
const MaterialApp( | ||
home: Material( | ||
child: Center( | ||
child: RaisedButton( | ||
onPressed: _launchURL, | ||
onPressed: _launchUrl, | ||
child: Text('Show Flutter homepage'), | ||
), | ||
), | ||
), | ||
), | ||
); | ||
|
||
void _launchURL() async { | ||
if (!await launch(_url)) throw 'Could not launch $_url'; | ||
void _launchUrl() async { | ||
if (!await launchUrl(_url)) throw 'Could not launch $_url'; | ||
} | ||
``` | ||
|
||
|
@@ -43,7 +43,7 @@ See the example app for more complex examples. | |
## Configuration | ||
|
||
### iOS | ||
Add any URL schemes passed to `canLaunch` as `LSApplicationQueriesSchemes` entries in your Info.plist file. | ||
Add any URL schemes passed to `canLaunchUrl` as `LSApplicationQueriesSchemes` entries in your Info.plist file. | ||
|
||
Example: | ||
``` | ||
|
@@ -59,7 +59,7 @@ See [`-[UIApplication canOpenURL:]`](https://developer.apple.com/documentation/u | |
### Android | ||
|
||
Starting from API 30 Android requires package visibility configuration in your | ||
`AndroidManifest.xml` otherwise `canLaunch` will return `false`. A `<queries>` | ||
`AndroidManifest.xml` otherwise `canLaunchUrl` will return `false`. A `<queries>` | ||
element must be added to your manifest as a child of the root element. | ||
|
||
The snippet below shows an example for an application that uses `https`, `tel`, | ||
|
@@ -94,34 +94,53 @@ for examples of other queries. | |
|
||
## Supported URL schemes | ||
|
||
The [`launch`](https://pub.dev/documentation/url_launcher/latest/url_launcher/launch.html) method | ||
takes a string argument containing a URL. This URL | ||
can be formatted using a number of different URL schemes. The supported | ||
URL schemes depend on the underlying platform and installed apps. | ||
The provided URL is passed directly to the host platform for handling. The | ||
supported URL schemes therefore depend on the platform and installed apps. | ||
|
||
Commonly used schemes include: | ||
|
||
| Scheme | Example | Action | | ||
|:---|:---|:---| | ||
| `https:<URL>` | `https://flutter.dev` | Open URL in the default browser | | ||
| `mailto:<email address>?subject=<subject>&body=<body>` | `mailto:smith@example.org?subject=News&body=New%20plugin` | Create email to <email address> in the default email app | | ||
| `tel:<phone number>` | `tel:+1-555-010-999` | Make a phone call to <phone number> using the default phone app | | ||
| `sms:<phone number>` | `sms:5550101234` | Send an SMS message to <phone number> using the default messaging app | | ||
| `https:<URL>` | `https://flutter.dev` | Open `<URL>` in the default browser | | ||
| `mailto:<email address>?subject=<subject>&body=<body>` | `mailto:smith@example.org?subject=News&body=New%20plugin` | Create email to `<email address>` in the default email app | | ||
| `tel:<phone number>` | `tel:+1-555-010-999` | Make a phone call to `<phone number>` using the default phone app | | ||
| `sms:<phone number>` | `sms:5550101234` | Send an SMS message to `<phone number>` using the default messaging app | | ||
| `file:<path>` | `file:/home` | Open file or folder using default app association, supported on desktop platforms | | ||
|
||
More details can be found here for [iOS](https://developer.apple.com/library/content/featuredarticles/iPhoneURLScheme_Reference/Introduction/Introduction.html) | ||
and [Android](https://developer.android.com/guide/components/intents-common.html) | ||
|
||
**Note**: URL schemes are only supported if there are apps installed on the device that can | ||
URL schemes are only supported if there are apps installed on the device that can | ||
support them. For example, iOS simulators don't have a default email or phone | ||
apps installed, so can't open `tel:` or `mailto:` links. | ||
|
||
### Checking supported schemes | ||
|
||
If you need to know at runtime whether a scheme is guaranteed to work before | ||
using it (for instance, to adjust your UI based on what is available), you can | ||
check with [`canLaunchUrl`](https://pub.dev/documentation/url_launcher/latest/url_launcher/canLaunchUrl.html). | ||
|
||
However, `canLaunchUrl` can return false even if `launchUrl` would work in | ||
some circumstances (in web applications, on mobile without the necessary | ||
configuration as described above, etc.), so in cases where you can provide | ||
fallback behavior it is better to use `launchUrl` directly and handle failure. | ||
For example, a UI button that would have sent feedback email using a `mailto` URL | ||
might instead open a web-based feedback form using an `https` URL on failure, | ||
rather than disabling the button if `canLaunchUrl` returns false for `mailto`. | ||
|
||
### Encoding URLs | ||
|
||
URLs must be properly encoded, especially when including spaces or other special | ||
characters. This can be done using the | ||
characters. In general this is handled automatically by the | ||
[`Uri` class](https://api.dart.dev/dart-core/Uri-class.html). | ||
For example: | ||
|
||
**However**, for any scheme other than `http` or `https`, you should use the | ||
`query` parameter and the `encodeQueryParameters` function shown below rather | ||
than `Uri`'s `queryParameters` constructor argument for any query parameters, | ||
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. | ||
|
||
```dart | ||
String? encodeQueryParameters(Map<String, String> params) { | ||
return params.entries | ||
|
@@ -137,57 +156,46 @@ final Uri emailLaunchUri = Uri( | |
}), | ||
); | ||
|
||
launch(emailLaunchUri.toString()); | ||
launchUrl(emailLaunchUri); | ||
``` | ||
|
||
**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 | ||
### URLs not handled by `Uri` | ||
|
||
A particular mobile device may not be able to receive all supported URL schemes. | ||
For example, a tablet may not have a cellular radio and thus no support for | ||
launching a URL using the `sms` scheme, or a device may not have an email app | ||
and thus no support for launching a URL using the `mailto` scheme. | ||
In rare cases, you may need to launch a URL that the host system considers | ||
valid, but cannot be expressed by `Uri`. For those cases, alternate APIs using | ||
strings are available by importing `url_launcher_string.dart`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we take a page from the React book and call this file: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did think about it; my hope is that having to find a separate import is already enough of a deterrent. If that turns out not to be true and we see a lot of people filing issue because they blindly used this and ignored all the warnings about how it should rarely be used, we could deprecate that import file and add one with a scary name. |
||
|
||
We recommend checking which URL schemes are supported using the | ||
[`canLaunch`](https://pub.dev/documentation/url_launcher/latest/url_launcher/canLaunch.html) | ||
in most cases. If the `canLaunch` method returns false, as a | ||
best practice we suggest adjusting the application UI so that the unsupported | ||
URL is never triggered; for example, if the `mailto` scheme is not supported, a | ||
UI button that would have sent feedback email could be changed to instead open | ||
a web-based feedback form using an `https` URL. | ||
Using these APIs in any other cases is **strongly discouraged**, as providing | ||
invalid URL strings was a very common source of errors with this plugin's | ||
original APIs. | ||
|
||
## Browser vs In-app Handling | ||
By default, Android opens up a browser when handling URLs. You can pass | ||
`forceWebView: true` parameter to tell the plugin to open a WebView instead. | ||
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. | ||
### File scheme handling | ||
|
||
## File scheme handling | ||
`file:` scheme can be used on desktop platforms: `macOS`, `Linux` and `Windows`. | ||
`file:` scheme can be used on desktop platforms: Windows, macOS, and Linux. | ||
|
||
We recommend checking first whether the directory or file exists before calling `launch`. | ||
We recommend checking first whether the directory or file exists before calling `launchUrl`. | ||
|
||
Example: | ||
```dart | ||
var filePath = '/path/to/file'; | ||
final Uri uri = Uri.file(filePath); | ||
|
||
if (await File(uri.toFilePath()).exists()) { | ||
if (!await launch(uri.toString())) { | ||
if (!await launchUrl(uri)) { | ||
throw 'Could not launch $uri'; | ||
} | ||
} | ||
``` | ||
|
||
### macOS file access configuration | ||
#### macOS file access configuration | ||
|
||
If you need to access files outside of your application's sandbox, you will need to have the necessary | ||
[entitlements](https://docs.flutter.dev/desktop#entitlements-and-the-app-sandbox). | ||
|
||
## Browser vs in-app Handling | ||
|
||
On some platforms, web URLs can be launched either in an in-app web view, or | ||
in the default browser. The default behavior depends on the platform (see | ||
[`launchUrl`](https://pub.dev/documentation/url_launcher/latest/url_launcher/launchUrl.html) | ||
for details), but a specific mode can be used on supported platforms by | ||
passing a `LaunchMode`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is changing the default setting not a braking change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case the old API with the old config style is still available. You only need to migrate to the
WebViewConfiguration
if you start using the new URI/String based APIs (not the one underlegacy
)