유튜브 코딩셰프님의 동영상을 참고했다.
너무나 친절하게 잘 설명해준다. geolocator라는 플러그인을 활용한다. 전에 혼자 공부 했을 때는 권한 얻기(authentication?)부분에서 androidmanifest 파일과 info.plist 파일에 구문을 추가 할 때 위치를 정확히 몰라서 상당히 헤맸다. 아마 위 영상과 위 영상의 재생목록의 다음 영상 정도만 보더라도 현재 위치 구하는 것은 할 수 있을 것이다.
시작하기가 막막했던 부분이다. 네이버나 카카오의 api를 활용하면 되겠다는 생각이 들었는데 막상 api를 제대로 활용 해 본 적이 없어서 고생했다.
카카오와 네이버 api를 뒤지다가 네이버 클라우드 플랫폼에서 제공하는 reverse Geocoding API를 사용하기로 결정!
https://api.ncloud-docs.com/docs/ai-naver-mapsreversegeocoding-gc#
그런데 사용하려고 보니 뭐가 뭔지 하나도 모르겠다! 우선 네이버 맵 플러그인을 플러터에서 쓰기 위해 플러그인 install부터 했다.
네이버 맵 플러그인 공식 문서
설치에 유일한 한 줄기 빛이였던 글 하나
(marrrang 님께서 이 글을 보실지 모르겠지만 정말 압도적으로 감사합니다!)
설치를 하고 나서 여러 정보를 뒤져가며 종합해서 어떻게든 콘솔에 띄우는 걸 성공시켰다.
Future<List> fetchData() async {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
//현재위치를 position이라는 변수로 저장
String lat = position.latitude.toString();
String lon = position.longitude.toString();
//위도와 경도를 나눠서 변수 선언
print(lat);
print(lon);
// 잘 나오는지 확인!
Response response = await get(
Uri.parse(//이 부분이 코딩셰프님 영상과 차이가 있다. 플러터 버젼업이 되면서 이 메소드를 써야 제대로 uri를 인식한다.
"https://naveropenapi.apigw.ntruss.com/map-reversegeocode/v2/gc?request=coordsToaddr&coords=${lon},${lat}&sourcecrs=epsg:4326&output=json"),
headers: headerss);
// 미리 만들어둔 headers map을 헤더에 넣어준다.
String jsonData = response.body;
//response에서 body부분만 받아주는 변수 만들어주공~
print(jsonData);// 확인한번하고
var myJson_gu =
jsonDecode(jsonData)["results"][1]['region']['area2']['name'];
var myJson_si =
jsonDecode(jsonData)["results"][1]['region']['area1']['name'];
List<String> gusi = [myJson_si, myJson_gu];
return gusi; //구랑 시를 받아서 gusi라는 귀여운 이름으로 받는다...?
}
네이버 공식 문서를 보면 요청 예시로 이런 코드가 있다.
curl "https://naveropenapi.apigw.ntruss.com/map-reversegeocode/v2/gc?request=coordsToaddr&coords=129.1133567,35.2982640&sourcecrs=epsg:4326&output=json&orders=legalcode,admcode" \
-H "X-NCP-APIGW-API-KEY-ID: {애플리케이션 등록 시 발급받은 client id값}" \
-H "X-NCP-APIGW-API-KEY: {애플리케이션 등록 시 발급받은 client secret값}" -v
나같은 초보 개발자 (더군다나 api를 처음 써보는..ㅜ)에겐 이걸 도대체 어떻게 쓰라는 거지?? 라는 생각이 들 뿐이다.. 열심히 구글링 한 결과 첫 번째 줄의 url은 get의 첫 번째 파라미터로 넘기면 되고(그 url 안에 여러 요청 parameter를 넣는다.), -H라고 되어있는 두 번째, 세 번째 줄을 map<String,String> 형태로 만들어 get의 두 번째 파라미터로 넘기면 된다.
쉽게 코드로 보자면 이런 형태이다.
Map<String,String> headerss = {
"X-NCP-APIGW-API-KEY-ID": "Client ID", // 개인 클라이언트 아이디
"X-NCP-APIGW-API-KEY": "Client secret" // 개인 시크릿 키
}
Response response = get await(
Uri.parse("url"),
headers: headerss;
)
그리고 print(gusi);를 하면 이런 결과가 나온다.
flutter: [서울특별시, 서대문구]
gusi라는 리스트는 future를 통해서 나오기 때문에 futurebuilder를 통해 위젯에 나타내야 한다고 알고 있다. (아직 초보라 확실치는 않다..)
futurebuilder쓰는 방법을 검색해서 참조해서 코드를 짜 봤다.
https://eory96study.tistory.com/21
이 블로그를 참조해서 만든 코드이다.
FutureBuilder(
builder: (context, snapshot){
if (snapshot.hasData == false) {
return CircularProgressIndicator();
}
//error가 발생하게 될 경우 반환하게 되는 부분
else if (snapshot.hasError) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Error: ${snapshot.error}',
style: TextStyle(fontSize: 15),
),
);
}
else {
List ll = snapshot.data as List;
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(ll[0]),
Text(" "),
Text(ll[1]),
],
),
);
}
},
future: fetchData(),
)
다만 snapshot.data에 인덱싱을 적용할 수가 없어서 ll이라는 snapshot.data를 list로 받는 새 list를 만들어서 인덱싱하였다. 거의 하드코딩 수준이었지만 일단 표현하는 데에는 성공했으니 응용하면 가능성이 무궁무진한듯!
후기
api를 쓰는 방법을 어느 정도 익혔으니 난 또 성장했다.. 엄청난 고통이 따르는 과정이었지만 뿌듯하다.