UIDocumentInteractionController日历访问

我有一个ics(日历)文件,我打开一个UIDocumentInteractionController ,使用presentOptionsMenuFromRect: 运行时,“Open In”菜单看起来像这样 。

正如你所看到的,没有“添加到日历”选项。 这是什么让我:我使用.vcf(联系人卡)文件相同的确切代码,并按预期与“打开联系人”选项可用。

我是否在Info.plist缺less日历访问权限? 为什么UIDocumentInteractionController不能UIDocumentInteractionController处理.ics文件types,但.vcf工作得很好? 这两种文件types非常相似。 从选项菜单中,如果我把ics文件邮寄给我自己,并从邮件应用程序中打开它,它就会读取它,并且可以将事件添加到我的日历中,所以我知道这些数据是有效的。 我search了一个解决scheme的高和低,没有人似乎知道为什么日历访问不起作用。 我遇到的一些问题仍未得到答复:

无法将ics文件添加到日历

我怎样才能让UIDocumentInteractionController显示日历作为打开一个.ics文件的选项?

如果苹果故意这样做,我能想到的唯一原因是他们宁愿开发人员使用EventKit将事件添加到日历。 如果属实,那么这个解决scheme是相当令人沮丧 任何有关这个问题的见解将不胜感激。

我结束了通过( https://github.com/KiranPanesar/MXLCalendarManager )下载.ics文件。 然后,我可以使用EventKit将下载的.ics文件parsing为EKEvent,并通过EKEventEditViewController( https://developer.apple.com/library/prerelease/ios/samplecode/SimpleEKDemo/Listings/Classes_RootViewController_m.html )将其打开。 绕了一圈,但似乎工作。 以下是我如何设置我的webview控制器类实现这个:

 @interface WebViewController : UIViewController <UIWebViewDelegate, EKEventEditViewDelegate> { // EKEventStore instance associated with the current Calendar application @property (nonatomic, strong) EKEventStore *eventStore; // Default calendar associated with the above event store @property (nonatomic, strong) EKCalendar *defaultCalendar; @end @implementation WebViewController - (void)viewDidLoad { [super viewDidLoad]; ... // Initialize the event store self.eventStore = [[EKEventStore alloc] init]; } - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSURL *url = [request URL]; NSString *path = [url absoluteString]; NSRange range = [path rangeOfString:@".ics" options:NSCaseInsensitiveSearch]; if (range.length > 0) { [self checkCalendarAndAddEvent:url]; return NO; } [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; return YES; } -(void)checkCalendarAndAddEvent:(NSURL*)url { EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent]; if(status == EKAuthorizationStatusAuthorized) { [self addEventToCalendar:url]; } else { [self.eventStore requestAccessToEntityType:EKEntityTypeEvent 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; add to calendar [self addEventToCalendar:url]; }); }else { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Privacy Warning" message:@"Permission was not granted for Calendar" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } }]; } } -(void) addEventToCalendar: (NSURL *)url { MXLCalendarManager* calendarManager = [[MXLCalendarManager alloc] init]; self.defaultCalendar = self.eventStore.defaultCalendarForNewEvents; [calendarManager scanICSFileAtRemoteURL:url withCompletionHandler:^(MXLCalendar *calendar, NSError *error) { MXLCalendarEvent *mxlEvent = calendar.events.firstObject; EKEventEditViewController *addController = [[EKEventEditViewController alloc] init]; EKEvent * event = [EKEvent eventWithEventStore:self.eventStore]; event.location = mxlEvent.eventLocation; event.startDate = mxlEvent.eventStartDate; event.endDate = mxlEvent.eventEndDate; event.title = mxlEvent.eventSummary; event.notes = mxlEvent.eventDescription; addController.event = event; // Set addController's event store to the current event store addController.eventStore = self.eventStore; addController.editViewDelegate = self; [self presentViewController:addController animated:YES completion:nil]; }]; } @end 

我也不得不稍微修改MXLCalendarManager.m的某些部分,以便为我的特定types的.ics格式化做好准备。 例如,我的.ics文件的摘要部分如下所示:

 DESCRIPTION;LANGUAGE=en-us:The following details your appointment:\n\n\n 

作为MXLCalendarManager只在寻找:

 DESCRIPTION: (Something). 

我修改了这些代码来解释; ln。 这也删除了所有的人工换行符,但允许我在摘要描述中添加自己的行:

  // Extract event description [eventScanner scanUpToString:@"DESCRIPTION" intoString:nil]; [eventScanner scanUpToString:@":" intoString:nil]; [eventScanner scanUpToString:@"\nSEQUENCE" intoString:&descriptionString]; if(descriptionString.length > 1) { descriptionString = [descriptionString substringFromIndex:1]; descriptionString = [[[descriptionString stringByReplacingOccurrencesOfString:@"\nSEQUENCE" withString:@""] stringByReplacingOccurrencesOfString:@"\r\n " withString:@""] stringByReplacingOccurrencesOfString:@"\\n" withString:@"\n"]; }