-
Flutter: 날씨 앱(weather app) 만들기 2: JSON parsing공부 기록/Flutter 2022. 1. 6. 23:43728x90
https://www.youtube.com/watch?v=ccq1yCmNzdk&list=PLQt_pzi-LLfoOpp3b-pnnLXgYpiFEftLB&index=14
#1에서는 버튼을 누르면 날씨 정보를 가져왔는데, 앱이 실행되자마자 날씨 정보가 나타나도록 코드를 바꿔보자.
onPressed를 null로 바꾸고, initState() 사용class _LoadingState extends State<Loading> { // _LoadingState 위젯이 생성될 때 딱 한번 호출되는 메서드 추가 @override void initState() { super.initState(); getLocation(); //initState 안에 추가함으로써 앱이실행되지마자 위치 정보가 뜰 수 있도록 수정함 } void getLocation() async { // 현재 위치 가져오기 Position position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high); print(position); }
인터넷이 안되거나 위치정보 동의를 거부하는 경우와 같이 예외적인 상황을 위해 exeption handling 필요 -> try-catch문 사용. 예외의 경우는 일반적으로 'e'를 사용하는데, 다른 걸로 사용해도 괜찮음.
에러가 발생하지 않고 메시지가 출력되도록.
https://pub.dev/packages/http/install을 참고해 http package 설치.
공식 문서 참고하여 인터넷 허용까지 추가.<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.weather"> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> // 이전에 추가해둔 위치 동의 <uses-permission android:name="android.permission.INTERNET" /> //인터넷 허용 동의
fetchData() 추가. get에 마우스를 올려보면 어떤 형태로 써야하는지 나옴.
문서를 보면, get()은 지정한 헤더들을 지정한 URL로 GET 요청을 보내는 함수이다. URL은 URI보다 더 작은 개념.
API Reference > HTTP > Response를 살펴보면, Response란 미리 알려진 전체 응답 바디에 있는 HTTP 응답 클래스라고 한다. 여기서 새로운 인스턴스를 생성하고, 다양한 Properties를 이용하여 데이터를 사용할 수 있다.
예를 들어, body 속성을 이용하면, 응답 바디 전체가
statusCode를 이용하면 상태코드가 나타난다.
package 에 as http를 추가하여, get이 http 패키지로부터 왔다는 것을 명시 + get 함수를 불러올 때도 http. 표시해야함
이렇게 표기해줌으로써, 다른개발자가 은 http.Response를 보고 http 패키지로부터 나온 것을 파악한 후, 문서(> API reference)에서 이의 Response에 대한 정보를 확인할 수 있음
데이터 형식에 대해 알아보자면, XML은 html 태그와 비슷한데 (<p> <br>...), 다른 점은 사용자 임의로 태그를 만들고 키와 값을 설정하여 메타 정보를 추가할 수 있다. (오른쪽 그림 예시 참고)
JSON parsing을 해보자. 요청 성공시 (상태 코드 200) reponse body를 가져오고, 실패 시 에러메시지를 띄우도록.
- import 'dart:convert'; 문 추가 -> jsonDecode() 메서드를 사용할 수 있게됨. 인자값으로 응답 바디를 선언한 jsondata 변수를 전달해주자.
- myJson이라는 변수에 jsonDecode() 함수 호출 weather의 0번 인덱스에 있는 데이터 중 description을 가져와보자.
ㄴJSON의 값은 string, int 등 어떤 타입이 올지 모르므로 Dynamic 타입으로 지정해주어야 하기 때문에 변수 키워드를 'var'로 지정해주어야 한다.
ㄴ 이 때 특이한 것은, jsonDecode(변수)['weather'][0]['description']; 형식으로 작성.Troubleshooting: 여기서 나는 await get() 부분에서 에러가 발생하였다.
-> http 버전을 강의에서 사용한 버전(http: ^0.12.2)으로 바꾸었더니, "Error: Cannot run with sound null safety, because the following dependencies don't support null safety: - package:http - package:http_parser"가 발생하였다. null safety가 적용된 버전이라 그런 것 같다. . 이 블로그를 참고해서 안드로이드 스튜디오에서 --no-sound-null-safety 를 설정하니, 빌드가 잘 되었다!의문) 왜 instance of 'Response'가 보이지? Future<void> getLocation() async 에 Future를 붙여봐도 동일하네 +_+
// import 'dart:html'; import 'dart:core'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:http/http.dart' as http; // http import 'dart:convert'; class Loading extends StatefulWidget { const Loading({Key? key}) : super(key: key); @override _LoadingState createState() => _LoadingState(); } class _LoadingState extends State<Loading> { // _LoadingState 위젯이 생성될 때 딱 한번 호출되는 메서드 추가 @override void initState() { super.initState(); getLocation(); //initState 안에 추가함으로써 앱이실행되지마자 위치 정보가 뜰 수 있도록 수정함 fetchData(); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: ElevatedButton( onPressed: null, child: Text('Get my location'), ), ), ); } void fetchData() async { http.Response response = await http.get('https://samples.openweathermap.org/data/2.5/weather?q=London&appid=b1b15e88fa797225412429c1c50c122a1'); print(response); if(response.statusCode == 200){ String jsonDada = response.body; // 성공하면 응답 바디를 가져옴 var myJson = jsonDecode(jsonDada)['weather'][0]['description']; // weather[0]의 description만 가져옴 var windSpeed = jsonDecode(jsonDada)['wind']['speed']; print(jsonDada); print(myJson); print(windSpeed); } else (response.statusCode); // 성공하지 않으면 상태코드를 보여줌 } Future<void> getLocation() async { try { Position position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high); print(position); } catch (e) { print('Internet connect problem'); } // // void requestPermission() async { // //권한 요청하기 // LocationPermission permission = await Geolocator.requestPermission(); // } } }
'공부 기록 > Flutter' 카테고리의 다른 글
Flutter: 날씨앱 만들기 (앱의 생명주기) (0) 2022.01.06 Flutter: constant, final (1) 2021.12.03 Flutter: 스낵바, BuildContext (0) 2021.11.28 Flutter: 로그인 & 주사위 게임 실습 (0) 2021.11.27 Flutter: collection, generic (0) 2021.11.23