상세 컨텐츠

본문 제목

러닝 앱 개발기 (1) - 달린 경로를 기록하기

러닝 앱 개발기

by Mr.Garlic 2021. 12. 9. 01:32

본문

들어가기에 앞서

이전 글에서 대략적으로 앱을 만들게 된 계기와 초기에 고려했던 부분들을 소개했다. 이번 글에서는 달린 경로를 기록하면서 있었던 문제점들과 해결한 방법에 대해서 이야기해 보려 한다. 읽어주실 분들께 미리 말씀드리고 싶은 부분은 이 방법이 최고의 방법은 아닐것이고, 더 나은 방법을 찾으시면 알려주시기를 기대하고 있다. 다만 아예 갈피를 못잡고 계시거나 국내 블로그에서 정보를 찾고 싶으신 분들을 위해 글을 남겨본다. 😊 그리고 내가 직접 고안해 낸 방법이 아닌 만큼 원글을 원작자분의 출처에서 확인하시기 바란다! 따라서 코드는 내 블로그에서는 확인 불가이다. 

 

지도상에 경로 나타내기

일단 지도에 어떻게 이동 경로를 나타낼 것인가가 가장 큰 문제였다. 너무도 당연하겠지만 먼저 지도를 볼 수 있는 ViewController를 만들어 주는 것으로 시작했다. 

 

만들어준 뷰 컨트롤러에 Map Kit View를 추가해준다.

 

 

이때 어떻게 그림을 그려줘야 할까가 너무 막막해서 검색을 하던중 다음 블로그를 발견하게 되었다. 검색어는 'swift 이동 경로' 였다. 

 

Swift/iOS MapKit 으로 지도에 이동 기록 나타내기(with LocalDB Realm)

Swift/iOS MapKit 으로 지도에 이동 기록 나타내기(with LocalDB Realm) 안녕하세요 kchoi입니다. 오늘은 MapKit을 사용하는 법부터 MapKit을 가지고 Map 위에 우리가 움직인 기록을 그려보도록 하겠습니다. 그리

42kchoi.tistory.com

 

해당 블로그에서 언급한 내용을 그대로 적는 것은 큰 의미가 없다. 따라서 여기서 언급된 요소들을 개념적으로 설명해보는 것으로 갈음하려고 한다. 위 블로그에 언급된 코드를 잘 소화하기만 해도 위치 정보가 업데이트 될 때 마다 받아오는 좌표 사이의 직선거리를 MKPolyline으로 그려줄 수 있게 된다. 이 부분은 개념적으로 이해하기도 어렵지 않았기 때문에 생략하도록 한다. 

 

위 블로그만 잘 소화하기만 해도 이렇게 멋드러진 선을 그릴 수 있다! 야호~
 
 

나타낸 경로를 이미지로 저장하기

이제 경로를 잘 그리게 되었다면 한가지 문제에 봉착하게 될 것이다. 어떻게 사용자가 달린 부분만 똑~ 따서 저장을 해 줄 것인가? 
 
1. MKPolyline으로 지도위에 그린 overlay만을 이미지로 저장해볼까? -> 그럼 어디를 뛰었는지를 알 수가 없다. ㅠㅠ
2. 스크린샷을 찍게 하면 되지 않을까? -> 이게 정답인 것 같았다. 
 
그래서 알아보게 된 MKMapSnapshotter
MKMapSnapshotter는 옵션으로 어떤 영역(region)을 찍을 건지를 정해주고 이미지 사이즈만 정해주면 간단하게 지도의 스냅샷을 찍어준다. 이 때 영역을 꼭 지정해야 하는 이유는 기본적으로 영역을 지정해 주지 않으면 우리가 보고 있는 지도의 영역을 기본값으로 찍어주기 때문에 만약 유저가 러닝을 종료하는 시점에 손으로 맵을 움직여서 다른 곳을 보고 있다고 하면 우리가 원하는 '지나온 길이 모두 포함된 이미지'가 만들어지지 못하는 것이다. 
 
그러다 봉착한 문제는 어떻게 region을 지정해 주어야 지나온 길이 모두 포함된 region이 될까? 라는 문제였다.  위에서 언급된 블로그의 구현 방식을 따라 지도에 선을 그려줬다면 기본적으로 지나온 길에 대한 coordinate 정보가 모여있는 points 라는 배열을 가지고 있을 것이다. 이 배열 안에 있는 모든 coordinate가 포함이 되는 region을 구해내면 되는데! 그 정보는 국내에서는 거의 찾기가 어려웠다. 
 
검색을 하다가 아주 친절한 github을 하나 발견하게 되는데 바로 이것이다. 
 
 

Create an MKCoordinateRegion from an array of coordinates. Safely handles coordinates that cross the 180th meridian.

Create an MKCoordinateRegion from an array of coordinates. Safely handles coordinates that cross the 180th meridian. - MapKitExtensions.swift

gist.github.com

본디 CoordinateRegion은 하나의 좌표를 가지고 MapView가 그 곳에 포커스 되도록 할 때 보통 많이 사용하는데, 이것은 스냅샷을 찍을때도 사용이 되는 그 region이다! 이를 활용해서 여러개의 coordinate를 모두 포함하는 region을 구하는 것인데... 위도와 경도의 숫자가 어떤 의미를 가지고 있는가(!!!)를 잘 모르다 보니 사실 로직을 봐도 잘 모르겠다. 이 부분은 더 깊숙히 파 볼 생각이 아직 없어서 패스할 것 같다. 그래도 이 로직을 남겨주신 Gist님께 충쉥 충쉥! 다만 deprecated된 함수들이 왕왕 있어서 수정을 해주긴 해야한다. 어차피 경고창도 읽어보면서 함수의 역할도 알 수 있게 되니 직접 수정하시는 것을 추천. 모르시겠으면 댓글을 주시면 비루한 내 코드를 공유드리겠다!

 

자 그러면 이제 영역 정했고, 사이즈도 정했고 찍어서 저장만 해주면 된다. 제법 간단하게 해결을 한 느낌이 들었다! 이미지는 UIImage로 변환 후 Data 타입으로 바꿔 Realm 에 저장하고 불러오는 방식을 선택했다. 디렉토리에 저장할 수도 있었지만, 다른 정보들과 엮어서 봐야 하는 특성상 레코드의 컬럼으로 관리하는 것이 더 좋다고 판단했기 때문이다. 

 


 오늘은 경로를 만들고 그를 저장하는 부분까지를 정리해 보았다. 스스로 회고를 위해 정리한 것이기 때문에 많은 생각들이 함축, 생략이 되어 있다. 그런데 혹시 이 글을 읽으시는 분들이 위 두 자료를 참고해도 영 문제가 안풀릴 수 있다고 생각한다. 본인도 기능을 만들면서 위의 개념들을 마구마구 응용해야 하다보니 블로그에 100% 의존해서 원하는 기능을 만들 수는 없었다! 혹시 중간에 막히거나 궁금한 점이 있으면 댓글로 마구마구 남겨주시면 최대한 답변을 드리도록 노력하겠다! 

 

 

관련글 더보기