본문 바로가기
Flutter

Flutter http 서버 연동하기

by ksb0511 2022. 1. 3.

Retrofit 을 포스팅하고 바로 http 서버 연동을 포스팅해야지 라고 생각했는데 벌써 시간이 꽤 흘렀네요..ㅎ

 

까먹지 않기 위해 http 서버 연동을 포스팅해보려고 합니다.

 

저는 개인적으로 retrofit보다 http가 편했어요. 안드로이드 개발할 때 retrofit을 워낙 많이 해보다 보니 그게 더 익숙할 거라 생각했는데 개인적으로 flutter(웹) 쓸 때 http가 훨씬 편하고 간단했습니다. 나중에 기회가 된다면 비교하는 포스팅을 해보고 싶네요 아직 그런 글이 없는 것 같거든요😊 저만 궁금한가봐요...

 

일단 들어가기 앞서 패키지는 아래 링크에서 확인이 가능합니다

https://pub.dev/packages/http

 

http | Dart Package

A composable, multi-platform, Future-based API for HTTP requests.

pub.dev

당연히 가장 먼저 해야할 것은 pubspec.yaml 파일에 dependencies 부분에 추가하는 것입니다.

http: ^0.13.2

저는 0.13.2이지만 최신 버전을 쓰세요

저한테는 저게 최신이었습니다.

 

아 그리고 까먹을 뻔했는데 convert랑 async도 같이 추가시켜주세요. http 서버 연결할 때 유용할거에요

https://pub.dev/packages/convert

 

convert | Dart Package

Utilities for converting between data representations. Provides a number of Sink, Codec, Decoder, and Encoder types.

pub.dev

https://pub.dev/packages/async

 

async | Dart Package

Utility functions and classes related to the 'dart:async' library.

pub.dev

 

간단히 어디에 쓰이는 지 말하자면 convert는 말그대로 

이런 뜻인걸 보니.. 뭐 json 인코딩같은거 할때 필요하겠죠?

 

그리고 async는 javascript하셨던 분들은 잘 아시겠지만 비동기때문에 필요한겁니다. 저는 javascript를 할 줄 몰라서 찾아봤어요.ㅎ

 

아무튼 이정도 하고 빠르게 서버 연결을 위한 함수를 만들어 보겠습니다.

retrofit처럼.. 뭐 복잡할게 1도 없습니다.

 

함수가 아니라 그냥 내부에 코드 구현하고 싶은 사람은 그러셔도 돼요. 다만 저는 메인 코드도 너무 길어서 함수로 만들었습니다.

Future<String> refreshToken(context, String? refresh_token) async {
  final uri = Uri.parse(base_url + '/refreshToken'); // 자신의 url을 넣어주세요

  // 서버에 전송할 데이터를 넣어주세요.
  // 저는 json으로 보내야했기에 jsonEncode라고 적고 그 안에 쓴거고 이때 convert 패키지가 필요한 겁니다.
  final map = jsonEncode({
    "id": "id",
  });

  // 헤더가 없는 사람은 생략해도 돼요. 저는 넣어야 할 것도 있었고 Content-Type이랑 Accept도 혹시 몰라서 적었어요.
  Map<String, String> headers = {
    'Content-Type' : 'application/json',
    'Accept' : 'application/json',
    'user-id' : user_id!,
    'Authorization' : "Bearer "+refresh_token!
  };

  // 대망의 POST입니다. 여지껏 위에서 차례로 선언해둔 상수, 변수들을 넣어줍니다.
  http.Response response = await http.post(
    uri,
    headers: headers,
    body: map,
  );

  // 이것은 제가 임의로 만들었어요. 쓸모없음. 이렇게 확인할 수 있습니다.
  if(response.statusCode>=200 && response.statusCode<300) {
    print("성공");
  }
  else {
    print("실패");
  }

  return response.body; //가져올 데이터인 String 값을 리턴
}

제가 진행했던 프로젝트에서 썼던 코드라 지극히 제 맘대로 짠 코드임을 감안해주세요.

독학한거라 눈치껏 짰습니다.

 

일단 이 함수 설명부터 간단히 하자면 이 코드는 제가 refreshToken 재발급받을 때 만들었던 함수입니다.

 

자 함수 만들기 끝입니다. 너무 간단해요.

 

이제 그냥 사용만 해주면 됩니다.

이미 자신이 만들어둔 위젯이 있을 거에요. 그 위젯에 서버를 연결시키고 싶은거겠죠..?

 

참고로 다 아시겠지만 서버로 값을 받는다는 의미는 가변상태이어야 하기에 Stateless Widget은 안됩니다. Stateful에서 하세요.

그리고 이제 사용은 FutureBuilder를 써야합니다. 필수에요. 아니면 나중에 사용할 때 에러남. (이유는 비동기 때문)

 

말보단 코드를 보여드리겠습니다. 이것도 제가 프로젝트 때 썼던 코드고 간소화했습니다.

return FutureBuilder(
    future: refreshToken(context, refresh_token),
    initialData: "", // 저는 초기데이터가 필요없어서 ""이렇게 설정했습니다.
    builder: (context, AsyncSnapshot snapshot){
      // 서버에서 값받아올 때까지 로딩 띄우기
      if (snapshot.connectionState == ConnectionState.waiting) 
        return Center(
          child: CircularProgressIndicator(),
        );

      // 저한텐 필요한 과정이었습니다...
      // snapshot.data가 바로 서버에서 받아온 데이터에요.
      if(snapshot.data==null){
        Navigator.pop(context);
      }
      
      // json 디코딩을 해주고 그 안에 있는 리스트까지 분리시켰습니다.
      // 끝! 위젯은 생략했어요 재량껏 UI 구성하시길... 활용만 하심 됩니다..
      var refresh = jsonDecode(snapshot.data);
      access_token = refresh['access_token'];
      
    }
);

아마 이 코드 보시면 그냥 충분히 이해가 되실거에요. 너무너무 간단하죠..?

 

하지만 저도 수십번의 실패를 거쳐서 했습니다..

 

서버 연결할 때 정말 많은 고충이 있었는데 한글 깨짐, 사진 받아오기 등 그것도 한번 포스팅 해볼게요~

 

댓글