이번에 개발하면서, iCloud를 처음 사용했습니다.
데이터 모델 프레임워크를 SwiftData를 사용하면, Project에 iCloud capability를 추가하면 자동으로 동기화가 됩니다.
근데 개발중에 특정 데이터들은 앱에서 직접 관리를 하고 유저가 입력하는 데이터만 아이클라우드로의 동기화가 필요했는데 이걸 하는 방법을 몰라서 구글링 열심히하다가, 정답같진 않지만 이렇게 했다라는 글을 몇몇 봤고 해보니까 성공하길래 한국어로도 기록해놓고 싶어서 기록합니다.
일단 iCloud capability 등록이나, 컨테이너 생성 내용은 생략합니다.
## Model Configuration 분리하기
일단 동기화할 모델과 동기화하지 않을 모델을 구분해서 ModelConfiguration을 선언해주는 것이 필요합니다.
let localSchema = Schema([
Book.self,
BookStore.self,
])
let cloudSchema = Schema([
Diary.self
])
let localModelConfiguration = ModelConfiguration("Local",
schema: localSchema,
isStoredInMemoryOnly: false,
cloudKitDatabase: .none
)
let cloudModelConfiguration = ModelConfiguration("Cloud",
schema: cloudSchema,
isStoredInMemoryOnly: false,
cloudKitDatabase: .automatic
)
container = try ModelContainer(
for: schema,
configurations: [localModelConfiguration, cloudModelConfiguration]
)
위 코드 처럼 일단 스키마를 2개로 구분해주고, 각각의 스키마에 대한 ModelConfiguration을 생성합니다.
이 때, cloudKitDatabase 옵션을 구분지어줘야합니다. 입력하지않으면 기본은 .automatic 인데, 동기화하지 않을 모델스키마에 대해서는 .none으로 명시적 선언을 해주어야합니다.
이후, 하나의 ModelContainer에 configuration들을 배열로 생성해서 넘겨줍니다. 이렇게하면 코드 상 컨테이너는 하나만 사용하는 것 처럼 보이지만, 내부적으로는 데이터베이스가 분리되게됩니다.
## 각 모델간의 Relationship 관리하기
SwiftData를 사용하면 @Relationship 매크로를 이용해서 모델간 관계를 나타낼 수 있었는데, 위와 같이 일부 모델은 로컬에만 저장하고 일부 모델은 iCloud 싱크도 해야하는 상황이라면, 이 @Relationship 매크로를 사용할 수 없습니다.
그렇다면 각 모델 간 참조는 어떻게해야하냐?? 면 각 모델간의 id값등을 이용해서 foreign key를 참조하는 방식으로 해야합니다.
컨테이너를 분리하지않는다면 직접 관계에 대한 cascade 방식도 편하게 지정해줄 수 있으나 컨테이너를 분리하게 되어서 관계성 내의 삭제로직이나 업데이트 로직도 별도로 관리해주어야합니다.
## 동기화 로직
Relationship 관리방법이 객체를 직접 참조하는게 아니라 객체의 속성값을 참조하는 방식으로 바뀌면서 동기화로직도 챙겨줘야합니다.
예컨데
- 여러 단말기를 사용하는 경우
- 단말기 변경
- 앱 삭제 후 재설치
- iPad, macOS등에서 하나의 iCloud 계정을 이용한 사용
등에서 동기화로직을 챙겨줘야합니다.
이 때, 로컬 데이터베이스에 저장하는 데이터는 id값이 바뀌거나 변경될 일이 없도록 주의를 해야합니다. 당연하게도, 이미 icloud에는 기존의 id값을 참조하던 데이터가 올라가있는데, 로컬에서 id값이 바뀌어버리면 icloud에 올라간 데이터는 동기화될 수가 없기 때문입니다.
게다가 iCloud의 Production 환경 데이터는 앱개발자도 조회할 수 없다고 알려져있어서.. 복구 불가이니 주의해야겠습니다.
끝
'SwiftUI로 1인 앱 개발 해보기' 카테고리의 다른 글
XCode에서 실기기 테스트빌드를 무선으로 해보기 (0) | 2025.02.02 |
---|---|
iOS앱 개발할 때 비소모품 인앱결제 구현해보기 (0) | 2025.02.02 |
AppStore Connect 앱 내 구입 심사정보 스크린샷 첨부 오류 해결 (0) | 2025.02.01 |
iOS 앱 개발 시 인앱구매/인앱결제 구매항목 복원 테스트 방법 (1) | 2025.01.31 |
SwiftUI 커스텀 폰트 적용해보기 (0) | 2025.01.29 |
댓글