main.dart
import 'package:flutter/material.dart';
import 'package:webtoon_app/screens/home_screen.dart';
import 'package:webtoon_app/services/api_service.dart';
void main() {
ApiService().getTodaysToons();
runApp(const App());
}
class App extends StatelessWidget {
const App({super.key}); // 이 위젯의 key를 stateless widget이라는 슈퍼클래스에 보낸다.
// 위젯은 key라는 걸 가지고 있고 ID처럼 쓰인다.
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomeScreen(),
);
}
}
services/api_service.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:webtoon_app/models/webtoon_model.dart';
class ApiService {
static const String baseUrl =
"<https://webtoon-crawler.nomadcoders.workers.dev>";
static const String today = "today";
// api요청을 하기 위해서 웹에서 fetch나 axios를 사용하는 것처럼 http 모듈을 사용해주자!
Future<List<WebtoonModel>> getTodaysToons() async {
List<WebtoonModel> webtoonInstances = [];
final url = Uri.parse('$baseUrl/$today');
final response = await http.get(url);
// 데이터가 올 때까지 잠깐 멈춰야될 때가 있을 때 사용한다.
// await으로 future가 완료될 때까지 기다린다.
if (response.statusCode == 200) {
final List<dynamic> webtoons = jsonDecode(response.body);
// 텍스트로 응답된 body를 JSON으로 디코딩해준다.
// dynamic으로 반환값이 나와서 type지정해주는게 좋음
for (var webtoon in webtoons) {
final toon = WebtoonModel.fromJson(webtoon);
webtoonInstances.add(toon);
print(webtoon);
}
return webtoonInstances;
}
throw Error();
}
}
models/webtoon_model.dart
class WebtoonModel {
final String title, thumb, id;
WebtoonModel.fromJson(Map<String, dynamic> json)
: title = json['title'],
thumb = json['thumb'],
id = json['id'];
// Map<String, dynamic>은 TS로 따지면 key값이 String value값이 any이다.
// named constructor라고 하고 이름이 있는 클래스 constructor
}
screens/home_screen.dart
import 'package:flutter/material.dart';
import 'package:webtoon_app/models/webtoon_model.dart';
import 'package:webtoon_app/services/api_service.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<WebtoonModel> webtoons = [];
bool isLoading = true;
void waitForWebtoons() async {
webtoons = await ApiService().getTodaysToons();
isLoading = false;
}
@override
void initState() {
super.initState();
waitForWebtoons();
}
@override
Widget build(BuildContext context) {
print(webtoons);
print(isLoading);
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 2,
title: const Text("오늘의 웹툰",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.w500)),
backgroundColor: Colors.white,
foregroundColor: Colors.green,
),
);
}
}