CloudKit Quick Start - Creating a Database Schema by Saving Records CloudKit


Creating a Database Schema by Saving Records

https://developer.apple.com/library/archive/documentation/DataManagement/Conceptual/CloudKitQuickStart/CreatingaSchemabySavingRecords/CreatingaSchemabySavingRecords.html

개발과정에서 클라우드킷 API를 사용해 스키마를 생성하는 것은 쉽다. 데이터베이스에 레코드 객체를 저장할 때 연관된 레코드 형식과 그 필드가 자동적으로 생성된다. 이 기능은 저스트인타임 스키마라는 기능으로서 개발 환경에서만 사용할 수 있는 것으로 앱이 이미 팔려지는 상황에서는 접근할 수 없다. 예를 들어 개발과정에서는 클라우드킷 데이터베이스를 파퓰레이트하고 프로퍼티리스트내에 저장된 레코드를 테스트할 수 있다.

이 챕터는 몇몇 클라우드킷 API를 소개하고 코드 조각을 포함한다. #import <CloudKit/CloudKit.h> 를 구현파일에 추가하여 클라우드킷 클래스와 메소드를 사용할 수 있게 한다. Read Cloud Kit Framework Reference for details on CloudKit APIs.

스키마 디자인에 대해

유지할 객체 모델의 포션을 저장하기 위한 클라우드킷 스키마를 설계한다. 만약 스크랫치로 부터 앱을 구현한다면 모델 뷰 컨트롤러 디자인 패턴을 사용자 인터페이스를 모델 객체로부터 분리하기 위해 사용하였을 것이다. 그러면 아이클라우드에 저장하기를 원하는 객체 모델의 일부를 효율적으로 저장하기 위한 스키마를 디자인한다.

레코드 형식으로 데이터 분리하기

클라우드킷 스키마는 이름, 필드 그리고 다른 메타데이터를 갖는 하나이상의 레코드 형식으로 구성된다. 필드형식은 몇몇 추가와 함께 허용가능한 프로퍼티 리스트 형식과 유사하다. 벌크데이터를 위해서는 어셋형식을 사용하며 레코드와 별개로 저장된다. 지리 좌표를 효율적으로 질의하기 위한 Location형식도 있으며 레코드 중에 1대1과 1대다 관계를 나타내기위한 Reference형식도 있다. 레코드의 최대 크기는 1MB이므로 큰 데이터는 Asset형식을 사용한다.

표는 클라우드킷 대시보드에 보여진 가능한 필드형식과 이들의 동일한 클라우드킷 프레임워크 클래스를 보여준다.

Field Type

Class

Description

Asset

CKAsset

A large file that is associated with a record but stored separately

Bytes

NSData

A wrapper for byte buffers that is stored with the record

Date/Time

NSDate

A single point in time

Double

NSNumber

A double

Int(64)

NSNumber

An integer

Location

CLLocation

A geographical coordinate and altitude

Reference

CKReference

A relationship from one object to another

String

NSString

An immutable text string

List

NSArray

Arrays of any of the above field types



앱의 유지데이터를 저장하기 위해 이들 필드를 사용하는 레코드 형식을 설계한다. 예를 들어, 이 마스터 디테일 사용자 인터페이스는 마스터 인터페이스에 아크워크 타이틀의 묶음을 표시하고 디테일 인터페이스에는 선택된 아트워크의 속성을 표시한다.

../Art/masterdetail_sketch_2x.png

코드 내에서, 하부 객체 모델은 Artwork와 Artwork 클래스로 구성되며 Artwork 는 Artist로 단일 관계를 나타낸다.

스키마에서, 이 객체 모델의 객체사이에 1대1 매핑을 가지며 레코드형식은 Artwork, Artist가 있다. artist필드는 Artist 레코드를 참조하는 Reference 형식이다. image필드는 Asset 형식으로서 URL을 담고 있으며 location 은 Location형식으로서 위도 경도를 담고 있다. 모든 다른 필드는 단순 문자열과 날짜 형식이다.

../Art/schema_design_2x.png

레코드에 이름 정하기

레코드를 위한 유일 이름 생성을 위해 휴리스틱을 결정한다. 레코드 존과 커플된 레코드 이름은 레코드 지정자로서 데이터베이스내에 레코드의 위치를 나타낸다. 레코드 이름은 다른 데이터 소스에서 사용되는 외부 키가 될 수 있고 레코드 존에서 문자열이 조합이 단일하게 만들 수도 있다. 예를 들어, Artwork 레코드의 레코드 이름은 아티스트의 첫 그리고 마지막 이름을 카탈로그 넘버로 결합하여 115 Chen, Mei와 같은 문자열이 될 수 있다. 만약 클라우드킷 대시보드에서 레코드를 만든다면 유일 아이디가 자동적으로 레코드에 할당된다.

프로그램적으로 레코드 생성하기

먼저 레코드 지정자를 생성하는데 CKRecordID 클래스 인스턴스로서 레코드 이름과 레코드 존을 지정한다. 그리고 레코드를 생성하는데 CKRecord 클래스 인스턴스이며 레코드 지정자를 전달한다. 키 값 코딩 스타일 메소드를 사용한 레코드 필드를 설정한다.

코드 내에서 레코드 생성하려면
1. 유니크 레코드 이름을 지정하여 레코드 아이디 생성하기

let artworkRecordID = CKRecordID(recordName:"115")
CKRecordID* artworkRecordID=[[CKRecordID alloc] initWithRecordName:@"115"];

2. 레코드 객체 생성하기

let artworkRecord = CKRecord(recordType:"Artwork",recordID:artworkRecordID)
CKRecord* artworkRecord=[[CKRecord alloc] initWithRecordType:@"Artwork" recordID:artworkRecordID];

3. 레코드의 필드를 설정하기
artworkRecord["title"]="MacKerricher State Park" as NSString
artworkRecord["artist"]="Mei Chen" as NSString
artworkRecord["address"]="Fort Bragg, CA" as NSString

artworkRecord[@"title"]=@"MacKerricher State Park";
artworkRecord[@"artist"]=@"Mei Chen";
artworkRecord[@"address"]=@"Fort Bragg, CA";

레코드 저장하기

레코드 (퍼블릭, 프라이비트 또는 커스텀)를 저장할 데이터베이스를 선택하고 레코드를 저장한다. 레코드 형식이 레코드에 존재하지 않으면 생성된다.
레코드를 저장하려면
1. 앱의 기본 컨테이너에서 데이터베이스를 가져온다

퍼블릭 데이터베이스를 가져오려면

let myContainer = CKContainer.default()
let publicDatabase = myContainer.publicCloudDatabase

CKContainer* myContainer = [CKContainer defaultContainer];
CKDatabase* publicDatabase = [myContainer publicCloudDatabase];

프라이비트 데이터베이스를 가져오려면

let myContainer = CKContainer.default()
let privateDatabase = myContainer.privateDatabase

CKContainer* myContainer = [CKContainer defaultContainer];
CKDatabase* privateDatabase = [myContainer privateCloudDatabase];

커스텀 컨테이너를 가져오려면

let myContainer = CKContainer(identifier: "iCloud.com.example.ajohnson.GalleryShared")

CKContainer* myContainer = [CKContainer containerWithIdentifier:@"iCloud.com.example.ajohnson.GalleryShared"];

다중 앱에서 공유되는 커스텀 컨테이너를 생성하려면 read Share Containers Between Apps.

2. 레코드를 저장한다
publicDatabase.save(artworkRecord) {
  (record, error) in
  if let error = error {
    // Insert error handling
    return
  }
  // Insert successfully saved record code
}

[publicDatabase saveRecord:artworkRecord completionHandler:^(CKRecord* artworkRecord, NSError* error) {
  if (error) {
    // Insert error handling
    return
  }
  // Insert successfully saved record code
}];

만약 레코드 형식이 존재하지 않으면 클라우드킷 프레임워크가 설정 한 필드에 맞춰 생성한다.

엑스코드의 실행 버튼을 클릭하기전에 다음 섹션에 설명되어 있듯이 장치의 아이클라우드 크레덴셜을 입력한다.

앱을 실행하기 전에 아이클라우드 크레덴셜 입력하기

개발중에, 엑스코드를 통해 앱을 시뮬레이터나 장치에서 실행할 때 퍼블릭 데이터베이스내의 레코드를 읽으려면 아이클라우드 크레덴셜을 입력해야 한다. 프로덕션중에는 기본 퍼미션으로도 비인증된 사용자는 퍼블릭데이터를 읽어올 수 있지만 레코드를 적을 수는 없다

그러므로, 앱을 실행하고 데이터베이스에 레코드를 저장하기 전에 iOS 설정이나 맥의 시스템 설정상의 아이클라우드 계정을 입력한다. 아이클라우드 드라이브도 활성화한다. 이후에 아이클라우드 크레덴셜이 필요할 때 사용자에게 대화상자를 표시하기 위한 적절한 에러핸들링이 필요할 수 있다. as described in Alert the User to Enter iCloud Credentials.

iOS시뮬레이터에서 앱을 실행하려면 시뮬레이터 내에 아이클라우드 크레덴셜을 입력한다. 이 단계는 엑스코드의 스키마 팝업내에서  각 시뮬레이터를 실행해 수행한다.

시뮬레이터에서 아이클라우드 크레덴셜을 입력하려면

1. 엑스코드 선택 > 개발자 도구 열기 > 시뮬레이터
2. 시뮬레이터에서 하드웨어 > 홈
3. 설정 앱 실행하고 아이클라우드 실행
../Art/3_icloud_settings_2x.png
4. 애플아이디와 암호 입력하기
5. 사인인 클릭
iOS가 아이클라우드 계정을 확인하는 동안 대기
6. 아이클라우드 드라이브를 활성화 하려면 iCloud Drive 스위치 클릭
스위치가 보이지 않으면 이미 아이클라우드 드라이브가 활성화된 상태

For how to create an iCloud account, read Create an iCloud Account for Development.


사용자에게 아이클라우드 크레덴셜을 입력하도록 알림

레코드를 저장하기 전에 사용자가 자신의 아이클라우드 계정에 로그인했는지 확인할 수 있게 해서 사용자 경험을 향상시킨다. 만약 사용자가 로그인되어 있지 않으면 아이클라우드 크레덴셜을 입력할 수 있도록 알리고 아이클라우드 드라이브를 활성화하게 한다. else부분에 대해 레코드를 저장하기 위한 코드를 추가한다.

[[CKContainer defaultContainer] accountStatusWithCompletionHandler:^(CKAccountStatus accountStatus, NSError* error) {
  if (accountStatus == CKAccountStatusNoAccount) {
    UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Sign in to iCloud" message:@"Sign in to your iCloud account to write records. On the Home screen, launch Settings, tap iCloud, and enter your Apple ID. Turn iCloud Drive on. If you don't have an iCloud account, tap Create a new Apple ID." preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"Okay" style:UIAlertActionStyleCancel handler:nil]];
  }
  else {
    // Insert your just-in-time schema code here
  }
}];

레코드를 저장할 때 발생할 에러에 대해 read CloudKit Framework Constants Reference.

앱 실행하기

엑스코드에서 앱을 실행해 데이터베이스내에 레코드를 저장하고 스키마를 생성한다

다음단계 확인하기

클라우드킷 대쉬보드를 사용해 레코드 형식이 스키마에 추가되었는지 레코드가 데이터베이스에 추가되었는지 확인한다.

클라우드킷 대쉬보드를 사용해 레코드 형식 보기

레코드형식이 알맞은 필드이름과 형식을 가지고 있는지 확인한다.

레코드 형식을 보려면
1. 클라우드킷 대쉬보드에 로그인
2. 리스트에서 앱에의해 사용되는 컨테이너 선택
3. 개발이나 프로덕션 환경에서 데이터 선택
4. 탭바내에서 레코드 형식 클린
5. 레코드 형식 선택
필드이름과 형식은 오른편에 세부영역에 보여진다
../Art/2017RecordTypes.shot/Resources/shot_2x.png
Users레코드 형식은 구축된 시스템 레코드 형식으로서 삭제할 수 없지만, 필드를 추가할 수는 있다.

레코드를 보기 전에 레코드 이름 인덱스 활성화 하기

저스트인타임 스키마를 사용하는 레코드 형식에 대한 모든 메타데이터 인덱스는 기본적으로 비활성화 된다. recordName 쿼리 인덱스는 클라우드킷 대쉬보드내에서 연관 레코드를 보기 위해 활성화되어야 할 필요가 있다.

recordName 쿼리 인덱스 활성화하려면
1. 탭바에서 인덱스를 선택하고 레코드 형식을 선택한다
2. 인덱스 추가를 클릭하고 recordName 필드를 선택한다
3. 레코드 형식 저장을 클릭한다.

클라우드킷 대쉬보드를 사용해 레코드 보기

모든 데이터를 가진 저장한 레코드를 확인한다
1. 클라우드킷 대쉬보드의 탭바에서 레코드를 클릭
2. 필터나 소트 크리테리아를 추가해 쿼리 정의하기
3. 쿼리 레코드 클릭
4. 두번째 컬럼에서 recordName 선택하기
레코드 키 값 페어가 오른쪽에 세부 영역에서 보여진다

../Art/2017ViewRecord.shot/Resources/shot_2x.png

리캡

이 챕터에서 다음을 어떻게 하는지 배웠다
- 프로그래밍적으로 레코드를 저장해 자신의 스키마 생성
- 다중 앱에서 컨테이너 아이디 공유
- 생성한 레코드 형식과 레코드를 확인하기 위해 클라우드킷 대쉬보드 사용




덧글

댓글 입력 영역