subindev 님의 블로그

[Flutter] #13 HTTP 요청 헬퍼 - Dio 패키지 본문

카테고리 없음

[Flutter] #13 HTTP 요청 헬퍼 - Dio 패키지

subindev 2025. 1. 21. 10:04

Dio 패키지 사용해 보기

https://pub.dev/packages/dio/install

 

dio install | Dart package

A powerful HTTP networking package, supports Interceptors, Aborting and canceling a request, Custom adapters, Transformers, etc.

pub.dev

 


1. pubspec.yaml 파일 설정

Dio 패키지를 사용하려면 프로젝트의 pubspec.yaml 파일에 아래 내용을 추가합니다.

dependencies:
  dio: ^5.7.0

설정 후, 다음 명령어를 실행합니다.

flutter pub get

 


 

2. Dio 사용 예제 코드

 

전체 코드

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: SafeArea(
        child: Scaffold(
          body: HomePage(),
        ),
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State createState() => _HomePageState();
}

class _HomePageState extends State {
  // Dio 객체 생성
  Dio _dio = Dio();
  // 서버에서 받은 데이터를 저장할 변수
  Todo? _todo;

  @override
  void initState() {
    super.initState();
    // 앱 실행 시 데이터를 가져오는 메서드 호출
    _fetchTodos();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: _todo == null
          ? CircularProgressIndicator() // 데이터 로드 중일 때 로딩 표시
          : Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text('ID : ${_todo!.id}'),
                Text('UserID : ${_todo!.userId}'),
                Text('Title : ${_todo!.title}'),
                Text('Completed : ${_todo!.completed}'),
              ],
            ),
    );
  }

  // 데이터를 가져오는 메서드
  Future _fetchTodos() async {
    try {
      // 서버에 GET 요청을 보냄
      Response response =
          await _dio.get('https://jsonplaceholder.typicode.com/todos/1');
      // JSON 데이터를 Todo 객체로 변환
      _todo = Todo.fromJson(response.data);
      // UI 갱신
      setState(() {});
    } catch (e) {
      print('오류 발생: $e');
    }
  }
}

// Todo 모델 클래스
class Todo {
  int? userId;
  int? id;
  String? title;
  bool? completed;

  Todo({
    required this.userId,
    required this.id,
    required this.title,
    required this.completed,
  });

  // JSON 데이터를 객체로 변환하는 생성자
  Todo.fromJson(Map<string, dynamic=""> json)
      : userId = json['userId'],
        id = json['id'],
        title = json['title'],
        completed = json['completed'];

  @override
  String toString() {
    return 'Todo{userId: $userId, id: $id, title: $title, completed: $completed}';
  }
}
</string,>

 

 


 

3. 주요 코드 설명

 

(1) Dio 객체

  • HTTP 요청을 처리하는 객체로, GET/POST 요청을 간단히 처리할 수 있습니다.
  • 위 코드에서는 _dio.get() 메서드를 사용해 데이터를 가져옵니다.

(2) JSON 데이터를 Dart 객체로 변환

  • 서버에서 받은 JSON 데이터를 Todo 클래스의 fromJson 생성자를 이용해 변환.
  • 예) 
  • Todo todo = Todo.fromJson(response.data);
    

(3) 비동기 처리

  • await 키워드로 비동기적으로 데이터를 가져오고, 완료되면 UI를 업데이트합니다.
  • 데이터 로딩 중에는 CircularProgressIndicator로 로딩 상태를 보여줍니다.

(4) 예외 처리

  • try-catch를 사용해 네트워크 오류를 대비.
  • 오류 발생 시, 콘솔에 에러 메시지를 출력합니다.

 


 

4. 실행 결과

  1. 로딩 상태: 데이터를 가져오는 동안 로딩 아이콘(CircularProgressIndicator) 표시.
  2. 데이터 출력:
    ID : 1
    UserID : 1
    Title : delectus aut autem
    Completed : false
    

 

5. 활용 팁

 

  1. Base URL 설정:
    • 여러 API 요청 시, 기본 URL을 설정하면 매번 URL을 입력하지 않아도 됩니다.
    BaseOptions options = BaseOptions(baseUrl: 'https://jsonplaceholder.typicode.com/');
    Dio dio = Dio(options);
    
  2. 인터셉터:
    • 요청 또는 응답 시 로깅이나 추가 작업을 수행할 수 있습니다.
    dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) {
        print('요청 보냄: ${options.uri}');
        return handler.next(options);
      },
      onResponse: (response, handler) {
        print('응답 받음: ${response.data}');
        return handler.next(response);
      },
      onError: (DioError e, handler) {
        print('에러 발생: ${e.message}');
        return handler.next(e);
      },
    ));
    
  3. POST 요청:
    • 데이터를 서버로 전송하는 POST 요청 예:
    Response response = await dio.post(
      '/todos',
      data: {'title': 'New Todo', 'completed': false},
    );