2015年3月25日水曜日

iOSのFacebook Eventカレンダーの謎

iOSで設定されているカレンダーの一覧は

let store:EKEventStore = EKEventStore()
let cals = store.calendarsForEntityType(EKEntityTypeEvent)

で取得ができます。

EKEventStoreを廃棄した後に、 取得したEKCalendar#source や EKCalendar#description などを使おうとすると、以下のようなエラーを吐いて、クラッシュします。

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI sourceType]: unrecognized selector sent to instance 0x7fc7e2cba4b0'
*** First throw call stack:
(
 0   CoreFoundation                      0x0000000106c7da75 __exceptionPreprocess + 165
 1   libobjc.A.dylib                     0x00000001087d5bb7 objc_exception_throw + 45
 2   CoreFoundation                      0x0000000106c84d1d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
 3   CoreFoundation                      0x0000000106bdc9dc ___forwarding___ + 988
 4   CoreFoundation                      0x0000000106bdc578 _CF_forwarding_prep_0 + 120
 5   EventKit                            0x0000000106945475 -[EKCalendar type] + 67
 6   EventKit                            0x0000000106945649 -[EKCalendar description] + 97

まぁこれは、そういうもんなんだろうなー! という感じですよね。
多分、SourceはEKEventStoreで保持されていて、storeが廃棄されたらSourceも廃棄(nullじゃなくてなんか違うオブジェクトになっちゃう感じ?)になるとか、そんな感じだろうと。
が、ここで謎が一点浮上。

iPhoneに、Facebookアカウントの"Facebook Events"というカレンダーがあります。
このカレンダーは、EKCalendarでみると、
title は "Calendar"、 source は "CalDAV" になります。

"Facebook Events"という名前で取得できればいいのにー と思っていたのですが、
なぜか
EKEventStoreを廃棄した後に、EKCalendarのタイトルを見ると、"Facebook Events" という名前に変わっている!
(titleであれば、storeを廃棄した後でもクラッシュせずに取得できる)

わざとEKEventStoreを廃棄すれば、そのカレンダーはFacebook Eventsなのかどうかが判断出来るという。。。
• • •