본문 바로가기

카테고리 없음

[Flutter_개발] Flutter 숙련 이론 강의 정리

1. 데이터 통신의 기초와 JSON

서버와 앱 간의 데이터 교환은 직렬화(Serialization) 과정을 통해 이루어진다.

  • 직렬화(Serialization): Dart 객체 → Map → JSON 문자열로 변환
  • 역직렬화(Deserialization): JSON 문자열 → Map → Dart 객체로 변환

이 과정을 통해 서로 다른 언어로 작성된 시스템(예: Java 서버와 Flutter 클라이언트) 간에도 데이터를 주고받을 수 있다

챕터1-1 데이터 통신 기초와 JSON

.

JSON의 기본 구조는 {key: value} 쌍이며, value에는 다음 타입이 올 수 있다.
String, Number, Boolean, Array, Object, null

Dart에서는 dart:convert 패키지의 jsonEncode, jsonDecode 함수를 이용해 변환을 수행한다.

  • jsonEncode(Map) → JSON 문자열
  • jsonDecode(String) → Map<String, dynamic> 또는 List<dynamic>

Map을 거치는 이유는 Dart 객체를 직접 문자열로 바꾸는 것은 복잡하기 때문에, 중간에 Map 형태로 변환한 후 라이브러리로 처리하는 것이다

챕터1-1 데이터 통신 기초와 JSON

.

2. JSON 실습 — Dart 객체 변환

Dart에서는 JSON 데이터를 다루기 위해 클래스를 정의하고 fromJson, toJson 메서드를 구현한다.

class User {
  String name;
  int age;

  User({required this.name, required this.age});

  User.fromJson(Map<String, dynamic> json)
      : this(name: json['name'], age: json['age']);

  Map<String, dynamic> toJson() => {"name": name, "age": age};
}
 

이런 구조를 사용하면 단순한 Map보다 오타를 줄이고 타입 안정성을 높일 수 있다

복잡한 JSON은 클래스 안에 또 다른 클래스를 포함시켜 처리한다.
예를 들어 Pet 안에 Contact 객체를 포함시키면, 중첩된 구조를 모델링할 수 있다.
서버 데이터 → Map → 객체로 변환 → UI에서 활용이라는 데이터 흐름을 직접 경험했다.

3. MVVM 아키텍처

MVVM은 Model-View-ViewModel의 약자로, Flutter 앱 구조를 체계적으로 관리하기 위한 설계 패턴이다

  • Model : 데이터 계층 (예: JSON으로 받은 User, Pet 등)
  • View : UI 계층 (예: 위젯 화면)
  • ViewModel : View와 Model 사이에서 데이터를 가공하고 상태를 관리하는 계층

StatefulWidget에서는 하나의 클래스가 UI, 로직, 상태 관리를 모두 담당해 코드가 복잡해진다.
반면 MVVM은 이 역할을 분리해 코드의 가독성과 유지보수성을 높인다.

→ View는 ViewModel을 구독하고(ViewModel의 상태 변화를 감시),
→ ViewModel은 Model에서 데이터를 가져와 상태를 갱신한다.
이렇게 의존성이 낮은 구조가 되어 테스트와 확장이 쉬워진다.

4. RiverPod — 상태 관리 패키지

MVVM에서 ViewModel의 역할을 돕는 라이브러리가 RiverPod이다

.

핵심 개념

  • Notifier : 상태를 저장하고 변경을 알리는 객체 (ViewModel의 역할)
  • NotifierProvider : ViewModel을 위젯에 공급하는 관리자
  • Consumer 위젯 : Provider로부터 상태를 구독해 화면을 업데이트
class HomeState {
  int counter;
  HomeState(this.counter);
}

class HomeViewModel extends Notifier<HomeState> {
  @override
  HomeState build() => HomeState(1);

  void updateState() {
    state = HomeState(state.counter + 1);
  }
}

final homeViewModelProvider =
    NotifierProvider<HomeViewModel, HomeState>(() => HomeViewModel());

View에서는 Consumer 위젯 안에서 ref.watch(homeViewModelProvider)로 상태를 구독하고,
ref.read(homeViewModelProvider.notifier)로 ViewModel 메서드를 호출할 수 있다.
이렇게 하면 상태 변화 → 자동 UI 갱신이 자연스럽게 이루어진다.

5. RiverPod 실습 — User 정보 가져오기

실습에서는 버튼 클릭 시 서버에서 JSON 데이터를 받아오는 시나리오를 구현했다

구조 요약

  • User 클래스 : 데이터 모델
  • UserRepository : 서버 통신(가상) → JSON → 객체 변환
  • HomeViewModel : Notifier 상속, getUserInfo() 메서드로 상태 갱신
  • HomeState : 현재 user 정보와 fetch 시간 보관
  • Consumer : View에서 ViewModel 상태 구독 및 UI 반영
 
HomeState homeState = ref.watch(homeViewModelProvider);
HomeViewModel viewModel = ref.read(homeViewModelProvider.notifier);

이 구조를 통해 Flutter 위젯 내부에서 비즈니스 로직을 분리하고,
데이터의 흐름이 Repository → ViewModel → View로 깔끔히 이어지도록 만들 수 있었다.


6. RiverPod의 장점 및 확장형 구조

마지막으로 다양한 Notifier 형태를 학습했다

Notifier는 앱 전역에서 지속적으로 유지되는 상태 관리에 사용되고,
AutoDisposeNotifier는 위젯이 사라질 때 상태가 자동으로 해제된다.
AutoDisposeFamilyNotifier는 ViewModel에 특정 값을 전달하여 상황에 따라 새로운 상태를 생성할 수 있다.

예를 들어, 로그인 시 사용자 정보처럼 전역적으로 유지되어야 하는 상태는 Notifier로,
회원가입 페이지 입력값처럼 일시적인 데이터는 AutoDisposeNotifier로,
게시글 상세 페이지처럼 ID에 따라 상태가 달라지는 경우는 AutoDisposeFamilyNotifier로 관리한다.

이 구조 덕분에 앱의 메모리를 효율적으로 관리하고, 각 화면의 생명주기에 맞춰 상태를 유연하게 유지·초기화할 수 있다.


정리

이번 학습을 통해 Flutter 앱의 핵심 구조를 다음과 같이 체계적으로 이해했다.

  • JSON을 통한 데이터 직렬화 / 역직렬화 원리
  • MVC보다 명확한 MVVM 설계 패턴 구조
  • RiverPod을 활용한 효율적인 상태 관리 및 의존성 분리

즉, 데이터의 흐름이
서버(JSON) → Model → ViewModel(RiverPod) → View(Widget)
으로 이어지는 전체 구조를 한 눈에 파악할 수 있게 되었고,
이는 앞으로 더 복잡한 Flutter 앱에서도 안정적이고 유지보수하기 쉬운 코드 작성을 위한 중요한 기반이 되었다.