zzangyeah 2023. 9. 29. 17:20
728x90

57강. HTTP 심화

HTTP

  • HTTP는 HTML문서와 같은 리소스들을 가져올 수 있도록 해주는 프로토콜
  • 프론트엔드에서는 반드시 HTTP 요청을 보낼 수 있어야 한다
    • 서버에 요청을 보내서 응답을 받고, 그 응답 데이터를 가공하여 보여줘야하기 때문
  • Dart에서 HTTP를 직접 요청해보도록 한다
  • 이 때, HTTP 요청을 보내기 위해 필요한 것 두가지
    • Method
      • GET : 주로 데이터를 받을 때 사용되는 메소드
      • POST : 주로 데이터를 생성할 때 사용되는 메소드
    • URL

Dart에서 HTTP요청하기

  1. Dart 프로젝트 생성
  2. http패키지 설치
    • http요청을 보내고, 응답을 받을 수 있는 다트 공식 페이지
  3. HTTP사용할 대상의 URL정의
  4. Method선택(GET, POST)
  5. 요청보내기
  6. 요청 응답받기
  7. 출력

서버(백엔드)에서는 요청을 받을 때 컨트롤이 가능

  • 요청을 시작한 브라우저가 무슨 브라우저인지 확인이 가능하다
    • 어떤 브라우저에서 요청을 보냈는지 = User-Agent
  • 무슨 메소드의 요청을 보냈는지에 따라 응답을 다르게 줄 수 있다

Get만 사용되는 경우

데이터를 읽거나 검색할 때 사용되는 메서드

주로 데이터를 읽을 때 사용된다

void main() async{
	var url = 'https://sniperfactory.com/sfac/http_only_get';
    var response = await http.get(Uri.parse(url);
    print(response.body);
}

Post만 사용되는 경우

데이터를 새로 생성할 때 생성되는 메서드

주로 데이터를 생성할 때 사용된다

void main() async{
	var url = 'https://sniperfactory.com/sfac/http_only_post';
    var response = await http.get(Uri.parse(url);
    print(response.body);
}

58강. Dio

HTTP패키지

플러터(다트)에서 가장 기본적인 Http 패키지로서, 공식 문서에서 다음과 같이 활용하고 있다

http://docs.flutter.dev/cookbook/networking/fetch-data 

 

Fetch data from the internet

How to fetch data over the internet using the http package.

docs.flutter.dev

Dio패키지

  • 기존 http패키지보다 더 많은 기능을 담고 있음
  • 특히, 요청 대상에 대한 설정과 연결관한 정보를 미리 설정해줄 수 있음
  • 요청 전에 데이터를 검수한다든지
  • 응답이 오면 데이터를 한번 점검한다든지
  • 1차적으로 가공한다든지
  • 파일(이미지), 다중파일같은 FormData를 사용해야할 때 손쉽게 구현가능
var dio = Dio(); //with default Options

//Set default configs
dio.options.baseUrl=url;

HTTP Header : user-agent

  • 사용자가 접속한 브라우저가 무엇인지 알고싶을 때
  • 크롤링 봇을 막을 때 유용하게 사용됨(user-agent를 설정하면 무효화 가능)

HTTP Header : JWT token

  • 내가 원하는 사용자에게만 데이터를 주고싶을 때 그들에게 미리 키를 공유해놓는 방법
  • 로그인->로그인 성공->서버가 JWT 토큰 발급->디바이스에 저장->요청시 JWT 토큰 장착

59강. Future, async, await

네트워크에 접속한다

  • 앱 접속->네트워크에서 데이터 받아오기->데이터를 예쁘게 보여주기
  • 네트워크에서 데이터 받아오는 방법? http 요청->응답 도착
  • http요청을 보내고나서, 응답이 3초 뒤에 온다고 가정했을 때, 내 코드들은 뭐하지?

Future 데이터  타입

  • 미래(Future)를 달리는 데이터타입
  • Future는 "알"이다
  • Future<T>의 T는 알을 까면 나오는 데이터 타입을 말함
  • await Future : Future가 끝날때까지 기다리겠다
//반드시 결과 데이터를 전달 받아서 처리해야할 경우
void main() async{
    print("로그인을 시도합니다.");
    await Future.delayed(Duration(seconds:3));
    print("로그인에 성공했습니다.");
    print("반가워요!");
}
  • Future.then : 일단 실행시켜놓고, 끝나면 별도로 처리하는 방법을 만듦
void main() async{
    print("로그인을 시도합니다.");
    Future.delayed(Duration(seconds:3)).then((res){
    	print("로그인에 성공했습니다.");
        print("반가워요!");
    });
}

//쓰레드와 비슷하다고 생각하면 됨

//위코드는 순서가 중요하다고 생각하는 개발자, 아래코드는 원인-결과가 중요하다고 생각하는 개발자가 주로 사용

//자스도 await promise/promise.then로 존재

//UI : 목적지 / Request : 관광버스 ->백엔드에 요청할 땐 한번에 보낸다!wow!

플러터에서 버튼을 누르면, 네트워크에서 데이터를 가져오고 난 뒤 응답을 화면에 갱신하는 코드

//1.데이터를 담을 변수를 만든다.
var message = "";

//2.데이터를 보여줄 위젯을 만든다.
Text(message);

//3.네트워크에 Future코드를 작성해서 데이터를 기다렸다가 받아오는 함수를 만든다.
Future<String> getData() async{
    var dio = Dio();
    var res = await dio.get("https://sniperfactory.com/sfac/http_test");
    return res.data["result"];
}

//4.이벤트핸들러를 만든다.
void handleOnPressed(){
    message = getData();
}

60강. null-safety

와 null!

네트워크의 데이터를 100% 확신할 수 있는가?

네트워크에서 데이터를 요청해서 받을 때 다음의 경우가 일어날 수 있음

ex)서버에 조회하고자 하는 데이터가 없을시, 회원정보를 가져오려고 했는데 탈퇴되었을시

프론트엔드는 데이터가 도착하지 않았을때(데이터가 없을때)에 대한 상황에도 대치를 해놓아야함

If null

만약 데이터가 null이라면 에러가 날 경우를 대비하여, If문으로 핸들링

//정상적인 경우
String message = "Hello";
Text(message),

//정상이지만, 데이터타입에 의심이 있는 경우
String? message = "Hello";
Text(message),

//하지만 정말 null값이 들어있을 경우->에러발생
//if문으로 null을 핸들링해줌
String? message = null;
if(message != null)
    Text(message!)

null-safety

내가 가질 변수가 null으르 가질 수 있을 대, 데이터 타입에 ?를 붙임

null일수도 있을떄에 제어문을 통해 다뤄줌

null이 아닐 것을 확신하면, 변수명 뒤에 !을 붙여줌

null인 데이터에 데이터를 넣어주려면, ?? 키워드를 사용

Map데이터타입에서의 null-safety

Map<String, dynamic> mapData = {
     "MyAge" : 100,
     "MyName" : "Zzang-yeah!"
}

61강. 예외처리(try-catch)

와!예외처리

예외처리

개발자의 실수로 인하여 생각하지 못하는 로직이 실행되면 앱이 종료되어버림

예외처리는 에러가 났을 때, 매뉴얼대로 행동하도록 하는 것

에러발생원인

ex)String+int, Text(null), list[3]=[1,2,3,4], 네트워크에러 등

에러가 발생해서 앱이 꺼지기 전 예외처리

//1.try-catch 에러원인 출력
try {
    List items = ["a","b","c"];
    print(items[3]);
} catch(e) {
    print("깔깔 에러남! $e");
}

//2.try-catch 예상가능 에러 설정
try {
    List items = ["a","b","c"];
    print(items[3]);
} on RangeError {
    print("깔깔 RangeError뜸!");
}

//3.try-catch 예상가능 에러 설정 및 출력
try {
    List items = ["a","b","c"];
    print(items[3]);
} on RangeError catch(e) {
    print("깔깔! 에러원인:$e");
}

62강. FutureBuilder

Future 실제 예시

//어플 구동->네트워크 데이터 요청->응답 데이터 적용->setState()->화면 그리기
var message = "";
...
Future<String> getData(){
    //인터넷...
    message= res["item"]["title"];
    setState((){});
)
Text(message)

FutureBuilder 위젯

Future를 실행시켜서 나온 데이터를 위젯으로 보여주고 싶을 때

Future를 대신 실행할 수 있는 매력적인 위젯

Future를 실행하는 도중에 일어나는 상태를 계속 보고해줌->ConnectionState라는 값을 통해 알려줌

ConnectionState.done/ConnectionState.waiting

FutureBuilder(
     future: Future.delayed(Duration(seconds:3), ()=>"Hello!"),
     builder : (context, snapshot) {
         if(snapshot.connectionState == ConnectionState.done) {
             return Text(snapshot.data!);
         }
         return SizedBox();
     }
)

로딩위젯

CiucularProgressindicator/LinearProgressindicator/flutter_spinkit패키

 

 

본 후기는 유데미-스나이퍼팩토리 9주 완성 프로젝트캠프 학습 일지 후기로 작성 되었습니다.