데이터 동기화

헬스 커넥트와 통합되는 대부분의 앱에는 정보 소스 역할을 하는 자체 데이터 스토어가 있습니다. 헬스 커넥트는 앱의 동기화를 유지하는 방법을 제공합니다.

앱이 다음을 진행하는지 확인합니다.

  • 앱의 데이터 스토어에서 새 데이터 또는 업데이트된 데이터를 헬스 커넥트에 제공합니다.
  • 헬스 커넥트에서 데이터 변경사항을 가져옵니다. 이는 앱의 데이터 스토어에 반영됩니다.
  • 앱의 데이터 스토어에서 데이터가 삭제되면 헬스 커넥트에서 해당 데이터를 삭제합니다.

각 사례에서 동기화 프로세스가 헬스 커넥트와 앱의 데이터 스토어를 정렬한 상태로 유지해야 합니다.

헬스 커넥트에 데이터 제공

동기화 프로세스의 첫 번째 단계는 앱의 데이터 스토어에서 헬스 커넥트 데이터 스토어로 데이터를 제공하는 것입니다.

데이터 준비

일반적으로 앱 데이터 스토어의 레코드에는 다음 세부정보가 있습니다.

  • 고유 키(예: UUID)
  • 버전 또는 타임스탬프

헬스 커넥트에 이미 제공된 데이터를 추적하도록 앱의 데이터 스토어를 설계합니다. 이를 위해 다음 로직을 적용합니다.

  • 변경사항 목록과 마지막 토큰이 발급된 이후 업데이트가 있는 레코드를 검색하는 데 사용할 수 있는 토큰을 제공합니다.
  • 내보낸 데이터가 마지막으로 수정된 시간을 추적합니다.

이러한 단계는 새 데이터나 업데이트된 데이터만 헬스 커넥트에 제공하도록 하는 데 필수적입니다.

헬스 커넥트에 데이터 쓰기

헬스 커넥트에 데이터를 제공하려면 다음 단계를 실행하세요.

  1. 앱의 데이터 스토어에서 신규 항목 또는 업데이트된 항목의 목록을 가져옵니다.
  2. 각 항목에서 해당 데이터 유형에 적합한 Record 객체를 만듭니다. 예를 들어 체중과 관련된 데이터에는 WeightRecord 객체를 만듭니다.
  3. 앱 데이터 스토어의 고유 키와 버전 세부정보를 사용하여 각 RecordMetadata 객체를 지정합니다. 데이터 버전이 지정되지 않은 경우, 현재 타임스탬프의 Long 값을 대안으로 사용할 수 있습니다.

    val record = WeightRecord(
        metadata = Metadata(
            clientRecordId = "<Your record's Client ID>",
            clientRecordVersion = <Your record's version>
        ),
        weight = weight,
        time = time,
        zoneOffset = zoneOffset
    )
    
  4. insertRecords를 사용하여 헬스 커넥트에 데이터를 upsert합니다. 데이터를 upsert한다는 것은 헬스 커넥트 데이터 스토어에 clientRecordId 값이 있고 clientRecordVersion이 기존 값보다 높은 경우 헬스 커넥트의 기존 데이터를 덮어쓰게 됨을 의미합니다. 그렇지 않으면 upsert된 데이터가 새 데이터로 작성됩니다.

    healthConnectClient.insertRecords(arrayListOf(record))
    

데이터 제공과 관련된 실용적인 고려사항을 알아보려면 데이터 쓰기 권장사항을 확인하세요.

헬스 커넥트 ID 저장

레코드를 헬스 커넥트로 upsert한 후 앱의 데이터 스토어는 각 레코드의 헬스 커넥트 id를 저장해야 합니다. 이렇게 하면 데이터를 가져온 후 앱이 각 수신 변경사항에 새 레코드 만들기나 기존 레코드 업데이트가 필요한지 확인할 수 있습니다.

insertRecords 함수는 id 값 목록이 포함된 InsertRecordsResponse를 반환합니다. 응답을 사용하여 레코드 ID를 가져와 저장합니다.

val response = healthConnectClient.insertRecords(arrayListOf(record))

for (recordId in response.recordIdsList) {
    // Store recordId to your app's datastore
}

헬스 커넥트에서 데이터 가져오기

동기화 프로세스의 두 번째 단계는 헬스 커넥트에서 앱의 데이터 스토어로 데이터 변경사항을 가져오는 것입니다. 데이터 변경사항에는 업데이트와 삭제가 포함될 수 있습니다.

변경 토큰 가져오기

헬스 커넥트에서 가져올 변경사항 목록을 가져오려면 앱에서 변경 토큰을 추적해야 합니다. 변경사항을 요청하여 데이터 변경사항 목록과 다음에 사용할 새로운 변경 토큰을 모두 반환할 때 이를 사용할 수 있습니다.

변경 토큰을 가져오려면 getChangesToken을 호출하고 필요한 데이터 유형을 제공합니다.

val changesToken = healthConnectClient.getChangesToken(
    ChangesTokenRequest(recordTypes = setOf(WeightRecord::class))
)

데이터 변경사항 확인

이제 변경 토큰을 가져왔으므로 이 토큰으로 모든 변경사항을 가져옵니다. 사용 가능한 데이터 변경사항이 있는지 확인하는 모든 변경사항을 통과하는 루프를 만드는 것이 좋습니다. 다음 단계를 따르세요.

  1. 토큰을 사용하여 getChanges를 호출해 변경사항 목록을 가져옵니다.
  2. 변경 유형이 UpsertionChange인지 DeletionChange인지 각 변경을 확인하고 필요한 작업을 실행합니다.
    • UpsertionChange의 경우 데이터를 다시 가져오지 않도록 호출 앱에서 발생하지 않은 변경사항만 가져옵니다.
  3. 다음 변경 토큰을 새 토큰으로 할당합니다.
  4. 변경사항이 남아 있지 않을 때까지 1~3단계를 반복합니다.
  5. 다음 토큰을 저장하고 나중에 가져올 수 있도록 예약합니다.
suspend fun processChanges(token: String): String {
    var nextChangesToken = token
    do {
        val response = healthConnectClient.getChanges(nextChangesToken)
        response.changes.forEach { change ->
            when (change) {
                is UpsertionChange ->
                    if (change.record.metadata.dataOrigin.packageName != context.packageName) {
                        processUpsertionChange(change)
                    }
                is DeletionChange -> processDeletionChange(change)
            }
        }
        nextChangesToken = response.nextChangesToken
    } while (response.hasMore)
    // Return and store the changes token for use next time.
    return nextChangesToken
}

데이터 가져오기와 관련된 실용적인 고려사항을 알아보려면 데이터 동기화에 관한 권장사항을 확인하세요.

데이터 변경 처리

앱의 데이터 스토어에 변경사항을 반영합니다. UpsertionChange의 경우 metadataidlastModifiedTime을 사용하여 레코드를 upsert합니다. DeletionChange의 경우 제공된 id를 사용하여 레코드를 삭제합니다.

헬스 커넥트에서 데이터 삭제

사용자가 앱에서 자체 데이터를 삭제하는 경우 이 데이터가 헬스 커넥트에서도 삭제되어야 합니다. 이를 위해서는 deleteRecords를 사용하면 됩니다. 이 메서드는 레코드 유형과 idclientRecordId 목록을 사용합니다. 값을 지정할 수 있어 여러 데이터를 편리하게 일괄 삭제할 수 있습니다. timeRangeFilter를 취하는 대체 deleteRecords 도 사용 가능합니다.

데이터 동기화 권장사항

동기화 프로세스에 영향을 주는 요인은 다음과 같습니다.

토큰 만료

사용하지 않은 변경 토큰은 30일 이내에 만료되므로 이러한 경우 정보가 손실되지 않도록 하는 동기화 전략을 사용해야 합니다. 다음 접근 방식을 전략으로 사용할 수 있습니다.

  • 앱 DataStore에서 최근 사용한 레코드 중 헬스 커넥트의 id도 포함하는 레코드를 검색합니다.
  • 특정 타임스탬프로 시작하는 레코드를 헬스 커넥트에서 요청한 다음 레코드를 앱의 DataStore에 삽입하거나 업데이트합니다.
  • 다음에 필요할 때 사용할 수 있도록 변경 토큰을 요청합니다.

권장되는 변경 관리 전략

앱이 무효하거나 만료된 변경 토큰을 받는 경우 로직에서 토큰이 적용되는 방식에 따라 다음 관리 전략을 사용하는 것이 좋습니다.

  • 모든 데이터 읽기 및 중복 삭제. 가장 이상적인 전략입니다.
    • 헬스 커넥트에서 마지막으로 데이터를 읽은 시간의 타임스탬프를 저장합니다.
    • 토큰 만료 시 가장 최근 타임스탬프의 데이터 또는 지난 30일간의 데이터를 모두 다시 읽습니다. 그런 다음 식별자를 사용하여 이전에 읽은 데이터에서 중복 데이터를 삭제합니다.
    • 클라이언트 ID는 데이터 업데이트에 필요하므로 이를 구현하는 것이 좋습니다.
  • 마지막으로 읽은 타임스탬프 이후의 데이터만 읽기. 그러면 변경 토큰 만료 시점 쯤에 데이터 불일치가 발생할 수 있지만 그 기간은 몇 시간에서 최대 이틀 정도 걸릴 만큼 줄어듭니다.
    • 헬스 커넥트에서 마지막으로 데이터를 읽은 시간의 타임스탬프를 저장합니다.
    • 토큰 만료 시 이 타임스탬프 이후의 모든 데이터를 읽습니다.
  • 지난 30일간의 데이터를 삭제한 후 읽기. 이는 첫 번째 통합에서 발생하는 상황에 더 잘 맞습니다.
    • 지난 30일 동안 앱이 헬스 커넥트에서 읽은 모든 데이터를 삭제합니다.
    • 삭제한 다음 이 데이터를 다시 읽습니다.
  • 중복 삭제 없이 지난 30일 동안의 데이터 읽기. 이는 가장 이상적이지 않은 전략이며, 사용자에게 중복 데이터가 표시됩니다.
    • 지난 30일 동안 앱이 헬스 커넥트에서 읽은 모든 데이터를 삭제합니다.
    • 중복된 항목을 허용합니다.

데이터 유형 변경 토큰

앱이 2개 이상의 데이터 유형을 독립적으로 사용하는 경우 각 데이터 유형에 별도의 변경 토큰을 사용하세요. 여러 데이터 유형이 함께 사용되거나 그중 어떠한 것도 사용되지 않는 경우에만 그러한 데이터 유형의 목록과 Changes Sync API를 같이 사용하세요.

포그라운드 읽기

앱은 포그라운드에 있는 동안에만 헬스 커넥트의 데이터를 읽을 수 있습니다. 헬스 커넥트에서 데이터를 동기화할 때 헬스 커넥트에 대한 액세스가 언제든지 중단될 수 있습니다. 예를 들어 앱은 헬스 커넥트에서 대량의 데이터를 읽을 때 동기화 도중 발생하는 중단을 처리하고 다음에 열릴 때 동기화를 계속 진행할 수 있어야 합니다.

가져오기 시점

앱이 새 데이터에 대한 알림을 받을 수 없으므로 다음 두 가지 시점에서 새 데이터를 확인하세요.

  • 앱이 포그라운드에서 활성화될 때마다 확인합니다. 이 경우에는 수명 주기 이벤트를 사용하세요.
  • 앱이 포그라운드에 남아 있는 동안 주기적으로 확인합니다. 새 데이터를 사용할 수 있게 되면 사용자가 화면을 업데이트하여 변경사항을 반영하도록 사용자에게 알림을 보내야 합니다.