[ð°åå¿è åãð°]Flutter/dartã§åŠã¶ããã°ã©ãã³ã° ~åå®å šæ§ã£ãŠïŒ~
ãœã¡ãœã¡ã®ã€ã©ãGW Advent(?) Calendar5æ¥ç®ã®èšäºã§ãïŒ
仿¥ã¯æ°åããããŠåå¿ã«åž°ãããšæããŸãã
ç§ãããã°ã©ãã³ã°ã«è§ŠããŠå匷ãå§ããŠãã4幎以äžãçµéããŠãããããã®ã§åå¿ã«åž°ã£ãŠããã°ã©ãã³ã°ã«ã€ããŠå匷ããªãããïŒãšããããšã§GPTå
çãçžæ£ã«ä»åã¯å匷ããŸã
ããããåã£ãŠãªãã ãð¡
GPTå
çïŒ
åã¯ããŒã¿ã®çš®é¡
- ãããã«ã¡ã¯ãã¯æååïŒStringïŒ
- 123ã¯æŽæ°ïŒintïŒ
- trueãšãfalseã¯çåœå€ïŒboolïŒ
ãªãã»ã©æååã§å®£èšãã倿°ã«ã¯æååããå ¥ããªãããæŽæ°ãªãæŽæ°ãšããããšãããã
String name='tolto';
int age=20;
bool isActiv=false;
// âïž :name='user1';
// â :name=123;
// âïž :age=12;
// â :age='user1';
åå®å šæ§ã£ãŠïŒ
ä»åã¯ãã°ã€ã³èªèšŒãäŸã«èããŠã¿ãŸãã
Flutterã¢ããªã§ãã°ã€ã³ç»é¢ããããšä»®å®ããå Žåãæ³å®ããŠä»åã¯ãŠãŒã¶ãŒãå
¥åããã®ã
- ã¡ãŒã«ã¢ãã¬ã¹ïŒStringïŒ
- ãã¹ã¯ãŒãïŒStringïŒ
ã«çµããŸãã
ãã®ãšããFlutterïŒDartïŒã§ãããªé¢šã«å€æ°ãçšæ
String email = 'example@email.com';
String password = 'mypassword123';
åå®å
šæ§ããªãå Žåã©ããªãã®ã
ãããåãããã¡ããã¡ãã§ãOKã ãš
email = 12345; // ã¡ãŒã«ã¢ãã¬ã¹ã«æ°åãå
¥ãã
ãããªã£ãŠããŸããšã¡ãŒã«ã¢ãã¬ã¹ã¯æ¬æ¥ãæåãã§ã§ããŠãããæ°åã ããããã°ã€ã³ã§ããããããªããšããããšãçºçããŠããŸããŸãã
ããã§ç»å Žããã®ã**ãåå®å
šæ§ã**ã§ãã
Dartã¯åå®å
šãªèšèªã ããããããééããã¡ãããšãšã©ãŒã«ããŠãããŸãã
ã§ã¯å®éã®ã³ãŒããèŠãŠã¿ãŸãããã
void login(String email, String password) {
print('ãã°ã€ã³äž: $email');
}
void main() {
login('taro@example.com', 'pass1234'); // OKïŒ
login(12345, true); // ããã¯ãšã©ãŒ
}
ãã®ããã«ééã£ããåãã®ããŒã¿ã䜿ãããšãããDartãæããŠãããŸãã
ããŒã䟿å©ãããïŒ
ãããŸã§èªãã§ããïŒããã ãããå šç¶å®çšé¢ã§ã®æ³åã€ããããããšæã£ãŠã人ããããšæãã®ã§ãããããå®çšçãªéšåãžæãäžããŠã¿ãŸãã
åå®å®å šæ§ãä¿ã£ãã¡ãœãã
以äžã®ããã«dartã§ã¯åŒæ°ã«åã宣èšããªããŠããšã©ãŒãåºããã«ã³ã³ãã€ã«ã§ããŸãã
void login(mail, pass) {
print('ã¡ãŒã«: $mail, ãã¹: $pass');
}
GPTå çïŒ
ãã§ããããã£ãŠåå®å šãªã®ïŒã
çµè«ããèšããšâŠ
ãã®æžãæ¹ã ãšãåå®å šã§ã¯ãªããïŒ
ãªãããšãããšãDartã¯**åãæžããªããšãdynamicïŒäœã§ãããã®åïŒ**ãšããŠæ±ã£ã¡ããããã
ã ããã§ãã
ã€ãŸã
void login(dynamic mail, dynamic pass) { ... }
ãšåãæå³ã«ãªã£ãŠããŸã£ãŠããã®ã§
login(12345, true); // æ°åãšçåœå€
ããã§ãdartã¯æããªãã®ã§ã³ã³ãã€ã«ã§ããŠããŸãã
ããã ãšãŠãŒã¶ãŒããã®ããŒã¿ãã¡ãã£ã¯ãã£ã§ãäºåã«åŒŸãããšãã§ããªãã®ã§æå³ããåäœãããªããªã£ãŠããŸãå±éºæ§ãããèš³ã§ãã
ãªã®ã§é¢æ°ã®å®£èšãããæã¯
void login(String email, String password) {
print('ãã°ã€ã³äž: $email');
}
ããããããšã§åãæžãããå®å šãªã³ãŒãã«ãªããŸãã
GPTå çïŒ
ã ãããã¡ãããšåãæžããããšããå®å šã§ãã°ã®å°ãªãã¢ããªãäœãã³ã
ãªãã»ã©...確ãã«éèŠã ïŒãšãªã£ãèš³ã§ãã
ãããŸã§èªãã§ã俺ã«ã¯ãŸã ãŸã ãã®è¶³ããªããã»ã»ã»!ãã£ãšå®çšçãªã®ãç¥ããããã ïŒãã£ãŠãã人åãã«å¿çšç·šãæžããŸãã
å®çšçãªåå®å šâ ïŒå¿çšç·š
Flutterã«ã¯å倧ãªRemiãããããŸããããã§ãRiverodãproviderãäœã£ããã®äººã§ãã
ãã®Remiãããäœã£ãã®ãFreezedã§ããã䜿ãã°å®å
šãã€æ¥œã«è£å©ã¯ã©ã¹ãçæããŠåå©çšã§ããŸãããŸãä»åã®è¶£æšãšã¯å€ããŸããFreezedã䜿ãã°æ¥œã«JSONã®ãšã³ã³ãŒãããã³ãŒããã§ããã®ã§è©³ãã調ã¹ãŠã¿ãŠãã ããã
ã€ã³ã¹ããŒã«
dependencies:
flutter:
sdk: flutter
freezed: ^2.5.2
freezed_annotation: ^2.4.4
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^4.0.0
json_serializable: ^6.5.4
build_runner: ^2.4.13
ã³ãŒãã£ã³ã°
ä»åã¯è£å©ã¯ã©ã¹ãšããŠLoginEntity
ãäœæããŸãã
import 'package:freezed_annotation/freezed_annotation.dart';
part 'login_entity.freezed.dart';
class LoginEntity with _$LoginEntity {
const factory LoginEntity({
required String email,
required String password,
}) = _LoginEntity;
}
ãããã³ããŒããããšã©ãŒã ããã ãšæããŸããçŠããªãã§ïŒæ¬¡ã«ä»¥äžã®ã³ãã³ããã¿ãŒããã«ã§å®è¡ããŠãã ããã
flutter pub run build_runner build --delete-conflicting-outputs
ããããåãéå±€ã«login_entity.freezed.dart
ãçæãããããšã確èªã§ããããšæããŸãã
ãããŸã§ããã颿°ãäœæããŸãããã£ããŸã§ãšåæ§ã«ãã°ã€ã³ã®é¢æ°ã§ãã
Future<String> login(LoginEntity entity) async {
try {
// ããã«èªèšŒåŠçããããšæ³å®ïŒAPIéä¿¡ãªã©ïŒ
print('ãã°ã€ã³äž: ${entity.email}');
return "ok";
} catch (e) {
return "ãšã©ãŒ";
}
}
颿°ãªãã§ã¯entity.email
ãentity.password
ã§åŒã³åºãããšã§ã¡ãŒã«ããã¹ã¯ãŒããåŒã³åºããŸãã
åãããäººã¯æ°ã¥ããŠããããšæããŸããåŒæ°ã®å®£èšãLoginEntity
ã ãã«ãªããŸããã
åŒã³åºããšãã¯ä»¥äžã®ããã«ãªãèš³ã§ãã
login(
LoginEntity(email: 'test@test.com', password: '123456'),
);
ãããããæååã§ã¯ãªãã£ãå Žåããã§ãšã©ãŒãã§ãã®ã§åãå®å
šãšãããŸãã
ãŸãLoginEntity
ã¯å¥ã®ãã¡ã€ã«ãªã®ã§ã°ããŒãã«ã«ç®¡çãã§ããŠä»ã®ãã¡ã€ã«ã§ããæ¡ãåãåå©çšã§ããèš³ã§ãã
ãã£ãããã£ãŠæããŸãããããããåå©çšã§ãããªããŠç°å¢ã«ãåªãã()ãšãæã£ãŠãããªãšæããŸãã
æåŸã«è¶
å®çšç·šãšããŠå®éã«APIéä¿¡ããçšã§Riverpod,Dio,Freezedã§ç°¡åã«éä¿¡ãããæ¹æ³ã玹ä»ããŸãã
å®çšçãªåå®å šâ¡ïŒè¶ å®çšç·š
ãããŸã§ãããã°å€ååå¿è
ã§ã¯ãªãäžçŽã¬ãã«ã«äžæ©è¶³ãèžã¿å
¥ãããšãã£ãŠãéèšã§ã¯ãªãã®ã§ããåå®å
šãã€å®çšçãªã³ãŒãã玹ä»ããŸãã
LoginEntity
ãAPIéä¿¡ã«å¯Ÿå¿ãããããïœFromJson`ã䜿çšããŸãã
ããã§ããã£ãã¡ãã£ãšåºãŠããJSONã®ãšã³ã³ãŒã/ãã³ãŒãã«äœ¿ã䟿ããªãã€ã§ãã
APIéä¿¡ã¯åºæ¬çã«JSONã§ããåããããããã«äœ¿çšããŸãã
import 'package:freezed_annotation/freezed_annotation.dart';
part 'login_entity.freezed.dart';
part 'login_entity.g.dart';
class LoginEntity with _$LoginEntity {
const factory LoginEntity({
required String email,
required String password,
}) = _LoginEntity;
factory LoginEntity.fromJson(Map<String, dynamic> json) => _$LoginEntityFromJson(json);
}
ããã§æ¥œã«JSONã®ãšã³ã³ãŒã/ãã³ãŒããããã€ã€åãå®å šã«äœ¿ããŸãã
Dioã䜿ã£ãŠãã°ã€ã³APIåŒã³åºã
Flutterã§ã¯éåžžAPIéä¿¡ã«ã¯Dioãšããããã±ãŒãžã䜿çšããŸãã
ãã®ããã±ãŒãžã䜿ãã°ãšã©ãŒãã³ããªã³ã°ãç°¡åã«è¡ãããšãã§ããããã«ãªããŸãã
import 'package:dio/dio.dart';
class Endpoint {
final Dio _dio;
Endpoint(this._dio);
Future<String> login(LoginEntity entity) async {
try {
final response = await _dio.post(
'/login',
data: entity.toJson(),
);
return response.data['token'] as String;
} catch (e) {
throw Exception('ãã°ã€ã³å€±æ: $e');
}
}
}
GPTå çïŒ
entity.toJson() ã§åå®å šã«JSON倿ã
â åãåã£ãŠããªããšãããã§èªåçã«ãšã©ãŒã«ãªãïŒ
ãšã®ããšã§ããããããšã§å®å šã«ãã°ã€ã³åŠçãå¯èœã«ãªããŸãã
Riverpod 2.0:èªåçæã䜿ã£ãŠç¶æ 管ç
Flutterã§ã®ãããžã§ã¯ãã®å€ãã¯Riverpodã§ç¶æ
管çãè¡ããŸããç¶æ
管çã«ã€ããŠã¯ãŸãä»åºŠæ°ãåãã°ã¢ããã³ãã«ã¬ã³ããŒã§ãããŸãã
ãŸãdioãæäŸããproviderãå®çŸ©
final dioProvider = Provider((ref) => Dio(BaseOptions(baseUrl: 'https://api.example.com')));
次ã«EndpointãæäŸ
final endpointProvider = Provider((ref) => Endpoint(ref.watch(dioProvider)));
æåŸã«ãã°ã€ã³ãããããã®providerãå®çŸ©ããã°å®äºã§ã
import 'package:flutter_riverpod/flutter_riverpod.dart';
part 'login_controller.g.dart';
class LoginController extends _$LoginController {
FutureOr<void> build() {}
Future<void> login(LoginEntity entity) async {
state = const AsyncLoading();
try {
final endpoint = ref.read(endpointProvider);
final result = await endpoint.login(entity);
state = AsyncData(result);
} catch (e, st) {
state = AsyncError(e, st);
}
}
}
äœ¿ãæ¹
ref.read(loginControllerProvider.notifier).login(
LoginEntity(email: 'test@test.com', password: '123456'),
);
ãã®ã³ãŒãããã°ã€ã³ãã¿ã³ã®æŒäžæãªã©ã«äœ¿ãã°ãã°ã€ã³ãã§ããããã«ãªããŸãã
ãŸãšã
ãåãããããšã§å®å
šããã€ãéçºè
ã®ãã¹ãæžãããšããããšãããã£ããšæããŸãã
å®çšçãªåå®å
šâ¡ã«ã€ããŠã¯äžéšè¶£æšãšã¯éžããŠããæ°ãããã®ã§å°ãé©åœãªéšåããããšããããŸãããŸããã®èšäºãGPTããã«æããŠèª¬æããŠããã£ãŠãã ãã(ç¬)
èªãåããå°ãåå®å šã«ã€ããŠè©³ãããªã£ãŠããã°å¹žãã§ãã
ãœã¡ãœã¡ã®ã€ã©ãGW Advent(?) Calendar ïŒæ¥ç®ã¯åå®å šæ§ã«ã€ããŠå匷ããŸããïŒ
Discussion