[flutter] #1 json handling - flat structure

giyeon·2021년 5월 8일
0

flutter-json handling

목록 보기
1/3
post-thumbnail

#이 포스팅은 플린이의 입장에서 쓰여진 글입니다. 코드 지적은 언제나 환영입니다. 🙆🏻‍♂️

이 프로젝트는 Youtube '헤비프랜 - Heavy Fran'의 'Flutter json handling - json_serializable-플러터에서 json_serializable 패키지를 사용해 json 데이터 처리하는 방법' 강의를 참고했습니다.


Json handling

클라이언트는 서버와 data를 주고 받을 때 json을 사용하는 것이 일반일거에요.
이 시리즈는 flutter로 json을 다루는 방법에 대해서 다뤄볼게요.

강의에서는 json을 다루기 위해 세가지 방법을 보여주셔요.
가장 먼저 소개되는 부분은 flat의 형태입니다.

다음 주소에서 api key를 발급받아서 실습을 진행할게요.
openweathermap: https://openweathermap.org/

아래는 앞으로 다루게 될 json data입니다. 👀

{
"coord": {
"lon": 126.9778,
"lat": 37.5683
},
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "broken clouds",
"icon": "04d"
}
],
"base": "stations",
"main": {
"temp": 291.23,
"feels_like": 290.84,
"temp_min": 287.79,
"temp_max": 292.79,
"pressure": 1001,
"humidity": 67,
"sea_level": 1001,
"grnd_level": 995
},
"visibility": 7000,
"wind": {
"speed": 7.32,
"deg": 256,
"gust": 10.43
},
"clouds": {
"all": 75
},
"dt": 1620463873,
"sys": {
"type": 1,
"id": 8105,
"country": "KR",
"sunrise": 1620419370,
"sunset": 1620469661
},
"timezone": 32400,
"id": 1835848,
"name": "Seoul",
"cod": 200
}

flat

flat이라함은 nested된 json의 구조를 다 펴서 다루는 것을 말해요.
위의 json data를 보면 List로 감싸져 있기도 하고, 바로 Map이 나오기도 하고, Map으로 감싸져 있기도 해요.
이 구조를 하나하나 다 펴서 다루는 거에요 !
아마 코드를 보면 더 쉽게 와닿으실 거에요.

OldFlatWeather class

class OldFlatWeather {
  final double coordLon;
  final double coordLat;
  final int weatherId;
  final String weatherMain;
  final String weatherDescription;
  final String weatherIcon;
  final double mainTemp;
  final double mainFeelsLike;
  final double mainTempMin;
  final double mainTempMax;
  final int mainPressure;
  final int mainHumidity;
  final int visibility;

  OldFlatWeather({
    this.coordLon,
    this.coordLat,
    this.weatherId,
    this.weatherMain,
    this.weatherDescription,
    this.weatherIcon,
    this.mainTemp,
    this.mainFeelsLike,
    this.mainTempMin,
    this.mainTempMax,
    this.mainPressure,
    this.mainHumidity,
    this.visibility,
  });

class에 변수가 하나하나 명시가 되어있어요.
조금 노가다스러운.. 코드가 돼요.

factory로 fromJson method를 만들 때에도 json이 조금 복잡한 형태를 가지는 것이 특징이에요.
fromJson은 json을 인자로 받으면 OldFlatWeather class로 값을 받아오는 역할을 해요.

factory OldFlatWeather.fromJson(Map<String, dynamic> json) {
    return OldFlatWeather(
      coordLon: json["coord"]["lon"],
      coordLat: json["coord"]["lat"],
      weatherId: json["weather"][0]["id"],
      weatherMain: json["weather"][0]["main"],
      weatherDescription: json["weather"][0]["description"],
      weatherIcon: json["weather"][0]["icon"],
      mainTemp: json["main"]["temp"],
      mainFeelsLike: json["main"]["feels_like"],
      mainTempMin: json["main"]["temp_min"],
      mainTempMax: json["main"]["temp_max"],
      mainPressure: json["main"]["pressure"],
      mainHumidity: json["main"]["humidity"],
      visibility: json["visibility"],
    );
  }

flat형태의 문제점은.. 보다시피 typing error가 발생할 가능성이 있어요.
구조를 잘못보거나 스펠이 틀리는 오류가 나기 쉬워요.

json 설정은 다했으니!
이제 screen에 띄우러 가요.

FlatWeatherScreen

먼저 url에 접속해서 json을 따와야해요.
그러고난 후 만들어 놓은 fromJson method로 인스턴스를 만들어요.
결과적으로 OldFlatWeather의 인스턴스를 반환하도록 해줘요.
method로 만들어볼게요.

Future<OldFlatWeather> getWeather() async {
    try {
      const String url =
          'https://api.openweathermap.org/data/2.5/weather?q=seoul&appid=$KEY';
      final http.Response response = await http.get(url);
      final responseData = json.decode(response.body);
      final OldFlatWeather ofw = OldFlatWeather.fromJson(responseData);
      return ofw;
    } catch (err) {
      print(err);
      throw err;
    }
  }

이 method를 FutureBuilder의 future부분에 넣어주면 돼요.
FutureBuilder는 getWeather() 의 return값인 OldFlatWeather의 인스턴스를 포함한 data를 snapshot으로 다룰 수 있게 해줘요.
snapshot.data로 인스턴스의 필드값에 접근이 가능해요!

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flat Weather'),
      ),
      body: FutureBuilder(
        future: getWeather(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            final ofw = snapshot.data;
            return ListView( ...

다음은 nested 유형으로 다루는 방법을 알아볼게요 🙌

profile
Web , App developer wannabe 🧑🏻‍💻

0개의 댓글