레코드 변화 구독하기 CloudKit


Subscribing to Record Changes

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

마지막 쿼리와 동일한 데 질의를 반복하는 것은 비효율적이다. 대신에, 레코드 변화에 구독하여 백그라운드에서 쿼리를 실행할 수 있게 한다. 서버는 변화를 알려준다. 예를 들어, 한 사용자가 특정 아티스트에 대한 아트워크에 흥미를 가진다면 앱은 해당 아티스트가 업로드한 새로운 아트워크가 생겨나면 알 수 있다.

../Art/subscriptions_2x.png

데이터베이스에 구독을 저장하기

코드에서, 구독 객체를 생성해 관련된 변화의 형식, 레코드 형식, 프리디케이트를 지정한다. 그러면 데이터베이스에 구독 객체를 저장한다.

구독을 생성하고 저장하려면
1. 프리디케이트 객체를 생성한다.
  예를 들면, 아티스트로부터 아트워크로 구독한다. (아트워크 레코드 형식내 아티스트 필드는 참조형식이다)
CKRecordID* artistRecordID = [[CKRecordID alloc] initWithRecordName:@"Mei Chen"];
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"artist=%@", artistRecordID];

일러두기: 프리디케이트의 형식 문자열의 가능한 값 형식은 CKRecord, CKRecordID, 그리고 CKReference 객체이다. 레코드 이름을 알고 있다면 해당 레코드 이름을 포함하는 레코드 아이디를 생성할 수 있다.

2. 레코드 형식, 프리디케이트, 그리고 알림 옵션을 가지는 구독객체를 생성한다.
CKSubscription* subscription = [[CKSubscription alloc] initWithRecordType:@"Artwork" predicate:predicate options:CKSubscriptionOptionsFiresOnRecordCreation];

options파라미터의 가능한 값은 CKSubscriptionOptionsFiresOnRecordCreation, CKSubscriptionOptionsFiresOnRecordDeletion, CKSubscriptionOptionsFiresOnRecordUpdate, CKSubscriptionOptionsFiresOnce, options가 비트마스크이므로 변화형식의 조합을 지정할 수 있다.

3. 클라우드킷 알림 객체를 생성한다.
CKNotificationInfo* notificationInfo = [CKNotificationInfo new];
notificationInfo.alertLocalizationKey = @"New artwork by your favorite artist.";
notificationInfo.shouldBadge = YES;
지역화된 문자열을 사용자에게 보여주려면 알림의 alertLocalizationKey 속성을 설정한다. (alertBody 속성이 아닌)

4. 구독의 알림 객체를 새로운 클라우드킷 알림 객체로 설정한다.
subscription.notificationInfo = notificationInfo;

5. 데이터베이스에 구독을 저장한다.
CKDatabase* publicDatabase = [[CKContainer defaultContainer] publicCloudDatabase];
[publicDatabase saveSubscription:subscription completionHandler:^(CKSubscription* subscription, NSError* error) {
  if (error) {
  }
}];

Xcode에서 앱을 실행해 데이터베이스에 구독을 저장한다.

푸시알림 등록

데이터베이스에 구독을 저장하는 것은 구독이 실행될 때 자동적으로 알림을 받게 하는 것이 아니다. 클라우드킷은 애플 푸시 알림 서비스 APNs를 사용해 앱에 구독 알림을 보내어 이들을 얻으려면 푸시 알림을 등록해야 한다.

iOS와 tvOS 앱에서 이 코드를 application:didFinishLaunchingWithOptions: 프로토콜에 추가하여 푸시 알림을 위한 등록을 수행한다.

UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert categories:nil];
[application registerUserNotificationSettings:notificationSettings];
[application registerForRemoteNotifications];

맥앱에 대해서, applicationDidFinishLaunching: 프로토콜 메소드를 구현하여 푸시 알림을 등록한다.

선택적으로 application:didRegisterForRemoteNotificationWithDeviceToken: 과 application:didFailToRegisterForRemoteNotificationsWithError: 메소드로 앱이 푸시 알림 등록을 성공했는지 실패했는지 알 수 있다.

일러두기: 구독알림을 받기 위해 개발자 계정에서 앱의 명시적 앱ID를 위한 푸시 알림을 활성화 할 필요는 없다. Xcode는 클라우드킷활성화하면 자동적으로 APNs 엔타이틀먼트를 추가한다.

코드에서 푸시 알림 다루기

다음, application:didReceiveRemoteNotification: 메소드를 구현해 구독 알림을 처리한다. iOS와 tvOS 앱에서 UIApplicationDelegate 프로토콜 메소드를 구현하며 맥 앱에서는 NSApplicationDelegate 를 구현한다. 예를 들어 프리디케이트가 생성, 업데이트 또는 삭제될 때에 매치되면 뷰를 업데이트하도록 구현한다.

1. application:didReceiveRemoteNotification: 프로토콜을 앱 델리게이트에 추가한다.
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo {
}

2. application:didReceiveRemoteNotification: 메소드에서 userInfo 파라미터를 CKNotification 객체로 컨버트한다.
CKNotification* cloudKitNotification = [CKNotification notificationFromRemoteNotificationDictionary:userInfo];

3. 알림의 바디를 얻는다.
NSString* alertBody = cloudKitNotification.alertBody;

4. CKQueryNotification 객체로부터 새롭거나 수정된 레코드를 얻는다.
if (cloudKitNotification.notificationType == CKNotificationTypeQuery) {
  CKRecordID* recordID = [(CKQueryNotification*)cloudKitNotification recordID];
}

5. 레코드 변화에 따라 뷰를 업데이트하거나 사용자에게 알린다.

테스트 구독

Xcode를 통해 초기에 구독을 테스트 할 수 있고 클라우드킷 대시보드를 사용해 레코드를 생성, 수정, 삭제할 수 있다. 그러면 다중 장치에서 앱을 실행해 완전하게 구독을 테스트할 수 있다. 한장치를 사용해 변화를 새성하고 다른 장치를 통해 구독 알림을 받는다. 다중 장치를 사용하는 것은 알림은 알림이 발생한 곳에서는 얻어지지 않기 때문이다.

iOS 와 tvOS 에 대해 맥에 접속된 장치를 사용해 구독 알림을 테스트한다. 만약 푸시 알림을 성공적으로 등록했다면 다이얼로구가 보여지고 앱에 알림을 받을지 사용자 퍼미션을 물어본다.

리캡

이 챕터에서는 다음을 배웠다.
- 프리디케이트를 사용하여 레코드 변화에 구독하는 방법
- 구독 알림 다루기



덧글

댓글 입력 영역