[들어가기 전에]
아주 예전에 만들어보고 싶었던 프로젝트를 이제야 진행하는데요...!ㅋㅋㅋㅋ
해당 프로젝트의 기능 중 하나가 걸음 수를 측정하는 만보기 기능이 있습니다. 사용자의 걸음 수를 경험치를 환산해서 캐릭터를 키우는 앱을 계획하고 있어요.
https://github.com/eunsung-dev/SeungMaGoChi
GitHub - eunsung-dev/SeungMaGoChi
Contribute to eunsung-dev/SeungMaGoChi development by creating an account on GitHub.
github.com
해당 기능을 구현하기 위해 2가지 방법이 있어요.
바로 HealthKit과 CoreMotion이죠.
저는 걸음 수 측정을 실시간으로 할 것인지 혹은 정해진 주기마다 걸음 수를 측정할 것인지를 확실하게 정하지 않아 일단 CoreMotion 프레임워크를 사용하였습니다!
[CMPedometer]
CoreMotion에서 걸음 수 측정은 CMPedometer 클래스를 사용하면 됩니다.
CMPedometer는 모션 데이터를 활용하여 사용자의 걷기와 뛰기를 분석하고 걸음 수, 거리, 속도 등 다양한 기능을 제공하고 있어요.
애플 개발자 문서에서는 다음과 같이 설명하고 있습니다.
"A CMPedometer object provides access to the step counting capabilities of a device. You use an instance of this class to receive updates about the user’s current motion or to request information about the user’s motion over a period of time. The pedometer object operates in both the foreground and background."
내용인즉슨, CMPedometer 객체는 디바이스의 걸음 수 측정에 대한 접근을 제공합니다. foreground와 background 모두 가능하죠.
또한 CMPedometer는 다양한 메서드와 속성을 가지고 있습니다.
- 📌 isStepCountingAvailable: 기기가 걸음 수를 셀 수 있는지 여부를 나타냅니다.
- 📌 isDistanceAvailable: 기기가 이동 거리 측정할 수 있는지 여부를 나타냅니다.
- 📌 startUpdates(from:withHandler:): 말 그대로 업데이트를 시작합니다. 첫 번째 파라미터로 시작 시간을 받으며, 두 번째 파라미터로 업데이트 핸들러 블록을 받습니다.
- 📌 stopUpdates(): 업데이트를 중지합니다.
- 📌 queryPedometerData(from:to:withHandler:): 주어진 시간 범위 내의 pedometer 데이터를 요청합니다. 첫 번째와 두 번째 파라미터로 시작 시간과 종료 시간을 받으며, 세 번째 파라미터로 결과 핸들러 블록을 받습니다.
메서드와 속성을 활용한 예시는 다음과 같은데요..!
import CoreMotion
class PedometerManager: ObservableObject {
private let pedometer = CMPedometer()
@Published var steps: Int = 0
func startPedometerUpdates() {
guard CMPedometer.isStepCountingAvailable() else { return }
pedometer.startUpdates(from: Date()) { [weak self] pedometerData, error in
guard let pedometerData = pedometerData, error == nil else { return }
DispatchQueue.main.async {
self?.steps = Int(pedometerData.numberOfSteps)
}
}
}
func stopPedometerUpdates() {
pedometer.stopUpdates()
}
}
이 코드는 startUpdates와 stopUpdates를 활용하여 걸음 수 측정을 시작, 중지를 할 수 있습니다.
하지만, 정해진 기간의 걸음 수를 측정하기를 원하다면 해당 코드가 효율적일까요? 걸음 수를 실시간으로 업데이트하기 때문에 계속해서 걸음 수를 저장할 것입니다. 결국은 배터리 성능 저하, 메모리와 CPU 과부하가 발생할 것이죠.
이를 해결하기 위해서는 queryPedometerData 메서드를 사용하면 됩니다.
import CoreMotion
let pedometer = CMPedometer()
// Define the start and end dates for the query
let startDate = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
let endDate = Date()
// Query the pedometer data
pedometer.queryPedometerData(from: startDate, to: endDate) { data, error in
if let error = error {
print("An error occurred while querying pedometer data: \(error.localizedDescription)")
} else if let data = data {
print("Steps taken in the last 24 hours: \(data.numberOfSteps)")
if let distance = data.distance {
print("Distance traveled in the last 24 hours: \(distance.floatValue) meters")
}
}
}
현재로부터 24시간 동안의 걸음 수를 측정하므로 실시간으로 업데이트하는 거에 비해 효율적이라고 할 수 있겠죠?
따라서,
실시간으로 걸음 수를 측정하는 기능이 필요하다 ➡️ startUpdates, stopUpdates
특정 시간 범위 동안 걸음 수를 측정하는 기능이 필요하다 ➡️ queryPedometerData
라고 정리할 수 있겠네요 😎
'iOS' 카테고리의 다른 글
[Swift] 메모리 누수(Memory Leak)와 순환 참조(Retain Cycle) (0) | 2023.11.17 |
---|