iOS:EKEventStore sources / defaultCalendarForNewEvents / calendarsForEntityType all在授权后不返回任何内容 [英] iOS: EKEventStore sources / defaultCalendarForNewEvents / calendarsForEntityType all return nothing AFTER authorization

查看:394
本文介绍了iOS:EKEventStore sources / defaultCalendarForNewEvents / calendarsForEntityType all在授权后不返回任何内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,我试图帮助走出门。这段代码最初是由另一个团队用iOS5编写的。我添加了requestAccessToEntityType:completion:成功运行的调用。但是,在被授予访问权限后,我没有基于实体的source / defaultCalendar或日历。我无法创建新日历。

I have an app I am trying to help get out the door. This code was originally written with iOS5 in mind by another team. I added the requestAccessToEntityType:completion: call which runs successfully. However, after being granted access, I get no sources / defaultCalendar or calendars based on entity. And I cannot create a new calendar.

调用defaultCalendarForNewEvents时出现此错误

When calling defaultCalendarForNewEvents I get this error

错误域= EKCADErrorDomain代码= 1013操作无法完成。(EKCADErrorDomain错误1013。),结果为零。

如果我退出viewController尝试执行此操作并返回,则一切正常。如果在收到关于无源的警报后,我继续尝试(没有退出viewController),它反复失败。

If I back out of the viewController trying to do this and go back in, it all works fine. If, after getting the alert about no source, I keep trying (without backing out the viewController), it repeatedly fails.

我想强调,授权调用有效(要求用户访问日历并提供日历,以及稍后调用以确认授权通过)。我发现的所有其他问题都是类似的解决方案 - 确保你requestAccessToEntityType

I want to stress, that the authorization call works (the user is asked for access to calendars and gives it, and later calls to confirm authorization pass). All the other questions I have found that are similar have that as the solution -- making sure you requestAccessToEntityType

[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
    if (granted)
        {
       //[self performSelectorOnMainThread:@selector(doScheduleActivity:) withObject:activity waitUntilDone:YES];
           dispatch_async(dispatch_get_main_queue(), ^{
                [self doScheduleActivity:activity];
                });
           }
       else
       { // probably should force the main thread
         dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Calendar Access Required" message:@"In order to schedule activities, APP needs access to your Calendar.  You can change this in your device Settings." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [av show];
            });
         }

}] ;

已授予返回true并且[self doScheduleActivity:被调用。以下代码是在该例程的最开始时调用的函数,其中包含失败。

granted comes back true and the [self doScheduleActivity: gets called. The following code is a function called at the very beginning of that routine and where the failures are.

EKCalendar *saCalendar;
EKSource *source;
NSError *error;
UIAlertView *alert;

LogDebug(@"eventStore defaultCalendar %@", [eventStore defaultCalendarForNewEvents]);

// validate access to calendar prior to segueing
if ([EKEventStore respondsToSelector:@selector(authorizationStatusForEntityType:)])
{
    switch([EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent])
    {
        case EKAuthorizationStatusAuthorized:
            break;
        case EKAuthorizationStatusNotDetermined:
            {
                dispatch_async(dispatch_get_main_queue(), ^{
                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:SA_ALERT_CAPTION_CALENDAR_ACCESS_NOT_DETERMINED message:SA_ALERT_BODY_CALENDAR_ACCESS_NOT_DETERMINED delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
                    [alert show];
                    });
                return false;
                }
        case EKAuthorizationStatusDenied:
            {
                dispatch_async(dispatch_get_main_queue(), ^{
                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:SA_ALERT_CAPTION_CALENDAR_ACCESS_DENIED message:SA_ALERT_BODY_CALENDAR_ACCESS_DENIED delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
                    [alert show];
                    });
                return false;
                }
        case EKAuthorizationStatusRestricted:
            {
                dispatch_async(dispatch_get_main_queue(), ^{
                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:SA_ALERT_CAPTION_CALENDAR_ACCESS_RESTRICTED message:SA_ALERT_BODY_CALENDAR_ACCESS_RESTRICTED delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
                    [alert show];
                    });
                return false;
                }
        default:
            break;
    }
}

// search for application specifc calendar..
saCalendar = nil;
for(EKCalendar *calendar in [eventStore calendarsForEntityType:EKEntityTypeEvent])
{
    if([calendar.title isEqualToString:SA_ACTIVITIES_CALENDAR_TITLE])
    {
        saCalendar = calendar;
        break;
    }
}
// ..and create from scratch if nonexistent
if(nil == saCalendar)
{
    // find local source to hook up new calendar to
    for(source in [eventStore sources])
    {
        if(source.sourceType == EKSourceTypeLocal)
        {
            break;
        }
    }

    // if could not find local source type, something is wrong
    if( source == nil || source.sourceType != EKSourceTypeLocal)
    {
        alert = [[UIAlertView alloc] initWithTitle:SA_ALERT_CAPTION_CALENDAR_ERROR_NO_SOURCE message:SA_ALERT_BODY_CALENDAR_ERROR delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
        [alert show];
        return false;
    }

    // create calendar for applcation, name it, color it and assign source
    saCalendar = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:eventStore];
    [saCalendar setSource:source];
    [saCalendar setTitle:SA_ACTIVITIES_CALENDAR_TITLE];
    [saCalendar setCGColor:[[UIColor yellowColor] CGColor]];

    // create immediately
    error = nil; 
    if(![eventStore saveCalendar:saCalendar commit:true error:&error])
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:SA_ALERT_CAPTION_CALENDAR_ERROR_CANT_SAVE message:SA_ALERT_BODY_CALENDAR_ERROR delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
            [alert show];
            });
        return false;
    }
}

return true;

尽管已获得授权且签入 [EKEventStore authorizationStatusForEntity :EKEntityType 返回EKAuthorizationStatusAuthorized

Everything comes back nil though it was authorized and the check in [EKEventStore authorizationStatusForEntity:EKEntityType returns EKAuthorizationStatusAuthorized

在此处出现故障后,如果我退出此视图控制器并返回,则可以正常工作。这仅在系统第一次要求用户进行日历访问时才会发生,并且他们回复确定。

After I get a failure here, if I back out of this view controller and go back in, it works. This only happens the first time when the system asks the user for calendar access and they reply OK.

感谢您的任何见解。我一直在单步执行调试器,并且还进行printf类型调试以避免任何类型的计时问题等等,并且没有看到与我在Apple网站上查找的事件相反的事情。

Thanks for any insight. I've been stepping through the debugger, and also doing printf type debugging to avoid any sort of timing issues, etc. and see nothing contrary to the event stuff I have looked up on the Apple site.

我的目标设备是6.1.3 iPhone 5

My target device is 6.1.3 iPhone 5

推荐答案

好的,原来还有一个小的viewDidLoad中的代码行,它位于 [eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL grant,NSError * error 代码并试图访问eventStore之前。这是多余的并且我不需要发生这种情况而且我没有注意到它。一旦我删除了这些代码,现在的东西就可以工作了,所以它确实需要授权,因为即使在授权之后,eventStore已经糟糕了,因为之前的访问。

OK, it turns out there was a small line of code in a viewDidLoad that was before the [eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error code and that tried to access the eventStore. It was superfluous and did not need to be happening and I had not noticed it. Once I removed this code the stuff now works, so it does go back to needing to authorize, as even after authorization, the eventStore was already "bad" due to this previous access.

这篇关于iOS:EKEventStore sources / defaultCalendarForNewEvents / calendarsForEntityType all在授权后不返回任何内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆