最近アプリをリリースしたところ、すぐに厄介なバグが見つかりました。イベントを iCal に追加するボタンがあります。押すと、アプリがカレンダーにアクセスすることを許可するよう求められます。ユーザーが [OK] をクリックすると、エラー メッセージが表示されます (コード内の if(!saved))。ただし、ユーザーがアプリを再起動すると、すべてが完全に機能します (つまり、アイテムは許可を求めることなく iCal に追加されます)。
このバグで特に厄介なのは、シミュレーターや、アプリが以前にインストールされていたデバイス (アプリを削除してプライバシー設定をリセットした後も含む) に表示されないことです。これにより、複製が困難になります。
- (IBAction)addToCal:(id)sender{
EKEventStore *eventStore = self.filmController.eventStore;
/* I have moved this code to a new method, called after access is requested. See the edit...
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = self.film.title;
event.startDate = self.show.date;
event.endDate = [[NSDate alloc] initWithTimeInterval:(60*[self.film.length integerValue]) sinceDate:event.startDate];
event.location = @"Cinema";
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
*/
if([eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)]){
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if(granted) {
BOOL saved = [self saveEventToEventStore:eventStore];
NSString *msg;
NSString *title;
if(!saved) {
title = @"Sorry: We can't access your calendar";
msg = @"Please check your access settings for the app in Settings>>Privacy>>Calendars (and try turning permissions 'Off' then 'On'). If you still can't save events then please let us know.";
}
else {
title = @"Added";
msg = @"Item added to calendar";
}
UIAlertView *eventAlert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[eventAlert performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:YES];
}
else {
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:@"Sorry: We can't access your calendar" message:@"You must change the setting for the app in Settings>>Privacy>>Calendars." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[errorAlert performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:YES];
}
}];
}
else {
[self saveEventToEventStore:eventStore];
}
}
-(BOOL) saveEventToEventStore:(EKEventStore *)eventStore {
//Set event details
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = self.film.title;
event.startDate = self.show.date;
event.endDate = [[NSDate alloc] initWithTimeInterval:(60*[self.film.length integerValue]) sinceDate:event.startDate];
event.location = @"Cinema";
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
//event details end
NSError *err;
return [eventStore saveEvent:event span:EKSpanThisEvent error:&err];
}
どんな助けでも大歓迎です....
ニック
編集:私はこれについて多くのことを考えてきましたが、何が間違っているのかまだ明らかではありません. 私の唯一の推測は、requestAccess の前にイベントの詳細を設定していることです。これによりエラーが発生し (おそらくカレンダーの設定時)、保存が失敗する可能性があります。アプリを再起動すると、アクセスが既に許可されている状態からアプリが起動するため、エラーを回避できます。「iCalに追加」ボタンが最初に押されたときにのみ問題が発生すると想定しているため、この推測にはまだ完全には満足していませんが、その後のプレスでは問題が発生します。
上記の新しい (より完全な) コードを追加しました。これにより、requestAccess の後にイベントが作成されます。悲しいことに、私はそれをテストするためのデバイスを使い果たしましたが、見つけた場合、これが機能したかどうかを更新します.