반응형
앱이 서버와 데이터 주고받는 법
- Flutter에서 GET, POST 요청을 하는 방법
- pubspec.yaml의 dependencies에 아래 코드 추가 후 Pub get 클릭해서 설치하기
dependencies:
flutter:
sdk: flutter
http: ^0.13.4
- 이후 android/app/src/main/AndroidManifest.xml 파일에 코드 삽입
- 해당 코드는 인터넷 사용 허락에 대한 코드
- 안드로이드만 설치가 필요하고 IOS는 별도 설치가 필요하지 않다고 함
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.instagram" > <uses-permission android:name="android.permission.INTERNET" />
- 마지막으로 main.dart 파일의 상단에 import 해오기
import 'package:http/http.dart' as http;
import 'dart:convert';
- 이제 요청을 해볼 텐데
- 앱이 로드 되었을 경우 바로 요청을 해 데이터를 뿌리기 위해 initState() 위젯을 사용하기
- 여기서 get 요청을 하는 코드는 아래와 같다.
- http.get(Uri.parse('API주소'));
- 요청한 데이터는 변수에 담아 변수.body를 해야 볼 수 있다.
- 다만 함수 실행 보다 출력 또는 처리하는 로직이 더 빠르기에 비동기 통신으로 async, await을 처리하려고 하지만
- initState는 async, await 처리를 할 수 없다.
- 그래서 initState() 밖에 비동기 통신 함수를 작성 후 안에 추가하게 되면 의도대로 실행 됨.
getData() async{
var result = await http.get(Uri.parse('경로'));
print(result.body);
}
@override
void initState() {
super.initState();
getData();
}
- 그런데 받아온 데이터는 JSON 자료형이기에 jsonDecode를 사용해 사용할 수 있게 변형해주기
- jsonDecode(result.body)
숙제
경로로 부터 받아온 데이터를 뿌리고 빈 배열로 생기는 에러 또한 함께 처리하기
- 에러 해결의 경우엔 현재 homeData의 개수에 맞게 출력을 하도록 하니 잘 해결 되었다.
import 'package:flutter/material.dart';
import './style.dart' as style;
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() {
runApp(
MaterialApp(
theme: style.theme,
home: MyApp()
)
);
}
class MyApp extends StatefulWidget {
MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
var homeData = [];
getData() async{
var result = await http.get(Uri.parse('경로'));
setState(() {
homeData = jsonDecode(result.body);
});
}
@override
void initState() {
super.initState();
getData();
}
// 0: home, 1: shop
var tab = 0;
changeTab(tabNumber){
setState(() {
tab = tabNumber;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Instagram'),
actions: [
IconButton(
onPressed: (){},
icon: Icon(Icons.add_box_outlined)
)
],
),
body: [Home(homeData:homeData),Text('shop')][tab],
bottomNavigationBar: BottomNavigationBar(
onTap: (i){
changeTab(i);
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.shopping_bag_outlined),
label: 'Shopping',
),
],
showSelectedLabels: false, // 선택된 아이템의 레이블 숨김
showUnselectedLabels: false, // 선택되지 않은 아이템의 레이블 숨김
),
);
}
}
class Home extends StatelessWidget {
Home({super.key, this.homeData});
final homeData;
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: homeData.length,
itemBuilder: (context, idx){
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.network(homeData[idx]['image']),
Container(
margin: EdgeInsets.fromLTRB(10, 20, 10, 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text('좋아요', style: TextStyle(fontSize: 15, fontWeight: FontWeight.w700),),
Text(homeData[idx]['likes'].toString(), style: TextStyle(fontSize: 15, fontWeight: FontWeight.w700)),
],
),
Text(homeData[idx]['date'].toString()),
Text(homeData[idx]['content'].toString()),
],
),
)
],
);
},
);
}
}
'Flutter' 카테고리의 다른 글
[Flutter] 스크롤 위치 파악 & 무한 스크롤 (0) | 2023.08.10 |
---|---|
[Flutter] Future 다루기 & FutureBuilder (0) | 2023.08.09 |
[Flutter] 탭으로 페이지 나누는 법 (사진 추가, ListView) (0) | 2023.08.09 |
[Flutter] Theme 파일 분리와 추가 내용 (0) | 2023.08.08 |
[Flutter] 프로젝트 설치 & ThemeData로 스타일 분리하는 방법 (0) | 2023.08.08 |