CoreLocation을 적용하면서 사용자의 현재 위치 가져오기, 현재 위치의 주소 가져오기 등을 했었는데요.
오늘은 CoreLocation을 개발하면서 제 앱에 맞게 최적화 했던 것들을 정리해보려합니다.
처음에는 위치 기반 앱이다 보니 위치를 옮길 때 사용자의 위치를 자동으로 가져오려 했습니다.
이전에 만들었던 코드를 보시면 이렇게 작성했었는데요
함수가 실행되는 디테일한 빈도와 순서가 궁금해서 프린트를 하나하나 찍어봤습니다.
locationManagerDidChangeAuthorization()에 print("위치 가져옴"),
locationManager(didUpdateLocations:) 에 print("위치 업데이트")을 넣고 찍어보면
앱을 실행할 때
이렇게 나오게 됩니다.
처음에 사용자가 위치 동의를 하거나, 위치 동의를 한 상태라면
locationManagerDidChangeAuthorization()함수가 먼저 한 번 실행되고
그 뒤에 사용자의 위치를 추적하면서 위치가 바뀌면 locationManager(didUpdateLocations:)가 계속 실행되는 구조더라구요
그런데 여기서 문제가 있었습니다!
사용자의 위치가 바뀌고, 그 위치에 맞는 날씨를 업데이트하기 위해서
위치가 업데이트때마다 호출되는 locationManager(didUpdateLocations:) 함수에 업데이트 로직을 넣으려고 했는데
locationManager(didUpdateLocations:)가 한번만 실행되는게 아니라 한번에 두, 세번씩 호출되서
위치가 바뀔때마다 앱이 두, 세번씩 새로고침이 되는 것이었습니다..
https://developer.apple.com/documentation/corelocation/cllocationmanager/1423836-desiredaccuracy
찾아보니 설정한 위치정확도 등에 따라 호출빈도가 달라질 수 있다고 해서 공식문서를 참고해
locationManager의 .desiredAccuracy와 .distanceFilter를 조정해보았습니다!
이렇게 위치 정확도와 업데이트 빈도를 낮춰봤는데도 두, 세번씩 호출되더라구요
그래서 처음에 앱을 켰을때 locationManagerDidChangeAuthorization()만 사용해서 한 번만 위치정보를 사용하려 해봤습니다!
이렇게 하면 위치정보를 한 번만 호출하긴 하지만 유저가 앱을 켠 채로 위치를 이동했을때 자동으로 업데이트가 되지 않기 때문에
사용성이 불편한 것 같아서 고민하다가..
위치정보를 계속 켜고, 추적하는것이 아니라 필요할때마다 위치정보를 한 번만 요청하면 어떨까라는 생각을 하게 됩니다!
공식문서를 통해 LocationManager를 자세히 알아보니 저 같은 경우는
.startUpdatingLocation, .stopUpdatingLocation()으로 위치 서비스를 켰다 끄거나,
위치 서비스는 계속 켠 상태로 .requestLocation()으로 위치를 한 번만 요청할 수 있었습니다.
처음에 당연히 껐다 켜는것 보다는 위치 서비스가 켜져 있는채로 .requestLocation()로 필요할때마다 요청하는게 더 빠를 줄 알았는데
두 가지 다 테스트해본 결과 그 반대더라구요!
위치서비스를 사용할때마다 아이폰의 왼쪽 상태바에 파란 화살표가 생기는데
.requestLocation()로 실행했을때는 3~5초정도 뒤에 파란 화살표가 생기고, 업데이트되는 반면에
.startUpdatingLocation()로 실행하니 즉각적으로 파란 화살표가 생기고 더 빠르게 업데이트되는것을 확인할 수 있었습니다!
그리고 위치서비스 정확도를 낮춘 채 위치서비스를 항상 켜놓는 것 보다는
필요할때마다 더 정확하게 설정된 위치서비스를 껐다 켜는 것이 위치 정확도에도 더 도움이 될 것으로 생각했습니다!
그래서 최종적으로 완성한 코드를 보시면
처음 앱이 시작될 때 호출되는 locationManagerDidChangeAuthorization()에 .startUpdatingLocation()으로 위치 업데이트를 켜고,
그 뒤에 실행되는 locationManager(didUpdateLocations:)에서 guard를 사용해
updateLocation 변수가 true 일때만 실행되게 하고, 바로 false로 만들어 한 번만 호출되게 만들었습니다!
그리고 위치정보와 날씨를 업데이트한 뒤 .stopUpdatingLocation()으로 위치 업데이트를 멈춰 불필요한 업데이트를 줄여줬습니다!
그리고 앱이 background에서 일정시간이 지난 뒤에 foreground로 진입하거나, RefreshControl로 스크롤뷰를 당겨서 업데이트할때마다 위치정보를 요청하고, 위치와 날씨정보를 업데이트하도록 만들었습니다!
그리고 앱을 실행해 프린트를 찍어보니 필요할때 마다 위치정보가 깔끔하게 한 번만 호출되게 되었습니다!!
앞으로도 화이팅!!