3

誰かが私がここで間違っていることを理解するのを手伝ってくれますか? 私のアプリは、iPhone のさまざまなカレンダーにアクセスして、今後のイベントをチェックすることになっています。そのため、カレンダーの「イベント」と「リマインダー」にアクセスする必要があります。イベントが発生したら、一時的に UserDefaults に保存します

私の .h ファイルには、次のようなものがあります

@property (nonatomic, strong) EKEventStore *eventStore;
@property (nonatomic, strong) NSMutableArray *calendars;
@property (nonatomic, strong) NSMutableArray *reminders;
@property (nonatomic) BOOL accessToCalendarsGranted;
@property (nonatomic) BOOL accessToRemindersGranted;

これらにアクセスするには、ユーザーから許可を得る必要があるため、メインコードには次のようなコードがあります。

    -(void)requestCalendarAccess
{
    // Prompt the user for access to their Calendar

    [_eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error){
        if (!granted)
        {
            NSLog(@"user has not granted access to calendars!!");
            // Display a message if the user has denied or restricted access to Calendar
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Privacy Warning", nil)
                                                            message:NSLocalizedString(@"Permission was not granted for Calendar", nil)
                                                           delegate:nil
                                                  cancelButtonTitle:NSLocalizedString(@"Dismiss", nil)
                                                  otherButtonTitles:nil];
            [alert show];

            return;
        }

        // Let's ensure that our code will be executed from the main queue
        dispatch_async(dispatch_get_main_queue(), ^{
            // The user has granted access to their Calendar
            [self accessGrantedForCalendar];
        });
    }];
}

これは accessGrantedForCalendar のコードで終了します

_calendars = [[NSUserDefaults standardUserDefaults] objectForKey:kCalendarListKey];

//if we have calendars stored in user defaults, we go and read them
if(!_calendars)
{
    _calendars = [[NSMutableArray alloc] init];
    NSArray *phoneCalendarArray = [_eventStore calendarsForEntityType:EKEntityTypeEvent];

for (EKCalendar *systemCalendar in phoneCalendarArray)
{
    NSMutableDictionary *calendarDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:[systemCalendar title], kCalendarName, [systemCalendar calendarIdentifier], kCalendarIndentifier, [NSNumber numberWithBool:YES], kCalendarWatched,  nil];

    [_calendars addObject:calendarDict];
}

[[NSUserDefaults standardUserDefaults] setObject:_calendars forKey:kCalendarListKey];
[[NSUserDefaults standardUserDefaults] synchronize];

}

そして、これはすべてかなりうまく機能しています。ここには含まれていない、実際にイベントを取得するための他の多くのコード。リマインダーに同じアプローチを試みると、問題が発生します。

-(void)requestRemindersAccess
{
    [self.eventStore requestAccessToEntityType:EKEntityTypeReminder completion:^(BOOL granted, NSError *error){
        if (granted)
        {
            // Let's ensure that our code will be executed from the main queue
            dispatch_async(dispatch_get_main_queue(), ^{
            // The user has granted access to their Calendar
                [self accessGrantedForReminder];
            });
        }
        else
        {
            NSLog(@"user has not granted access to reminders!!");
            // Display a message if the user has denied or restricted access to Calendar
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Privacy Warning", nil)
                                                            message:NSLocalizedString(@"Permission was not granted for Reminders", nil)
                                                           delegate:nil
                                                  cancelButtonTitle:NSLocalizedString(@"Dismiss", nil)
                                                  otherButtonTitles:nil];
            [alert show];
        }
    }];
}

accessGrantedForReminder でこれを終了するコード:

_reminders = [[NSUserDefaults standardUserDefaults] objectForKey:kRemindersListKey];

//if we don't have reminders stored in user defaults, we go and read them
if(!_reminders || _reminders.count == 0)
{
    _reminders = [[NSMutableArray alloc] init];
    //FOLLOWING LINE HAS PROBLEM FIRST TIME!!!
    NSArray *phoneReminderArray = [_eventStore calendarsForEntityType:EKEntityTypeReminder];

for (EKCalendar *systemCalendar in phoneReminderArray)
{
    NSMutableDictionary *calendarDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:[systemCalendar title], kCalendarName, [systemCalendar calendarIdentifier], kCalendarIndentifier, [NSNumber numberWithBool:YES], kCalendarWatched,  nil];

    [_reminders addObject:calendarDict];
}

[[NSUserDefaults standardUserDefaults] setObject:_reminders forKey:kRemindersListKey];
[[NSUserDefaults standardUserDefaults] synchronize];

}

上記の行には問題があります。最初にアプリケーションを実行したとき (つまり、許可を受け取った直後)、phoneReminderArray にオブジェクトが含まれていません。プログラムを終了して再度実行すると、phoneReminderArray は 1 つのオブジェクトを取得します。それは私を夢中にさせています-アプリを終了した後にのみ機能するのはなぜですか(他のカレンダー、ホーム、仕事、誕生日)すべてがすぐに表示されるように見えますか?

アイデアはありますか?

参考までに、この関連する質問を見て、カレンダー イベントの最初のロットに関する最初の問題を理解するのに役立ちましたが、リマインダーには役立たない

4

2 に答える 2

3

解決策は実際には非常に簡単です。リマインダーを取得するための次の行への呼び出しの直前:

  NSArray *phoneReminderArray = [_eventStore calendarsForEntityType:EKEntityTypeReminder];

次の行を配置します。

[_eventStore reset];

これで問題が解決するはずです。

于 2013-11-13T13:02:30.020 に答える
0

タラシャールの答えの後、私はそれを機能させることができませんでした.私も同様のrefreshSourcesIfNecessary方法を試してみました.

うまくいったこと: リマインダー カレンダーのリストを要求する前に、次の行を呼び出す必要がありました。

[_eventStore defaultCalendarForNewReminders];

その後、次の方法でリマインダー カレンダーのリストを取得できました。

[_eventStore calendarsForEntityType:EKEntityTypeReminder]
于 2015-12-18T21:21:20.513 に答える