Docs Menu
Docs Home
/ /
Atlas Device SDK
/ /

이벤트 라이브러리 - Swift SDK

이 페이지의 내용

  • 개요
  • 시작하기 전에
  • 이벤트 기록 활성화
  • 기본 이벤트 구성
  • 이벤트 구성에 매개변수 전달
  • 이벤트 메타데이터 업데이트
  • 이벤트 기록
  • 이벤트 Realm과 상호 작용
  • 읽기 또는 쓰기 이벤트 기록
  • 사용자 지정 이벤트 기록
  • 이벤트 객체 직렬화
  • JSON 객체 직렬화
  • 이벤트 직렬화 사용자 지정
  • 이벤트 Realm 파일 크기
  • 이벤트 라이브러리 참고
  • 이벤트
  • 이벤트 페이로드

이벤트 라이브러리를 사용하면 동기화가 활성화된 모바일 애플리케이션을 사용하는 동안 사용자의 활동을 추적할 수 있습니다. 이벤트 라이브러리는 읽기 및 쓰기 트랜잭션(write transaction)을 기록할 수 있습니다. 또한 개발자는 사용자 지정 이벤트를 구성하여 버튼 누름, UI에 표시되는 데이터 또는 기타 중요한 세부 정보를 기록할 수 있습니다.

이벤트 라이브러리를 사용할 때, 기록하고 싶은 이벤트를 지정할 수 있습니다. 이는 두 개의 영역을 여는 것을 의미합니다:

  • 사용자 영역은 사용자가 클라이언트 애플리케이션에서 읽기와 쓰기를 수행하는 곳입니다.

  • 이벤트 라이브러리가 범위 지정 이벤트와 사용자 지정 이벤트를 기록하는 이벤트 영역

두 영역의 데이터가 App Services App에 동기화됩니다. 클라이언트 사용자는 이벤트 영역이나 해당 데이터와 직접 상호 작용하지 않습니다. 이벤트 영역 동기화 사용자는 사용자 영역과 다를 수도 있습니다.

이벤트 라이브러리는 많은 양의 데이터를 생성하기 때문입니다.

  • 클라이언트 장치는 데이터를 저장할 수 있는 충분한 용량이 있어야 합니다.

  • Realm Mobile Sync의 이벤트 영역 사용량은 사용자 영역의 읽기 및 쓰기보다 많을 것으로 예상됩니다.

  • 앱의 지원 Atlas cluster에는 이벤트 라이브러리에서 생성된 데이터를 처리할 수 있는 충분한 저장 용량이 있어야 합니다.

이벤트 라이브러리는 연결된 Atlas 데이터 소스 의 AuditEvent 컬렉션 에 데이터를 저장합니다. App Services App 에서 개발 모드 를 활성화하여 Atlas 가 컬렉션 을 생성하고 업로드된 이벤트에서 스키마 를 추론할 수 있도록 합니다.

중요

파티션 기반 동기화 필요

이벤트 라이브러리는 Flexible Sync를 사용한 AuditEvents 기록을 지원하지 않습니다. 이 기능을 사용하려면 AuditEvent 데이터를 기록하기 위해 파티션 기반 동기화 App Services App 이 필요합니다.

이벤트 기록을 활성화하려면 Realm.Configuration에서 Event.Configuration 속성을 설정합니다 .

다음 두 가지 방법 중 하나로 EventConfiguration 를 초기화할 수 있습니다.

  • 세부 정보를 지정할 필요가 없는 경우 기본값으로 초기화되는 구성을 사용하세요.

  • 이벤트 구성을 사용자 지정하기 위해 추가 매개변수를 전달합니다.

특정 매개변수를 지정할 필요가 없는 경우 기본값으로 초기화되는 EventConfiguration 을 사용할 수 있습니다.

var config = user.configuration(partitionValue: "Some partition value")
config.eventConfiguration = EventConfiguration()

선택적 매개변수를 전달하여 EventConfiguration 을(를) 사용자 지정할 수 있습니다.

  • metadata: 각 이벤트에 추가할 메타데이터 필드의 문자열 사전

  • syncUser: 이벤트 영역 동기화에 사용할 사용자입니다. nil인 경우 기본값은 Realm.Configuration 의 사용자입니다.

  • partitionPrefix: 이벤트 파티션 값에 추가할 문자열 접두사

  • logger: 이벤트에 사용할 사용자 지정 로거입니다. nil인 경우 기본값은 사용자 영역의 로거입니다.

  • errorHandler: 이벤트 데이터를 업로드할 때 동기화 오류가 발생하는 경우 호출되는 사용자 지정 오류 핸들러입니다. nil 인 경우 SDK는 이벤트를 기록한 다음 abort() 을 호출합니다. 프로덕션 앱은 오류로 인한 중단이 바람직한 동작이 아닌 한 항상 errorHandler 이벤트를 정의해야 합니다.

let eventSyncUser = try await app.login(credentials: Credentials.anonymous)
var config = user.configuration(partitionValue: "Some partition value")
config.eventConfiguration = EventConfiguration(metadata: ["username": "Jason Bourne"], syncUser: eventSyncUser, partitionPrefix: "event-")

이벤트 기록을 시작한 후에도 메타데이터를 업데이트할 수 있습니다. updateMetadata() 함수를 사용하여 이벤트 구성에 제공된 메타데이터를 새 값으로 바꿉니다.

이벤트 범위가 활성화된 상태에서 메타데이터를 업데이트하는 경우, 이벤트 라이브러리는 다음 이벤트 범위가 시작될 때까지 새 메타데이터를 사용하지 않습니다.

var config = user.configuration(partitionValue: "Some partition value")
config.eventConfiguration = EventConfiguration(metadata: ["username": "Jason Bourne"], syncUser: user, partitionPrefix: "event-")
let realm = try! Realm(configuration: config)
let events = realm.events!
let updateUsernameScope = events.beginScope(activity: "Update username")
// Call some function that updates the user's username
updateUsername()
updateUsernameScope.commit()
// Update the metadata you supplied with the initial EventConfiguration
events.updateMetadata(["username": "John Michael Kane"])

이벤트 구성을 정의한 후에는 Realm 의 새 이벤트 속성을 사용하여 이벤트 기록 기능을 호출할 수 있습니다. 그러면 해당 영역에 연결된 Event 인스턴스가 반환됩니다.

let realm = try! Realm(configuration: config)
let events = realm.events!

버전 10.36.0에서 변경: 새 스코프 객체인 커밋() 및 취소()에 대한 endscope() 더 이상 사용되지 않습니다.

이벤트 라이브러리는 범위의 컨텍스트 내에서 읽기 및 쓰기 이벤트를 기록합니다. 범위는 이벤트 라이브러리가 영역 활동을 감시하고 기록하는 기간입니다. 다양한 범위를 설정하여 다양한 유형의 이벤트를 기록할 수 있습니다. 예를 들어 "로그인"과 같은 특정 사용자 흐름에 대한 범위, 다양한 화면에 대한 서로 다른 범위, 특정 규정 준수 관련 활동에 대한 서로 다른 범위를 가질 수 있습니다.

주어진 활동 이름으로 새 이벤트 기록을 시작하려면 시작 스코프(활동: "일부 활동") 을 사용합니다. 그러면 나중에 범위를 커밋하거나 취소하는 데 사용할 수 있는 범위 객체가 반환됩니다. 범위를 시작하면 범위 내에서 발생하는 활동이 읽기 또는 쓰기 이벤트로 기록됩니다.

  • 이벤트 읽기: 쿼리를 실행하고 객체를 인스턴스화합니다. 범위가 종료되면 이벤트 영역은 이러한 활동을 읽기 이벤트로 기록합니다.

  • 쓰기 이벤트: 객체 수정. 범위가 종료되면 이벤트 영역은 객체의 초기 상태와 이벤트 범위 중에 변경되는 모든 속성의 새 값을 기록합니다.

beginScope 을(를) 사용하여 이벤트를 기록하면 이벤트 영역이 아직 열려 있지 않은 경우 해당 이벤트 영역이 열립니다. SDK는 백그라운드 스레드에서 이벤트 Realm을 열고 오류 콜백에 오류를 보고합니다.

참고

겹치는 이벤트 범위

둘 이상의 이벤트 범위가 동시에 활성화되는 경우 생성된 이벤트는 모든 활성 범위에서 기록됩니다.

범위에 대한 이벤트 기록을 완료하면 commit() 를 사용하여 범위 내에서 발생한 이벤트를 저장합니다. 기록을 종료하면 이벤트 라이브러리가 이벤트를 로컬 디스크에 저장합니다. 그런 다음 장치가 네트워크에 연결되어 있으면 SDK는 비동기적으로 데이터를 서버로 전송합니다.

// Read event
let readEventScope = events.beginScope(activity: "read object")
let person = realm.objects(Person.self).first!
print("Found this person: \(person.name)")
readEventScope.commit()
let mutateEventScope = events.beginScope(activity: "mutate object")
// Write event
try! realm.write {
// Change name from "Anthony" to "Tony"
person.name = "Tony"
}
mutateEventScope.commit()

또는 이벤트 범위를 cancel() 할 수 있습니다. 이렇게 하면 이벤트 기록이 중지되고 이벤트가 디스크나 서버에 지속되지 않습니다.

let eventScope = events.beginScope(activity: "read object")
let person1 = realm.objects(Person.self).first!
print("Found this person: \(person1.name)")
eventScope.cancel()

isActive 부울을 사용하여 지정된 범위가 현재 진행 중인지 확인할 수 있습니다. 아직 커밋하거나 취소하지 않은 범위를 시작한 경우 true 를 반환합니다.

let readPersonScope = events.beginScope(activity: "read object")
let person2 = realm.objects(Person.self).first!
print("Found this person: \(person2.name)")
if readPersonScope.isActive {
print("The readPersonScope is active")
} else {
print("The readPersonScope is no longer active")
}
readPersonScope.cancel()

기록이 끝나면 선택적 완료 블록을 commit() 에 전달할 수 있습니다. SDK는 이벤트 영역 업로드가 완료되었을 때가 아니라 이벤트 데이터가 성공적으로 유지되었을 때 이 차단을 호출합니다.

let mutateScope = events.beginScope(activity: "mutate object with completion")
// Write event
try! realm.write {
// Add a userId
person.userId = "tony.stark@starkindustries.com"
}
mutateScope.commit(completion: { error in
if let error = error {
print("Error recording write event: \(error.localizedDescription)")
return
}
print("Successfully recorded a write event")
})

이벤트 라이브러리를 사용하면 데이터베이스 읽기 및 쓰기와 관련이 없는 버튼 클릭 또는 기타 이벤트를 기록할 수 있습니다. 사용자 지정 이벤트를 기록하려면 recordEvent 를 사용합니다. 이 함수는 다음과 같은 매개변수를 사용합니다.

  • activity: 활동 이름입니다. 이는 "user registration"과 같은 임의의 문자열입니다.

  • eventType: 이벤트 유형입니다. 이는 '누른 제출 버튼'과 같은 임의의 문자열입니다.

  • data: 이벤트에 대한 선택적 데이터 페이로드입니다.

  • completion: 선택적 완료 핸들러입니다. 이벤트 라이브러리는 이벤트가 이벤트 영역에 저장되거나 오류가 발생하면 이 완료 차단을 호출합니다. nil 오류는 성공을 나타냅니다.

사용자 지정 이벤트에는 읽기 및 쓰기 이벤트와 같은 범위가 없습니다. 대신 사용자 지정 이벤트를 기록하는 것은 trigger를 실행하는 것과 더 유사합니다.

events.recordEvent(activity: "event", eventType: "custom event")

이벤트 라이브러리는 각 이벤트 객체를 JSON 객체로 변환합니다. 대부분의 Realm 유형 에는 유사한 JSON 표현이 있습니다. 예를 들어 Realm 문자열 속성은 JSON 문자열이 됩니다.

이벤트 라이브러리는 직접 JSON 유사점이 없는 유형을 다음과 같이 표현합니다.

날짜
데이터
이벤트에서 완전히 제외됩니다.
UUID
RFC-4122로 인코딩됨 string - 호환 .
ObjectID
ObjectId string 표현으로 인코딩됩니다.
Decimal128
숫자가 아닌 문자열로 인코딩됩니다. JSON 숫자는 공식적으로 무한정 정밀도이지만, 실제로 그렇게 구현되는 경우는 거의 없습니다.
목록
배열로 인코딩됩니다.
세트
배열로 인코딩됩니다.
Dictionary
객체로 인코딩됩니다.
내장된 객체
객체로 인코딩됩니다.

비포함된 객체 링크는 대상의 프라이머리 키로 인코딩됩니다. 읽기 이벤트에서 링크를 따라가면 전체 객체로 확장됩니다. 링크를 따르지 않으면 이 키가 기본 키로 유지됩니다.

이벤트 객체에 대한 JSON 직렬화를 사용자 지정할 수 있습니다. 이벤트 페이로드를 사용자 지정하려면 CustomEventRepresentable 프로토콜을 사용합니다.

객체가 CustomEventRepresentable 을 준수하는 경우 이벤트 라이브러리는 다음을 통해 객체를 직렬화합니다.

  • 접근자 객체 생성

  • 해당 접근자 객체에서 customEventRepresentation 호출

  • 원본 객체 대신 결과 직렬화

CustomEventRepresentable 을 준수하려면 객체가 사용자 지정된 직렬화를 정의하는 customEventRepresentation 함수를 구현해야 합니다.

// To customize event serialization, your object must
// conform to the `CustomEventRepresentable` protocol.
class Person: Object, CustomEventRepresentable {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var name: String
@Persisted var employeeId: Int
@Persisted var userId: String?
convenience init(name: String, employeeId: Int) {
self.init()
self.name = name
self.employeeId = employeeId
}
// To conform to `CustomEventRepresentable`, your object
// must implement a `customEventRepresentation` func that
// defines your customized event serialization
func customEventRepresentation() -> String {
if employeeId == 0 {
return "invalid json"
}
return "{\"int\": \(employeeId)}"
}
}

장치가 오랫동안 오프라인 상태인 경우 이벤트 영역이 상당히 커질 수 있습니다.

이를 보완하기 위해 이벤트 라이브러리는 필요에 따라 이벤트 데이터를 여러 파티션으로 자동 분할합니다. 파티션이 최대 크기에 도달하면 이벤트 라이브러리는 이벤트 영역을 닫고 자동으로 새 파티션에 쓰기를 시작합니다.

이벤트 라이브러리는 사용자에게 동기화되지 않은 파티션이 있는지 확인합니다. 일치하는 경우 이벤트 라이브러리는 파일을 열고 데이터를 업로드한 다음 파일을 닫고 삭제합니다. 사용자에게 동기화되지 않은 파티션이 없어질 때까지 이 과정이 반복됩니다.

이벤트가 저장되는 AuditEvent 컬렉션에는 앱 수신 이벤트에 대한 서버에 정의된 스키마가 있어야 합니다.

스키마에는 다음 필드가 포함되어야 합니다.

ID
_id
ObjectId
이벤트 유형
event
선택적 문자열입니다. 범위 지정 이벤트의 경우 read 또는 write , 사용자 지정 이벤트의 경우 임의의 문자열입니다.
이벤트 범위
activity
선택적 문자열입니다. 이벤트 기록을 시작하기 위해 beginScope() 에 전달된 범위 이름이거나 사용자 지정 이벤트의 경우 임의의 문자열입니다.
타임스탬프
timestamp
이벤트 범위가 종료되고 데이터가 커밋된 기기 현지 시간 또는 이벤트가 서버에 도달한 시간입니다.
데이터
data
이벤트 페이로드입니다. 이는 범위가 지정된 이벤트의 경우 JSON blob이고 사용자 지정 이벤트의 경우 임의 문자열입니다.
Metadata
metadata key (문자열)
선택적 메타데이터 사전입니다. 이 사전에 키와 값이 포함된 경우 키는 이벤트 객체의 필드 이름이 되고 모든 이벤트에 대해 값이 해당 필드에 저장됩니다.

각 이벤트에는 읽거나 쓰고 있는 객체의 현재 상태를 캡처하는 data 속성에 페이로드가 포함되어 있습니다.

사용자 지정 이벤트의 페이로드는 nil을 포함하여 개발자가 원하는 대로 지정할 수 있습니다.

중요

페이로드는 읽거나 쓰는 객체의 현재 상태를 캡처하기 때문에 매우 많은 양의 데이터를 생성합니다. 그러나 사용자가 보는 정확한 데이터가 서버 측에 절대 존재할 수 없으므로 서버가 아닌 클라이언트에서 이 작업을 수행해야 합니다. 실제로 이는 기기가 오프라인 상태가 될 경우에도 대량의 데이터를 저장할 수 있는 용량을 갖추고 있어야 합니다. 또한, 이벤트 영역에 대한 Realm Mobile Sync 사용량은 사용자 영역에서 사용자가 읽고 쓰는 것보다 훨씬 높을 수 있습니다.

예시

위의 이벤트 기록 예제에서 읽기 및 쓰기 이벤트에 대한 data 페이로드는 다음과 같습니다.

이벤트 페이로드 읽기
{
"type":"Person",
"value": [{
"_id":"62b38b3c10846041166f5deb",
"_partition":"",
"employeeId":2,
"name":"Anthony",
"userId":null
}]
}
이벤트 페이로드 쓰기
{
"Person": {
"modifications": [{
"newValue": {
"name":"Tony"
},
"oldValue":{
"_id":"62b38b3c10846041166f5deb",
"_partition":"",
"employeeId":2,
"name":"Anthony",
"userId":null
}
}]
}
}

돌아가기

클라이언트 로그 수준 설정