[Flutter] 서버와 데이터 주고 받기

멋진감자·2025년 7월 17일
0

Flutter

목록 보기
15/25
post-thumbnail

서버

  • method(GET/POST), url 주면서 데이터 달라하면 주는 프로그램
  • url은 서버 개발한 넘한테 묻/달라하기
  • 서버 개발은 nodejs나 firebase 참고

GET

데이터 읽고 싶을 때

POST

데이터 보내고 싶을 때

테스트

강의 상 임시 서버로 GET 요청을 날려보자

패키지 설치

  • pubspec.yaml > dependencies 밑에 http: ^버전
  • pub get (전구)

AndroidManifest.xml

android > app > src > main > AndroidManifest.xml <application 앞에
<uses-permission android:name="android.permission.INTERNET" /> 작성

main.dart

맨 위에 아래 두 줄 추가

import 'package:http/http.dart' as http;
import 'dart:convert';

GET 요청 보내기

  • MyApp 위젯이 로드될 때 GET 요청하도록 initState(){} 생성
  • GET 요청은 시간이 걸리므로 넘어가지 않도록 await 필요
  • 근데 initState에 async 못 붙이니까 GET 함수 따로 빼기
getData() async {
  var result = await http.get(
    Uri.parse('서버URL'),
  );
  print(result.body);
}


void initState() {
  super.initState();
  getData();
}

jsonDecode()

  • 큰따옴표로 묶어서 문자처럼 사기친 상태
  • jsondecode로 가공 편하게 변환 ex) print(jsonDecode(result.body));

예외 처리

1. null data

에러 메세지

NoSuchMethodError: '[]'
Dynamic call of null.
Receiver: null
Arguments: [0]

원인

  1. data가 아직 로딩되지 않은 상태 (null/빈 리스트)에서 data[i]에 접근해서
  2. initState에서 비동기 함수 getData()가 실행중일 때, build()가 먼저 호출

해결

data == null 또는 data.isEmpty 체크

return data == null
  ? CircularProgressIndicator()
  : ListView.builder(

혹은

if (data.isNotEmpty) {
  return ListView.builder(
  // (생략)
} else {
  return CircularProgressIndicator()

2. !isDisposed

에러 메세지

Assertion failed: !isDisposed
"Trying to render a disposed EngineFlutterView."

원인

동기 작업이 완료되었을 때 위젯이 이미 dispose(unmount)된 경우
위젯이 unmount(dispose) 된 후에도 setState()가 호출되면 문제가 됨

void loadData() async {
  var result = await http.get(Uri.parse('서버URL'));
  setState(() {  // ❗ 요때 위젯이 dispose되었을 수 있음
    data = jsonDecode(result.body);
  });
}

해결

getData() async {
  var result = await http.get(Uri.parse('서버URL'));
  if (!mounted) return;
  setState(() {
    data = jsonDecode(result.body);
  });
}

3. 서버 다운 / 요청 경로 문제 등

getData() async {
  var result = await http.get(Uri.parse('서버URL'));
  if (result.statusCode == 200) { 요청 성공 시 실행 코드 }
  else { 실패 시 실행 코드 }
}

그 외

Dio

조금 더 짧은 코드로 GET 요청 가능한 패키지

FutureBuilder()

Future()를 뱉는 애들을 넣을 수 있는데 데이터가 자꾸 추가되면 사용하기 불편함

ex) body: [FutureBuilder(future: data, builder: (){}), ...],

list, map

map 안에 map, list 안에 list 등 모든 자료형을 넣기 가능

list

  • 형태: [자료1, 자료2...]
  • 읽기: list이름[0]
  • 결과: 자료1

map

  • 형태: {'이름1': 자료1, '이름2': 자료2...}
  • 읽기: map이름['이름1']
  • 결과: 자료1
profile
난멋져

0개의 댓글