네트워킹 - HTTP를 통한 데이터 가져오기 및 보내기
이번 강의에서는 Flutter에서 네트워킹을 처리하는 방법을 배워보겠습니다. HTTP를 통해 데이터를 가져오고 보내는 것은 대부분의 모바일 애플리케이션에서 중요한 기능입니다. 이 강의에서는 http 패키지를 사용하여 REST API와 상호작용하는 방법을 다룹니다.
http 패키지 설치
먼저, http 패키지를 설치해야 합니다. pubspec.yaml 파일에 http 패키지를 추가합니다.
dependencies:
flutter:
sdk: flutter
http: ^0.13.3
터미널에서 flutter pub get 명령을 실행하여 패키지를 설치합니다.
GET 요청으로 데이터 가져오기
GET 요청을 사용하여 서버에서 데이터를 가져오는 방법을 살펴보겠습니다.
JSONPlaceholder API 사용하기
JSONPlaceholder는 테스트용으로 사용할 수 있는 무료 API입니다. 여기서 제공하는 API를 사용하여 데이터를 가져오겠습니다.
데이터 모델 정의하기
먼저, 데이터를 저장할 모델 클래스를 정의합니다.
class Post {
final int userId;
final int id;
final String title;
final String body;
Post({
required this.userId,
required this.id,
required this.title,
required this.body,
});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
userId: json['userId'],
id: json['id'],
title: json['title'],
body: json['body'],
);
}
}
GET 요청 보내기
이제 http 패키지를 사용하여 GET 요청을 보내고 데이터를 가져옵니다.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('HTTP GET 예제'),
),
body: PostsScreen(),
),
);
}
}
class PostsScreen extends StatefulWidget {
@override
_PostsScreenState createState() => _PostsScreenState();
}
class _PostsScreenState extends State<PostsScreen> {
late Future<List<Post>> futurePosts;
@override
void initState() {
super.initState();
futurePosts = fetchPosts();
}
Future<List<Post>> fetchPosts() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
if (response.statusCode == 200) {
List jsonResponse = json.decode(response.body);
return jsonResponse.map((post) => Post.fromJson(post)).toList();
} else {
throw Exception('Failed to load posts');
}
}
@override
Widget build(BuildContext context) {
return Center(
child: FutureBuilder<List<Post>>(
future: futurePosts,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data![index].title),
subtitle: Text(snapshot.data![index].body),
);
},
);
}
},
),
);
}
}
POST 요청으로 데이터 보내기
POST 요청을 사용하여 서버에 데이터를 보내는 방법을 살펴보겠습니다.
데이터 보내기
이번에는 새로운 게시물을 생성하기 위해 POST 요청을 보냅니다.
Future<Post> createPost(Post post) async {
final response = await http.post(
Uri.parse('https://jsonplaceholder.typicode.com/posts'),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
body: json.encode({
'title': post.title,
'body': post.body,
'userId': post.userId,
}),
);
if (response.statusCode == 201) {
return Post.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to create post');
}
}
POST 요청 예제
createPost 함수를 사용하여 새로운 게시물을 생성합니다.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('HTTP POST 예제'),
),
body: CreatePostScreen(),
),
);
}
}
class CreatePostScreen extends StatefulWidget {
@override
_CreatePostScreenState createState() => _CreatePostScreenState();
}
class _CreatePostScreenState extends State<CreatePostScreen> {
final TextEditingController _titleController = TextEditingController();
final TextEditingController _bodyController = TextEditingController();
late Future<Post> _futurePost;
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
TextField(
controller: _titleController,
decoration: InputDecoration(labelText: '제목'),
),
TextField(
controller: _bodyController,
decoration: InputDecoration(labelText: '본문'),
),
ElevatedButton(
onPressed: () {
setState(() {
_futurePost = createPost(Post(
userId: 1,
id: 0,
title: _titleController.text,
body: _bodyController.text,
));
});
},
child: Text('게시물 생성'),
),
FutureBuilder<Post>(
future: _futurePost,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
return Text('게시물 생성됨: ${snapshot.data!.title}');
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
}
return CircularProgressIndicator();
},
),
],
),
);
}
}
FAQ
Q: HTTP 요청에서 타임아웃을 설정할 수 있나요?
A: 네, http.Client를 사용하여 타임아웃을 설정할 수 있습니다. 예를 들어, http.Client().get(Uri.parse('url')).timeout(Duration(seconds: 10));와 같이 설정할 수 있습니다.
Q: JSON 데이터를 파싱하는 다른 방법이 있나요?
A: 네, json_serializable 패키지를 사용하면 코드 생성으로 JSON 파싱을 자동화할 수 있습니다. 이 방법은 더 간결하고 유지보수가 쉬운 코드를 작성하는 데 유용합니다.
Q: 데이터 요청 시 에러를 어떻게 처리하나요?
A: try-catch 문을 사용하여 HTTP 요청에서 발생하는 에러를 처리할 수 있습니다. 또한, FutureBuilder를 사용하여 비동기 작업의 상태에 따라 UI를 업데이트할 수 있습니다.
결론
이번 강의를 통해 Flutter에서 HTTP를 통해 데이터를 가져오고 보내는 방법을 배웠습니다. http 패키지를 사용하여 GET 및 POST 요청을 보내고, JSON 데이터를 파싱하는 방법을 익혔습니다. 실습을 통해 실제 애플리케이션에 네트워킹 기능을 구현해 보며, REST API와 상호작용하는 방법을 이해할 수 있었습니다. 다음 강의에서는 Firebase와 같은 백엔드 서비스를 사용하여 데이터를 저장하고 관리하는 방법을 알아보겠습니다. Flutter로 다양한 네트워킹 기능을 구현해 보세요!
댓글