Skip to content

Commit b2717ba

Browse files
authored
Create a flutter example application that uses multiple client implementations (#1040)
1 parent a2f3c1d commit b2717ba

File tree

138 files changed

+5061
-57
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

138 files changed

+5061
-57
lines changed

.github/workflows/dart.yml

Lines changed: 238 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ and the browser.
1414
| [http_client_conformance_tests](pkgs/http_client_conformance_tests/) | A library that tests whether implementations of package:http's `Client` class behave as expected. | |
1515
| [cronet_http](pkgs/cronet_http/) | An Android Flutter plugin that provides access to the [Cronet](https://developer.android.com/guide/topics/connectivity/cronet/reference/org/chromium/net/package-summary) HTTP client. | [![pub package](https://img.shields.io/pub/v/cronet_http.svg)](https://pub.dev/packages/cronet_http) |
1616
| [cupertino_http](pkgs/cupertino_http/) | A macOS/iOS Flutter plugin that provides access to the [Foundation URL Loading System](https://developer.apple.com/documentation/foundation/url_loading_system). | [![pub package](https://img.shields.io/pub/v/cupertino_http.svg)](https://pub.dev/packages/cupertino_http) |
17+
| [flutter_http_example](pkgs/flutter_http_example/) | An Flutter app that demonstrates how to configure and use `package:http`. ||

pkgs/cronet_http/example/lib/book.dart

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

@@ -12,20 +12,16 @@ class Book {
1212
static List<Book> listFromJson(Map<dynamic, dynamic> json) {
1313
final books = <Book>[];
1414

15-
if (json['items'] is List<dynamic>) {
16-
final items = (json['items'] as List).cast<Map<String, Object?>>();
17-
15+
if (json['items'] case final List<dynamic> items) {
1816
for (final item in items) {
19-
if (item.containsKey('volumeInfo')) {
20-
final volumeInfo = item['volumeInfo'] as Map;
21-
if (volumeInfo['title'] is String &&
22-
volumeInfo['description'] is String &&
23-
volumeInfo['imageLinks'] is Map &&
24-
(volumeInfo['imageLinks'] as Map)['smallThumbnail'] is String) {
25-
books.add(Book(
26-
volumeInfo['title'] as String,
27-
volumeInfo['description'] as String,
28-
(volumeInfo['imageLinks'] as Map)['smallThumbnail'] as String));
17+
if (item case {'volumeInfo': final Map<dynamic, dynamic> volumeInfo}) {
18+
if (volumeInfo
19+
case {
20+
'title': final String title,
21+
'description': final String description,
22+
'imageLinks': {'smallThumbnail': final String thumbnail}
23+
}) {
24+
books.add(Book(title, description, thumbnail));
2925
}
3026
}
3127
}

pkgs/cronet_http/example/lib/main.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class HomePage extends StatefulWidget {
4343

4444
class _HomePageState extends State<HomePage> {
4545
List<Book>? _books;
46+
String? _lastQuery;
4647

4748
@override
4849
void initState() {
@@ -65,6 +66,7 @@ class _HomePageState extends State<HomePage> {
6566
}
6667

6768
void _runSearch(String query) async {
69+
_lastQuery = query;
6870
if (query.isEmpty) {
6971
setState(() {
7072
_books = null;
@@ -73,6 +75,9 @@ class _HomePageState extends State<HomePage> {
7375
}
7476

7577
final books = await _findMatchingBooks(query);
78+
// Avoid the situation where a slow-running query finishes late and
79+
// replaces newer search results.
80+
if (query != _lastQuery) return;
7681
setState(() {
7782
_books = books;
7883
});
@@ -127,7 +132,8 @@ class _BookListState extends State<BookList> {
127132
leading: CachedNetworkImage(
128133
placeholder: (context, url) =>
129134
const CircularProgressIndicator(),
130-
imageUrl: widget.books[index].imageUrl),
135+
imageUrl:
136+
widget.books[index].imageUrl.replaceFirst('http', 'https')),
131137
title: Text(widget.books[index].title),
132138
subtitle: Text(widget.books[index].description),
133139
),

pkgs/cronet_http/example/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: Demonstrates how to use the cronet_http plugin.
44
publish_to: 'none'
55

66
environment:
7-
sdk: ">=2.19.0 <3.0.0"
7+
sdk: "^3.0.0"
88

99
dependencies:
1010
cached_network_image: ^3.2.3

pkgs/cupertino_http/example/lib/book.dart

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,16 @@ class Book {
1212
static List<Book> listFromJson(Map<dynamic, dynamic> json) {
1313
final books = <Book>[];
1414

15-
if (json['items'] is List<dynamic>) {
16-
final items = (json['items'] as List).cast<Map<String, Object?>>();
17-
15+
if (json['items'] case final List<dynamic> items) {
1816
for (final item in items) {
19-
if (item.containsKey('volumeInfo')) {
20-
final volumeInfo = item['volumeInfo'] as Map;
21-
if (volumeInfo['title'] is String &&
22-
volumeInfo['description'] is String &&
23-
volumeInfo['imageLinks'] is Map &&
24-
(volumeInfo['imageLinks'] as Map)['smallThumbnail'] is String) {
25-
books.add(Book(
26-
volumeInfo['title'] as String,
27-
volumeInfo['description'] as String,
28-
(volumeInfo['imageLinks'] as Map)['smallThumbnail'] as String));
17+
if (item case {'volumeInfo': final Map<dynamic, dynamic> volumeInfo}) {
18+
if (volumeInfo
19+
case {
20+
'title': final String title,
21+
'description': final String description,
22+
'imageLinks': {'smallThumbnail': final String thumbnail}
23+
}) {
24+
books.add(Book(title, description, thumbnail));
2925
}
3026
}
3127
}

pkgs/cupertino_http/example/lib/main.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class HomePage extends StatefulWidget {
4141

4242
class _HomePageState extends State<HomePage> {
4343
List<Book>? _books;
44+
String? _lastQuery;
4445

4546
@override
4647
void initState() {
@@ -63,6 +64,7 @@ class _HomePageState extends State<HomePage> {
6364
}
6465

6566
void _runSearch(String query) async {
67+
_lastQuery = query;
6668
if (query.isEmpty) {
6769
setState(() {
6870
_books = null;
@@ -71,6 +73,9 @@ class _HomePageState extends State<HomePage> {
7173
}
7274

7375
final books = await _findMatchingBooks(query);
76+
// Avoid the situation where a slow-running query finishes late and
77+
// replaces newer search results.
78+
if (query != _lastQuery) return;
7479
setState(() {
7580
_books = books;
7681
});

pkgs/flutter_http_example/.gitignore

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Miscellaneous
2+
*.class
3+
*.log
4+
*.pyc
5+
*.swp
6+
.DS_Store
7+
.atom/
8+
.buildlog/
9+
.history
10+
.svn/
11+
migrate_working_dir/
12+
13+
# IntelliJ related
14+
*.iml
15+
*.ipr
16+
*.iws
17+
.idea/
18+
19+
# The .vscode folder contains launch configuration and tasks you configure in
20+
# VS Code which you may wish to be included in version control, so this line
21+
# is commented out by default.
22+
#.vscode/
23+
24+
# Flutter/Dart/Pub related
25+
**/doc/api/
26+
**/ios/Flutter/.last_build_id
27+
.dart_tool/
28+
.flutter-plugins
29+
.flutter-plugins-dependencies
30+
.packages
31+
.pub-cache/
32+
.pub/
33+
/build/
34+
35+
# Symbolication related
36+
app.*.symbols
37+
38+
# Obfuscation related
39+
app.*.map.json
40+
41+
# Android Studio will place build artifacts here
42+
/android/app/debug
43+
/android/app/profile
44+
/android/app/release

pkgs/flutter_http_example/.metadata

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# This file tracks properties of this Flutter project.
2+
# Used by Flutter tool to assess capabilities and perform upgrades etc.
3+
#
4+
# This file should be version controlled and should not be manually edited.
5+
6+
version:
7+
revision: "367f9ea16bfae1ca451b9cc27c1366870b187ae2"
8+
channel: "stable"
9+
10+
project_type: app
11+
12+
# Tracks metadata for the flutter migrate command
13+
migration:
14+
platforms:
15+
- platform: root
16+
create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
17+
base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
18+
- platform: android
19+
create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
20+
base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
21+
- platform: ios
22+
create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
23+
base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
24+
- platform: linux
25+
create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
26+
base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
27+
- platform: macos
28+
create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
29+
base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
30+
- platform: web
31+
create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
32+
base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
33+
- platform: windows
34+
create_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
35+
base_revision: 367f9ea16bfae1ca451b9cc27c1366870b187ae2
36+
37+
# User provided section
38+
39+
# List of Local paths (relative to this file) that should be
40+
# ignored by the migrate tool.
41+
#
42+
# Files that are not part of the templates will be ignored by default.
43+
unmanaged_files:
44+
- 'lib/main.dart'
45+
- 'ios/Runner.xcodeproj/project.pbxproj'

pkgs/flutter_http_example/README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# flutter_http_example
2+
3+
A Flutter sample app that illustrates how to configure and use
4+
[`package:http`](https://pub.dev/packages/http).
5+
6+
## Goals for this sample
7+
8+
* Provide you with example code for using `package:http` in Flutter,
9+
including:
10+
11+
* configuration for multiple platforms.
12+
* using `runWithClient` and `package:provider` to pass `Client`s through
13+
an application.
14+
* writing tests using `MockClient`.
15+
16+
## The important bits
17+
18+
### `http_client_factory.dart`
19+
20+
This library used to create `package:http` `Client`s when the app is run inside
21+
the Dart virtual machine, meaning all platforms except the web browser.
22+
23+
### `http_client_factory_web.dart`
24+
25+
This library used to create `package:http` `Client`s when the app is run inside
26+
a web browser.
27+
28+
Web configuration must be done in a seperate library because Dart code cannot
29+
import `dart:ffi` or `dart:io` when run in a web browser.
30+
31+
### `main.dart`
32+
33+
This library demonstrates how to:
34+
35+
* import `http_client_factory.dart` or `http_client_factory_web.dart`,
36+
depending on whether we are targeting the web browser or not.
37+
* share a `package:http` `Client` by using `runWithClient` and
38+
`package:provider`.
39+
* call `package:http` functions.
40+
41+
### `widget_test.dart`
42+
43+
This library demonstrates how to construct tests using `MockClient`.

0 commit comments

Comments
 (0)