From flutter-skills
Executes HTTP requests and handles JSON serialization in a Flutter app. Use when integrating with REST APIs or parsing structured data from external sources.
npx claudepluginhub gsmlg-dev/code-agent --plugin flutter-skillsThis skill uses the workspace's default tool permissions.
- [Core Guidelines](#core-guidelines)
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides MCP server integration in Claude Code plugins via .mcp.json or plugin.json configs for stdio, SSE, HTTP types, enabling external services as tools.
network_security_config.xml (Android) and NSAppTransportSecurity (iOS).Uri.https(authority, unencodedPath, [queryParameters]) to safely build URLs. This handles encoding and formatting reliably, preventing string concatenation errors.http.Response.statusCode. Treat 200 (OK) and 201 (Created) as success. Throw explicit exceptions for other codes (do not return null).compute() function.application/json.Use this workflow to implement network requests using the http package.
Task Progress:
http package to pubspec.yaml.AndroidManifest.xml and macOS .entitlements).Uri.Conditional Implementation:
http.get(uri).http.post(uri, headers: {...}, body: jsonEncode(data)). Ensure Content-Type is application/json; charset=UTF-8.http.put(uri, headers: {...}, body: jsonEncode(data)).http.delete(uri, headers: {...}).Feedback Loop: Validation & Error Handling
response.statusCode.200 or 201, call jsonDecode(response.body) and map to a Dart object.Exception('Failed to load/update/delete resource').Choose the serialization strategy based on project complexity.
Conditional Implementation:
dart:convert.json_serializable.Task Progress:
dart:convert.final properties.factory Model.fromJson(Map<String, dynamic> json) constructor.Map<String, dynamic> toJson() method.json_serializable)Task Progress:
flutter pub add json_annotation and flutter pub add -d build_runner json_serializable.json_annotation.dart in the model file.part 'model_name.g.dart'; directive.@JsonSerializable(). Use explicitToJson: true if the class contains nested models.fromJson factory and toJson method delegating to the generated functions.dart run build_runner build --delete-conflicting-outputs.Use this workflow to prevent frame drops when parsing large JSON payloads (e.g., lists of 1000+ items).
Task Progress:
String (the response body) and returns the parsed Dart object (e.g., List<Model>).jsonDecode and map the results to the Model class.response.body to Flutter's compute() function.import 'dart:convert';
import 'package:http/http.dart' as http;
class Album {
final int id;
final String title;
const Album({required this.id, required this.title});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
id: json['id'] as int,
title: json['title'] as String,
);
}
}
Future<Album> fetchAlbum() async {
final uri = Uri.https('jsonplaceholder.typicode.com', '/albums/1');
final response = await http.get(uri);
if (response.statusCode == 200) {
return Album.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else {
throw Exception('Failed to load album');
}
}
Future<Album> createAlbum(String title) async {
final uri = Uri.https('jsonplaceholder.typicode.com', '/albums');
final response = await http.post(
uri,
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{'title': title}),
);
if (response.statusCode == 201) {
return Album.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else {
throw Exception('Failed to create album.');
}
}
computeimport 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
// 1. Top-level function for parsing
List<Photo> parsePhotos(String responseBody) {
final parsed = (jsonDecode(responseBody) as List<Object?>)
.cast<Map<String, Object?>>();
return parsed.map<Photo>(Photo.fromJson).toList();
}
// 2. Fetch function using compute
Future<List<Photo>> fetchPhotos(http.Client client) async {
final uri = Uri.https('jsonplaceholder.typicode.com', '/photos');
final response = await client.get(uri);
if (response.statusCode == 200) {
// Run parsePhotos in a separate isolate
return compute(parsePhotos, response.body);
} else {
throw Exception('Failed to load photos');
}
}
json_serializable)import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable(explicitToJson: true)
class User {
final String name;
@JsonKey(name: 'registration_date_millis')
final int registrationDateMillis;
User(this.name, this.registrationDateMillis);
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}