ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 얼만큼 할 수 있고 얼마만에 할 수 있을까? - 파이룰
    Apple Developer Academy @ POSTECH🍍 2024. 10. 14. 22:45

    일단 지금 할 수 있는 것을 하자.

    애플 아카데미에서 지낸지도 6개월이 다되어가는 시점에 마지막 메크로 프로젝트를 맞이하게 되었다.
    우리팀은 메크로 주제를 멘토께서 협업프로젝트로 가져오신 공유자전거로 선택하였다.
    외부와 협업을 경험해볼 수 있다는 점, 이미 많은 공유자전거 플렛폼이 존재하여 레퍼런스가 많다는 점, 그리고 실 사용대상이 가까이 있다는 점들이 장점으로 다가왔기 때문이다.

     

    그러나 주제를 선택한 시점으로부터 기관과의 미팅을 하기까지 일주일간의 시간을 기다려야하는 상황이 되니
    팀 내부적으로 앞으로 기관과 소통주기가 이렇게 길다보면 중간중간 뜨는 시간이 많이 생길 것 같다는 걱정이 나왔다.

    그리고 협업과정에서 어그러져버리면 우리는 어떻게 대처해야할지에 대한 고민이 있었다.

    따라서 자전거라는 도메인을 유지하며 우리만의 무언가를 함께 가져가는 것이 좋지 않을까라는 합의가 있었고 자전거에 대한 앱을 하나 더 만들기로 결정했다.

     

    처음에는 안전한 자전거 주행을 도와주자라는 문구로부터 시작해서 안전 속도를 초과할 경우 이를 사용자에게 알려주어 적정속도를 유지하도록 하면 좋지 않을까라는 생각을 했지만 사용자 조사 결과 주행중 자전거 속도에 관심이 있는 대상은 안전하게 자전거를 이용하고자 하는 일상적인 사용자가 아니라 자전거를 열정적으로 타며 훈련등을 목적으로 현재 자신의 페이스를 유지하고 싶어하는 사람들이었다. 그래서 안전 속도보다는 라이중 속도를 명확히 표시해주자로 방향성을 바꾸게 되었다.

     

    기존 자전거 속도계 앱들을 분석한 결과, 대부분이 주행 중 불필요한 정보를 과도하게 표시하거나, 현재 속도를 명확하게 확인하기 어렵다는 문제점을 발견했다. 이에 우리는 "주행 중 스마트폰 화면을 자세히 보지 않고도 주변시만으로 현재 속도를 빠르게 파악할 수 있게 해주는 앱"이라는 새로운 목표를 설정했다

     

    우리는 앱을 설계하는 과정에서 Information Architecture ( 정보 구조도 )를 그리며 정보간의 위계를 정하였고 이를 바탕으로 Lo-Fi, Hi-Fi를 제작하며 각 화면에서의 중요한 정보를 명확히 표시하도록 노력했다.
    주행 시작전 사용자에게 원하는 속도 범위를 받은 다음에 이를 기준으로 속도의 현재 상태를 화면 전체에 색으로 표시해줌으로써 주행중에 숫자를 제대로 읽지 않아도 주변시에 걸리는 색만으로 자신의 현재 주행 상태를 체크할 수 있게 하는 것을 목표로 하였다.

     

    이 정도면 금방하지 않을까?

    앱의 주요 기능이 GPS를 이용해 실시간으로 위치정보를 가져와 이를 이용해 속도를 업데이트해주고 기타 주행 정보를 수집하는 것 밖에 없어서 이정도면 앱 구조 설계만 끝나면 한 3일이면 주요 Flow는 다 만들 것 같다고 생각했다.

     

    앱에서는 주행을 시작한 시점으로부터 주행을 종료할 때까지 하나의 주행 정보만 관리하면 되므로 RideSession이라는 하나의 주행 세션을 관리하는 객체를 만들었다. 처음에는 RideSession을 관리하는 서비스계층을 중간에 두려고 했으나 기능이 많지 않아 오히려 구조를 복잡하게 만든다고 판단해서 모든 주행 정보와 동작을 RideSession에서 처리하도록 했다.

     

    RideSessionCLLocationManager로부터 사용자 현재 위치를 받아 현재 속도 및 주행 거리, 시간등 주행과 관련한 정보들을 관리하고 이것들을 각 필요한 ViewModel에 발행해주도록 하였다.

     

    각 화면은 단계별 주행 상태를 보여주기 때문에 서로 별개의 정보를 다룬다고 생각했다. 따라서 View들이 서로를 알지 못하도록 AppCoordinator를 두어 앱의 화면 계층구조를 관리하도록 하였다. 그리고 각 View를 관리하는 ViewModel이 Event 발행하는 프로토콜을 채택하게 함으로써 화면간 이동이 필요한 동작이 실행될 때 이를AppCoordinator가 감지하여 화면을 교체하도록 하였다.

     

    이렇게 앱의 전반적인 구조 설계를 마무리하고 구체적인 작업으로 이를 나누는 과정에서도 구조가 명확하니 이정도면 금방하겠다라고 생각했다.

    PI Rule : 총 작업 시간 = 예상 시간 * 3.14

    얼른 끝내버리자고 호기롭게 시작을 했지만 할당된 작업을 실제로하는 과정은 쉽지 않았다.

     

    전체 데이터 흐름 관리를 Combine을 통해 구현하고자 했다. 그래서 명확하게 알지 못했던 구독, 발행 메커니즘에 대한 구체적인 이해가 필요했고 Combine 동작시에 어떤 시점에 어떤 쓰레드에서 현재 데이터가 관리되고 있느냐에 대한 파악도 필수적이었다. 그리고 send를 이용해 AppCoordinator로 화면을 교체하는 시점과 해당 화면을 관리하는 viewModel이 RideSession을 원하는 정보를 받아오는 동작 시점에 대한 타이밍 고려도 필요했다.

     

    여러 ViewModel에서 어떻게 같은 RideSession을 정확한 시점에 주입해야 일관된 주행관리가 가능할지에 대한 고민이 있었고 각 화면을 관리하는 AppCoordinator가 이를 관리하며 화면의 교체시점에 ViewModel 초기화와 동시에 RideSession을 주입해 같은 주행 세션이 한 주행 flow에서 유지될 수 있도록 했다.

     

    RideSession을 구현할 때도 처음에는 @ObservableObject@Published를 조합해서 변경되는 주행정보를 ViewModel에 발행하고자 했으나 RideSession에서 관리하는 전체 주행 정보가 모든 ViewModel에게 필요하지는 않기 때문에 RideSession 프로퍼티중 발행대상이 되는 프로퍼티만 @Published 마킹을하고 각 ViewModel에서 초기화할때 RideSession의 프로퍼티중 사용할 프로퍼티를 선택해 구독을 하도록 하였다.

    위치 정보를 관리하는데 있어어도 어려움이 있었다.


    기본적으로 RideSession에서 LocationManager를 구독하여 LocationManager가 새로운 정보를 발행할때마다 이를 핸들링하는 handleNewLocation을 메서드를 호출하여 위치데이터를 이용해 현재 속도, 총 주행거리등을 업데이트하도록 했다. 근데 이렇게 하니 의미없는 위치 데이터들에 대해서도 메서드가 호출되어 정확한 주행 정보 관리가 되지 않았다.


    그래서 LocationManager에서 distanceFilterhorizontalAccuracy을 이용해 유의미한 움직임이 발생해야만 위치 데이터를 발행하도록 했다. 이 결과 작은 움직임에 대해서는 위치 데이터가 발행되지 않아 좀 더 안정적인 주행정보 관리가 가능해졌으나 구조상 위치업데이트를 핸들링하는 메서드 내부에서만 현재 속도를 업데이트하다보니 움직임이 멈췄을 때 위치데이터가 발행되지 않아 현재 속도가 0이 되지 않고 이전 속도가 계속남아 있었다.


    이를 해결하기 위해 기존에 주행시간을 업데이트하기 위해 사용하던 타이머에 마지막 속도 업데이트 시점을 확인하는 로직을 추가하여 마지막 위치 발행시점으로부터 일정 시간이 지나면 멈춘것으로 판단하여 속도를 0으로 변경하도록 하였다.

     

    구현을 검증하는 것도 쉽지 않았다. 처음에는 타이머와 임의 위치데이터를 조합하여 LocationManager
    를 목킹하는 방법에 대해서 생각해봤는데 기기의 실제 GPS를 통해 얻는 위치 데이터를 대체할 수 없다고 판단했다. GPS는 주변 환경과 실제 기기의 시스템 상황에 데이터가 크게 영향을 받는다고 생각했기 때문이다.


    실내에서 GPS 드래프트 현상 때문에 정상적으로 GPS 사용이 불가해 주말 오후 내내 밖에서 코드를 바꾸고 돌아다녀보며 제대로 되는지 확인했다. 이 과정중에서도 뭔가 더 좋은 방법이 있을 것 같은데 모르니 몸이 고생한다고 생각했다.

     

    유효거리 필터나 마지막 위치 업데이트 체크 주기 그리고 요구 GPS 정확도를 조정하는 것도 어려웠다.
    앱의 반응성을 향상시키기 위해 거리필터를 낮추거나 위치 업데이트 체크 주기를 짧게하면 상태가 너무 급격하게 변하거나 특이값에 너무 민감하게 반응하였고 안정적인 주행 정보를 제공하기 위해 필터 거리도 늘리고 주기도 길게하고 저역 통과 필터를 적용하니 값이 이전보다 안정적으로 찍히기는 하는데 속도 변화에 대한 반응성이 이전보다 떨어졌다.

     

    그래서 이 둘사이에서 적정한 값을 찾으면서 MC3 때 악기별 소리 인식 임계값을 조정할 때가 떠올랐다. 제공하려는 서비스의 목적에 맞추어 정확성과 적절한 피드벡에 대해서 고려하는 것은 기능이 얼추 마무리 되었다고 생각했을 때 항상 다가오는 문제인것 같다.

     

    앱이 제대로 작동하는지 확인하기 위해 트랙위에서 달리기를 할 때 확인해보았다.
    첫 직선주로에서 속도가 정확히 찍히다가 방향전환을 하자 그 이후로 속도가 제대로 찍히지 않았다.
    구현에 실수가 있었는지 확인하기 위해 다른 속도계 앱들을 다운받아 똑같은 환경에서 똑같이 뛰어봤는데 같은 현상이 관찰되었다. 뛰는 장소가 산지에 둘러싸여 있는 지형이고 같은 곳을 계속 돌다보니 위치 변화가 제대로 반영되지 않는다고 생각했다.

     

    그래서 쭉 이어진 직선 주로를 찾아가서 뛰어보니 이전보다 속도가 안정적으로 측정되는 것을 확인했다. 그리고 달리기와 같이 크게 빠르지 않은 속도에서는 위치변화량보다 GPS 오차에 대한 영향이 더 크다고 하여 지쿠 자전거를 빌려서 좀더 빠른 속도로 달리니 지쿠에 달려 있는 속도계와 수치가 비슷하게 찍히는 것을 확인한 뒤에서야 조금 걱정을 덜었다.

     

    주말 내 여기저기 뛰어다니고 자전거도 타면서 처음 예상했던 시간보다 훨씬 긴 시간을 구현에 사용하였다.
    항상 처음 예상한 시간보다 훨씬 긴 시간이 작업에 소요되는 것 같아서 어떻게 하면 처음부터 작업에 드는 시간을 잘 산정할 수 있을까에 대한 고민이 생겨 여기 저기 방법을 찾아 다니다가 ‘수석 개발자가 알려주는 일 잘하는 방법’ 이라는 영상에서 파이룰이라는 개념에 대해 알게 되었다.

     

    작업에 대한 소요시간을 계산할 때는 항상 본인이 처음 생각했던 시간에 파이를 곱하면 실제 소요되는 시간을 구할 수 있다는 것이었다. 이번에 쓴 작업시간을 생각해보니 얼추 들어맞는 것 같아서 신기했다.

     

    이와 관련해서 이전에 멘토분하고도 이야기를 나누었는데 , 공수산정을 정확히하기 위해서는 그 일을 이미 해봤어야만 알 수 있다고 하셨다. 결국 경험치가 쌓이기전 까지는 열심히 삽질을 해봐야되고 그런 과정을 부단히 거치다보면 어디를 파야하고 어디를 파면 안되는지를 알게된다는 것이었다.

     

    뭐 그전까지는 몸으로 떼워야지 뭐 어쩌겠나 다만 그저 지치지 않고 계속 버틸 수 있기를 바랄 뿐이다.

     

     

     

    GitHub - DeveloperAcademy-POSTECH/2024-MacC-A9-DOMADO2: 🍎가 되지 말고 🍅가 되라

    🍎가 되지 말고 🍅가 되라. Contribute to DeveloperAcademy-POSTECH/2024-MacC-A9-DOMADO2 development by creating an account on GitHub.

    github.com

     

    댓글

Designed by Tistory.