본문 바로가기

프로젝트 후기

[애플워치 프로젝트] 개발 후기

🗓  개발 기간 : 2020.12 ~ 2021.02.초

🔎 서비스 이름 : Multi-modal Measurer

✏️ 사용한 언어와 구조 : Swift, MVC

📇 사용한 프레임워크 : HealthKit, CoreMotion, WCSession, CMPedometer, CoreData 

📇 깃헙 주소 : priviate

 

서론 : 

ICT 인턴십으로 참여한 회사에서, 인턴으로서 진행한 프로젝트입니다. 스토어 릴리즈를 목표로 하는것은 아니고, 대학 연구실의 의뢰를 받아서 진행한 프로젝트입니다. 12월의 어느날에 회사 프로젝트가 잠깐 비어있던 틈이 있었고 그 틈을 간파하고 대표님이 간단한 애플워치 프로젝트 하나 하겠냐고 여쭤보셨었습니다. 재미있어보여서 하겠다고 했었습니다. 그러나 그 미끼를 물어선 안됐습니다.. (stay....)

 

앱은 애플워치를 착용하고, 운동을 수행하는 사용자의 센서값을 추출하는 비교적 간단한 앱입니다. 데이터를 추출하는 종류는 다음과 같습니다.

 

심박수 

소모한 칼로리, 이동거리, 걸음 수

가속도계, 자이로스코프

현재 위치

 

그리고 등등의 추가사항이 있었지만 본질은 Sampling Frequency에 맞추어서 데이터를 가져오는 일이었습니다.

서버리스한 1인 프로젝트였습니다. 디자인도 없었다가 제출 기한이 다가오자 하루만에 맞춰냈던것 같습니다.

개발 과정 소개:

언급한 바와 같이 앱의 본질은 저 7개의 데이터를 받아오는 일입니다. 

 

심박수 >> HealthKit

소모한 칼로리, 이동거리, 걸음 수 >> CMPedometer

가속도계, 자이로스코프 >> CoreMotion

현재 위치 >> CoreLocation

 

필요한 시나리오를 정리해보면 다음과 같습니다.

1. 데이터를 수집하는 주체는 애플워치입니다. 각각 프레임워크 기능을 구현한 서비스 파일에서 데이터를 받아옵니다. 

2. WCSession을 통해 WatchOS <-> iOS 쌍방향의 데이터 전송을 진행합니다. WatchOS에서 수집 완료된 데이터는 일정 주기마다 iOS로 전송됩니다.

3. iOS에서는 지정된 Hz, 지정된 저장 시간마다 데이터를 정렬해서 csv파일의 형태로 정리합니다. 구분자는 ","와 "\n"입니다.

예를 들어 50Hz, 5분마다 저장한다고 하면 한 파일에 가속도는 1만 5천개의 데이터가 정렬이 되어야 합니다. 

4. 실제 사용 환경은 1분, 2분, 5분, 10분이 아니고 1시간 이상에도 안정적으로 데이터 수집이 필요했습니다. 따라서 데이터를 중간마다 로컬 또는 원격에 저장해야 했습니다. 일정 기준이 넘는 경우 CoreData에 저장했습니다. 저장은 선입선출의 Queue를 사용했습니다.

5. 데이터 수집이 완료되면 로컬에 저장된 String 타입을 csv파일의 형태로 추출합니다. 정해진 이메일로 전송합니다.

 

앱 실행 시나리오는 이렇게 5단계를 거치는 것 같습니다. 

여기서 QnA를 몇개 해보면,

 

- 애플워치 개발 경험이 있냐

> 전혀 없다

 

- 이런 운동앱이나 센서값을 수집해오는 기능을 개발해본적이 있냐

> 전혀 없다

 

- 사수가 있냐 또는 물어볼 사람이 있냐

> 전혀 없다

 

- 개발 기간은 얼마나 있는가

> 한달입니다

 

이걸 받아선 안되는 이유가 이렇게 명확했는데 한치앞을 못 내다보았습니다

 

가장 어려웠던 기능 설명 :

1. 데이터를 받아오는 일

애플워치에 데이터 수집을 시작하라는 신호가 도착하면 userInfo를 분석해서 몇 Hz로 센서값을 가져와야 하는지 등의 정보가 전달됩니다.

세팅의 코드는 너무 길어져서 생략합니다. 기회가 된다면 이부분의 블로그 포스팅을 이어가겠습니다!

 

motionSensor의 데이터 수집이 가능한 상태이면 데이터 수집을 시작합니다.  (10 ~ 11번째 줄 시작)

수집된 데이터는 딜리게이트를 통해 WCSession을 사용하는곳으로 전달되고, iOS로 전송되게 됩니다.

 

10번째 줄에서, 

motionManager.deviceMotionUpdateInterval = interval

interval은 사용자가 요구한 Sampling Frequency (Hz)이고 전달이 완료되면 motionManager가 11번째 줄을 수행하면서 데이터 수집이 진행되는 구조입니다. 문제는 정해진 Hz만큼의 데이터가 오지 않는다는 것이었습니다.

 

30Hz이면 1초에 30개의 데이터를 내뱉어야 하고, 1분에는 1800개의 데이터를 뱉어야 하지만 iOS에 도착한 데이터는 1800개보다 훨신 부족한 갯수인 경우가 많았습니다.

 

놀랍고 웃기게도 30Hz만 그런 것이었고

10, 20 Hz, 40, 50Hz인 경우에는 데이터 수집이 정상적으로 이뤄지는 것이 너무 황당했습니다 (다른 경우는 체크해보지 못함)

어디 문서에도 적혀있지 않고, 도대체 왜이럴까..하면서 직접 몇시간씩 데이터 측정을 해보고 로그를 관찰해봐야 알 수 있었던 것이어서 더 허탈하고 힘들었던것 같습니다. 이 글을 누군가 필요한 분이 보셨으면 좋겠습니다. 30Hz는 갯수가 안 맞아요!!!!!

또한 40Hz가 넘어가면 1시간 이상에서는 오차가 많이 발생합니다!!! 순수하게 갯수만 세도 잘 맞지 않아요. 1시간 측정하면 1분정도의 데이터가 날라가는 듯한 느낌. 10Hz, 20Hz가 장기간 측정에서 좋은 것 같습니다. 이 두 친구들은 비교적 오차가 거의 없는 듯 했습니다.

 

2. String을 csv로 추출하는 일

처음에는 라이브러리를 쓰려고 했습니다. string <-> csv 라이브러리가 생각보다 많았기 때문에 이것을 사용하면 되겠다 싶었습니다. 혹은 열어서 분석하면 되겠다고 생각했습니다. 그러나 라이브러리는 클라이언트들이 요구한 형태를 만들수가 없었고 무엇보다 갯수가 많으면 너무 느리고 가끔은 터지는것이 문제였습니다. 며칠정도 고생하다가 iOS 개발자 1500분이 계시는 카톡방에 여쭤보았는데 정말 감사한 은인분이 힌트를 조금 주셨습니다.

csv파일은 그냥 구분자만 있는 스트링이다라고 하셔서 거기서 아! 하고 방향을 틀게 되었습니다.

 

 

이런식으로 데이터가 정렬되어야 하는것인데, 그럼 위에서부터

 

177,80,남,25,13468\n

ID,이름\n

Data 종류,Accelerometer\n

~

 

이렇게 데이터만 정렬되기만 하는 거였었고, 저는 가져오는 Data를 String으로 이어붙이기만 하면 되었습니다.

시간복잡도나 수행시간이 걱정이 되었지만 다행히도 계산상에 무리가 없어서 그대로 진행했습니다.

 

 

3. 추출된 데이터의 갯수가 정확하게 맞아야 하는 일

이건 1번과도 연관이 있는데, 클라이언트께서 데이터의 갯수가 정확히 필요하다보니 갯수가 정확하게 추출되어야 했습니다.

예를 들어서 50Hz로 1분간 추출해야 하는 경우 한 파일단위에는 각 3000개의 데이터가 있어야 했습니다. (50Hz * 60초 = 3,000개)

 

처음으로는 타이머를 돌려보았습니다. WatchOS에서 타이머를 돌리고, 지정된 시간(예를 들어 1분)마다 저장하라는 트리거를 iOS에 전송하는 방식이었습니다. 그 결과는.. 실패였습니다.

예를 들어 3000개의 데이터가 정확히 필요한 경우에 2800개, 2750개, 어느 파일은 3400개 등 미세한 정도도 아니고 큰 오차가 발생했습니다.

 

저는 다음 방법으로 해결했습니다.

single queue를 마련하고 데이터를 누적시키고, 3000개의 데이터가 필요한 경우 3000개씩 짤랐습니다(선입선출). 이렇게 하니 정확도가 만족할만큼 나오고 누락되는 데이터도 이전에 비하면 많이 줄었습니다. 

 

다만  저장주기, Sampling Rates를 사용자마다 다르게 조작할 수 있는것에서 자르는 데이터의 갯수가 3000개가 아니고 6000개가 될수도 있고, 1800개가 될수 있었어야 했고 이를 계산하는데에 열심히 또 머리를 썼다고 합니다.

 

마치며 :

여러가지 이유로 힘들었습니다. 매 프로젝트가 힘들지만 되게 많은 이유로 고난을 겪었습니다.

특히.. 저만 그랬는지는 잘 모르겠지만 프로젝트가 엄청 작은데도 불구하고 애플워치 빌드가 너무 오래 걸리던 것도 있고,,, 그리고 무엇보다 모두 다 처음 하는 거였기 때문에 이걸 하면서도 아 이게 돌아갈까?? 하는 생각이 가장 많이 들었습니다. 특히 50Hz로 샘플링이 된다고?? 이 데이터가 iOS로 잘 넘어올까?? 백그라운드에서 작동이 잘 될까?? 등 개발을 하면서도 확신이 들지가 않았던 것도 있습니다.

 

여러 고난을 거치며, 워치 개발은 힘들구나를 경험할 수 있었습니다. 그리고 다시 돌아오니까 iOS가 굉장히 소중하게 느껴졌고

무엇보다 빌드를 하는 족족 실기기에서 착착 되는 모습이 너무 반갑고 좋았다고 합니다.

 

오늘도 읽어주셔서 감사합니다. 만약 궁금하신 점이 있다면 메일이나 댓글 부탁드립니다.

 

'프로젝트 후기' 카테고리의 다른 글

[Tost] 개발 후기  (2) 2021.02.28
[생글] 개발 후기  (2) 2021.02.28
[placepic] 개발 후기  (0) 2021.02.22