본문 바로가기

개발경험

[Swift] CMPedomter 러닝앱 케이던스 만들기

반응형

최근 러닝을 취미로 즐기면서 필요한 기능을 더해서 러닝앱을 만들어보고 싶다고 생각했다. 
앱에 대한 기능 중 첫 번째로 만들 기능은 케이던스 측정이었다. 

 

CMPedometer

시스템에서 생성된 실시간 워킹 데이터를 가져오기 위한 객체

걸음 수, 이동 거리, 오르내린 층수, 그리고 케이던스와 속도 등을 얻을 수 있다. 

queryPedometerData(from:to:withHandler:) 메서드를 사용하면 이미 수집된 정보를 가져올 수 있고
startUpdates(from:withHandler:)를 사용하면 이벤트 전달을 시작할 수 있다.

 

startUpdates(from:withHandler:)

보행자 관련 데이터를 앱에 전달하기 시작하는 메서드

사용자가 움직이는 동안, 지정한 startDate부터 지금까지의 누적된 보행 데이터를 handler 블럭을 통해 전달해 줌

 

데이터가 전달되는 방식

비동기적, 주기적으로 전달됨 내부적으로 일정 주기로 pedometer 데이터를 측정해서 핸들러 블럭을 전달함

이 때 동일 시점에 한 블럭만 실행되도록 보장하기 위해서 serial queue에서 실행된다. 

 

앱이 일시 중단될 경우

앱이 일시 중단되면 업데이트가 일시 정지된다.

앱이 다시 foreground나 background 상태로 돌아오면 다시 업데이트가 재개된다. 

 

가져올 수 있는 데이터(CMPedometerData)

Getting the Dates

startDate: pedometer data의 시작 시간

endDate: pedometer data의 끝 시간

 

Getting the Pedestrain Data

numberOfSteps: 유저의 걸음 수

distance: 유저의 측정된 거리(meter)

averageActivePace: 유저의 평균 페이스(seconds per meter)

currentPace: 현재 유저의 페이즈(seconds per meter) 

currentCadence: 케이던스(초 단위)

 

Getting the Floor Counts

floorsAscended: 걸어서 올라간 층수

floorDescended: 걸어서 내려간 층수 

 

특히 여기서 currentCadence는 초 단위로 케이던스를 측정한다. 하지만 러닝에서 사용하는 케이던스는 보통 분 단위로 나타나기 때문에 형상을 맞추기 위해서는 분 단위로 바꿔야 한다. 

 

func startCadenceUpdates() {
        guard CMPedometer.isCadenceAvailable() else {
            print("Cadence not available")
            return
        }

        pedometer.startUpdates(from: Date()) { [weak self] data, error in
            guard let self = self, let data = data, error == nil else { return }

            DispatchQueue.main.async {
                self.cadence = (data.currentCadence?.doubleValue ?? 0.0) * 60
                self.stepCount = data.numberOfSteps.intValue
            }
        }
    }

    func stopUpdates() {
        pedometer.stopUpdates()
    }

 

예제 코드를 통해 케이던스와 걸음 수를 측정해서 테스트를 진행해봤다. 

 

 

반응형