Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pkgs/cronet_http/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.9.1-wip

* Update example to fetch and display scores of package:cronet_http from pub.dev.

## 1.9.0

* Add `CronetEngine.startNetLogToFile` and `CronetEngine.stopNetLog`.
Expand Down
12 changes: 4 additions & 8 deletions pkgs/cronet_http/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,14 @@ void main() async {
final engine = CronetEngine.build(
cacheMode: CacheMode.memory,
cacheMaxSize: 2 * 1024 * 1024,
userAgent: 'Book Agent');
userAgent: 'Package Client');
httpClient = CronetClient.fromCronetEngine(engine, closeEngine: true);
} else {
httpClient = IOClient(HttpClient()..userAgent = 'Book Agent');
httpClient = IOClient(HttpClient()..userAgent = 'Package Client');
}

final response = await client.get(
Uri.https(
'www.googleapis.com',
'/books/v1/volumes',
{'q': 'HTTP', 'maxResults': '40', 'printType': 'books'},
),
final response = await httpClient.get(
Uri.https('pub.dev', '/api/packages/cronet_http/score'),
);
httpClient.close();
}
Expand Down
4 changes: 4 additions & 0 deletions pkgs/cronet_http/example/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ org.gradle.jvmargs=-Xmx12800M
org.gradle.caching=true
android.useAndroidX=true
android.enableJetifier=true
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
# This newDsl flag was added automatically by Flutter migrator
android.newDsl=false
32 changes: 0 additions & 32 deletions pkgs/cronet_http/example/lib/book.dart

This file was deleted.

138 changes: 41 additions & 97 deletions pkgs/cronet_http/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,145 +9,89 @@ import 'package:cronet_http/cronet_http.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:http/io_client.dart';
import 'package:http_image_provider/http_image_provider.dart';
import 'package:provider/provider.dart';

import 'book.dart';

void main() {
final Client httpClient;
if (Platform.isAndroid) {
WidgetsFlutterBinding.ensureInitialized();
final engine = CronetEngine.build(
cacheMode: CacheMode.memory,
cacheMaxSize: 2 * 1024 * 1024,
userAgent: 'Book Agent');
userAgent: 'Package Client');
httpClient = CronetClient.fromCronetEngine(engine, closeEngine: true);
} else {
httpClient = IOClient(HttpClient()..userAgent = 'Book Agent');
httpClient = IOClient(HttpClient()..userAgent = 'Package Client');
}

runApp(Provider<Client>(
create: (_) => httpClient,
child: const BookSearchApp(),
child: const PackageDetailsApp(),
dispose: (_, client) => client.close()));
}

class BookSearchApp extends StatelessWidget {
const BookSearchApp({super.key});
class PackageDetailsApp extends StatelessWidget {
const PackageDetailsApp({super.key});

@override
Widget build(BuildContext context) => const MaterialApp(
// Remove the debug banner.
debugShowCheckedModeBanner: false,
title: 'Book Search',
home: HomePage(),
title: 'Package Details',
home: PackageDetailsPage(),
);
}

class HomePage extends StatefulWidget {
const HomePage({super.key});
class PackageDetailsPage extends StatefulWidget {
const PackageDetailsPage({super.key});

@override
State<HomePage> createState() => _HomePageState();
State<PackageDetailsPage> createState() => _PackageDetailsPageState();
}

class _HomePageState extends State<HomePage> {
List<Book>? _books;
String? _lastQuery;
late Client _client;
class _PackageDetailsPageState extends State<PackageDetailsPage> {
String _output = 'Loading...';

@override
void initState() {
super.initState();
_client = context.read<Client>();
}

// Get the list of books matching `query`.
// The `get` call will automatically use the `client` configured in `main`.
Future<List<Book>> _findMatchingBooks(String query) async {
final response = await _client.get(
Uri.https(
'www.googleapis.com',
'/books/v1/volumes',
{'q': query, 'maxResults': '20', 'printType': 'books'},
),
);

final json = jsonDecode(utf8.decode(response.bodyBytes)) as Map;
return Book.listFromJson(json);
_fetchPackageInfo();
}

void _runSearch(String query) async {
_lastQuery = query;
if (query.isEmpty) {
void _fetchPackageInfo() async {
final client = context.read<Client>();
try {
final response = await client.get(
Uri.https('pub.dev', '/api/packages/cronet_http/score'),
);
if (response.statusCode == 200) {
final json =
jsonDecode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>;
setState(() {
_output = 'Information about package:cronet_http:\n'
'- Likes: ${json['likeCount']}\n'
'- 30-day downloads: ${json['downloadCount30Days']}';
});
} else {
setState(() {
_output = 'Request failed with status: ${response.statusCode}.';
});
}
} catch (e) {
setState(() {
_books = null;
_output = 'Request failed: $e';
});
return;
}

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

@override
Widget build(BuildContext context) {
final searchResult = _books == null
? const Text('Please enter a query', style: TextStyle(fontSize: 24))
: _books!.isNotEmpty
? BookList(_books!)
: const Text('No results found', style: TextStyle(fontSize: 24));

return Scaffold(
appBar: AppBar(title: const Text('Book Search')),
body: Padding(
padding: const EdgeInsets.all(10),
child: Column(
children: [
const SizedBox(height: 20),
TextField(
onChanged: _runSearch,
decoration: const InputDecoration(
labelText: 'Search',
suffixIcon: Icon(Icons.search),
),
Widget build(BuildContext context) => Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(
_output,
style: const TextStyle(fontSize: 18, fontFamily: 'monospace'),
),
const SizedBox(height: 20),
Expanded(child: searchResult),
],
),
),
);
}
}

class BookList extends StatefulWidget {
final List<Book> books;
const BookList(this.books, {super.key});

@override
State<BookList> createState() => _BookListState();
}

class _BookListState extends State<BookList> {
@override
Widget build(BuildContext context) => ListView.builder(
itemCount: widget.books.length,
itemBuilder: (context, index) => Card(
key: ValueKey(widget.books[index].title),
child: ListTile(
leading: Image(
image: HttpImageProvider(
widget.books[index].imageUrl.replace(scheme: 'https'),
client: context.read<Client>())),
title: Text(widget.books[index].title),
subtitle: Text(widget.books[index].description),
),
),
);
Expand Down
2 changes: 0 additions & 2 deletions pkgs/cronet_http/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ environment:
dependencies:
cronet_http:
path: ../
cupertino_icons: ^1.0.2
flutter:
sdk: flutter
http: ^1.0.0
http_image_provider: ^1.0.0
provider: ^6.1.1

dev_dependencies:
Expand Down
7 changes: 4 additions & 3 deletions pkgs/cronet_http/lib/cronet_http.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@
/// final engine = CronetEngine.build(
/// cacheMode: CacheMode.memory,
/// cacheMaxSize: 2 * 1024 * 1024,
/// userAgent: 'Book Agent');
/// userAgent: 'Package Client');
/// httpClient = CronetClient.fromCronetEngine(engine, closeEngine: true);
/// } else {
/// httpClient = IOClient(HttpClient()..userAgent = 'Book Agent');
/// httpClient = IOClient(
/// HttpClient()..userAgent = 'Package Client');
/// }
///
/// runApp(Provider<Client>(
/// create: (_) => httpClient,
/// child: const BookSearchApp(),
/// child: const PackageDetailsApp(),
/// dispose: (_, client) => client.close()));
/// }
/// }
Expand Down
4 changes: 2 additions & 2 deletions pkgs/cronet_http/lib/src/cronet_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -629,11 +629,11 @@ class CronetClient extends BaseClient {
/// void main() {
/// Client clientFactory() {
/// final engine = CronetEngine.build(
/// cacheMode: CacheMode.memory, userAgent: 'Book Agent');
/// cacheMode: CacheMode.memory, userAgent: 'Package Client');
/// return CronetClient.fromCronetEngineFuture(engine);
/// }
///
/// runWithClient(() => runApp(const BookSearchApp()), clientFactory);
/// runWithClient(() => runApp(const PackageDetailsApp()), clientFactory);
/// }
/// ```
@override
Expand Down
2 changes: 1 addition & 1 deletion pkgs/cronet_http/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: cronet_http
version: 1.9.0
version: 1.9.1-wip
description: >-
An Android Flutter plugin that provides access to the Cronet HTTP client.
repository: https://github.com/dart-lang/http/tree/master/pkgs/cronet_http
Expand Down
4 changes: 4 additions & 0 deletions pkgs/cupertino_http/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 3.0.3-wip

* Update example to fetch and display scores of package:cupertino_http from pub.dev.

## 3.0.2

* Fix a [bug](https://github.com/dart-lang/http/issues/1929) where code
Expand Down
11 changes: 5 additions & 6 deletions pkgs/cupertino_http/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,15 @@ void main() async {
if (Platform.isIOS || Platform.isMacOS) {
final config = URLSessionConfiguration.ephemeralSessionConfiguration()
..cache = URLCache.withCapacity(memoryCapacity: 2 * 1024 * 1024)
..httpAdditionalHeaders = {'User-Agent': 'Book Agent'};
..httpAdditionalHeaders = {'User-Agent': 'Package Client'};
httpClient = CupertinoClient.fromSessionConfiguration(config);
} else {
httpClient = IOClient(HttpClient()..userAgent = 'Book Agent');
httpClient = IOClient(HttpClient()..userAgent = 'Package Client');
}

final response = await httpClient.get(Uri.https(
'www.googleapis.com',
'/books/v1/volumes',
{'q': 'HTTP', 'maxResults': '40', 'printType': 'books'}));
final response = await httpClient.get(
Uri.https('pub.dev', '/api/packages/cupertino_http/score'),
);

httpClient.close();
}
Expand Down
24 changes: 13 additions & 11 deletions pkgs/cupertino_http/example/example.dart
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:convert' as convert;

import 'package:cupertino_http/cupertino_http.dart';

void main(List<String> arguments) async {
// This example uses the Google Books API to search for books about http.
// https://developers.google.com/books/docs/overview

// For a complete example of using `package:cupertino_http` in a Flutter
// application, see:
// https://github.com/dart-lang/http/tree/master/pkgs/flutter_http_example
// This example uses the pub.dev API to fetch details about
// package:cupertino_http.
// https://pub.dev/help/api
final client = CupertinoClient.defaultSessionConfiguration();
final url = Uri.https('www.googleapis.com', '/books/v1/volumes', {
'q': '{http}',
});
final url = Uri.https('pub.dev', '/api/packages/cupertino_http/score');

// Await the http get response, then decode the json-formatted response.
final response = await client.get(url);
if (response.statusCode == 200) {
var jsonResponse =
convert.jsonDecode(response.body) as Map<String, dynamic>;
var itemCount = jsonResponse['totalItems'];
print('Number of books about http: $itemCount.');
var likes = jsonResponse['likeCount'];
var downloads = jsonResponse['downloadCount30Days'];
print('Information about package:cupertino_http:');
print('- Likes: $likes');
print('- 30-day downloads: $downloads');
} else {
print('Request failed with status: ${response.statusCode}.');
}
Expand Down
Loading
Loading