목차

  1. JSON 데이터 불러오기
    1. JSON 파일 생성
    2. yaml 파일에 assets 추가 (폴더명/파일명)
    3. main.dart 작성
  2. 코드 추가 설명

 

 

 

✅ JSON 데이터 불러오기

 

 

 

1️⃣ JSON 파일 생성

  1. JSON 파일 생성하여 List 타입의 데이터 작성

 

 

2️⃣ yaml 파일에 assets 추가 (폴더명/파일명)

  1. pubspec.yaml 파일 내에 assets 부분에 JSON 파일 추가

 

3️⃣ main.dart 작성

  1. Future 타입의 메소드 작성 (** import도 필수로 적용시키기)
  2. 작성한 메소드를 변수에 담기
  3. FutureBuilder  코드 작성
  4. 정상 작동 확인

1. Future 타입의 메소드 작성 (** import도 필수로 적용시키기) / 2. 작성한 메소드를 변수에 담기
3. FutureBuilder  코드 작성
4. 정상 작동 확인

 

 

 

 

✅ 코드 추가 설명

  • Future : 나중에 값이 올 것을 약속하는 객체
    • 예를 들어 지금 당장 결과가 있는 게 아니라 “곧 결과를 줄게” 라는 약속을 담고 있음
    • 그래서 Future<T> 라고 쓰면 T 타입의 값을 나중에 돌려주겠다는 뜻
      여기서는 Future loadJson() → JSON 데이터를 나중에 돌려줄 거야

  • async : 함수 앞에 붙어 비동기 실행을 시키는 키워드
    • 이 함수 안에는 비동기 작업이 들어있다는 의미
    • async 가 붙으면 함수는 자동으로 Future 를 반환하게 됨

  • await : 비동기 작업이 끝날 때까지 기다리라는 명령어
    • await 는 무조건 async 함수 안에서만 사용 가능

  • rootBundle : Flutter 앱 안에 포함된 assets(정적 리소스)에 접근하기 위한 도구
    • pubspec.yaml 에 등록한 assets/ 나 lib/users.json 같은 파일들을 불러올 때 사용
    • rootBundle.loadString("경로") → 해당 경로의 파일을 문자열(String) 로 읽어옴

  • snapshot : FutureBuilder 가 Future 의 상태 + 결과 데이터를 한꺼번에 담아주는 객체
    • 구성요소
      1. snapshot.hasData : Future 실행이 끝나고 데이터가 성공적으로 도착했는지 여부 (true/false)
      2. snapshot.data : Future 가 성공했을 때 가져온 실제 데이터 (예: JSON 리스트, API 응답 값)
      3. snapshot.hasError : Future 실행 중 에러가 발생했는지 여부 (true/false)
      4. snapshot.error : 실제 발생한 에러 객체

 

 

 

 

 

 

 

✔️ 사용된 코드

class _MyHomePageState extends State<MyHomePage>{

  // Future : 나중에 완료될 작업의 결과를 표현하는 객체(API, JSON, 이미지 등 호출 시 사용)
  // async : 비동기 데이터 불러올 때 사용
  static Future loadJson() async{
    final String response = await rootBundle.loadString("lib/users.json");
    final data = await json.decode(response);
    return data['users'];   // ['users']를 입력해야 json에 저장한 users 내부 데이터를 불러옴
  }

  Future userList = loadJson(); // loadJson() 메소드를 변수에 담기

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Test App"),
      ),
      body: Container(
        child: FutureBuilder(
          future: userList,   // 여기에 데이터가 들어감
          builder: (context, snapshot) {
            if(snapshot.hasData){   // snapshot에 데이터가 있으면
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (context, index){
                  return Container(
                    margin: EdgeInsets.all(15),
                    child: Text("${snapshot.data[index]['id']} : ${snapshot.data[index]['username']} / ${snapshot.data[index]['email']}"),
                  );
                },
              );
            }else if(snapshot.hasError){  // snapshot이 에러인 경우
              return Center(child: Text("Error"),);
            }else{  // 그 외 상황이라면
              // CircularProgressIndicator : 로딩 화면에서 동그라미가 돌아가는 것
              return Center(
                child: CircularProgressIndicator(
                  strokeWidth: 2,     // 돌아가는 로딩 동그라미 선의 굵기
                ),
              );
            }
          },
        )
      ),
    );
  }
}

+ Recent posts