2015-01-13 113 views
1

我有一個ics(日曆)文件,我打開UIDocumentInteractionController,使用presentOptionsMenuFromRect:。運行時,「Open In」菜單看起來像thisUIDocumentInteractionController日曆訪問

正如你所看到的,沒有「添加到日曆」選項。以下是讓我感到滿意的原因:我使用的是.vcf(聯繫人卡片)文件的相同代碼,而works as expected和「打開聯繫人」選項可用。

我在日曆訪問中錯過了我的Info.plist的某種權限嗎?爲什麼UIDocumentInteractionController正確處理.ics文件類型,但.vcf工作正常?這兩種文件類型非常相似。從選項菜單中,如果我將ics文件郵寄給我自己並從郵件應用程序打開它,它就會讀取它並且可以將事件添加到我的日曆中,因此我知道這些數據是有效的。我搜索了一個解決方案的高和低,沒有人似乎知道爲什麼日曆訪問不起作用。我遇到一些問題仍然懸而未決:

Unable to Add ics file to Calendar

How can I have UIDocumentInteractionController show Calendar as an option for opening a .ics file?

如果蘋果公司是這樣做的故意,我能想到的唯一原因是因爲他們寧願開發人員使用EventKit添加事件到日曆。如果這是真的,那麼這個解決方案相當令人沮喪任何有關這個問題的見解都將不勝感激。

+0

開始有點不鼓勵,現在存在解決此問題的方法。我會向蘋果提交一份錯誤報告,看看他們有沒有什麼可說的。 – Alex

+0

我很感興趣,所以一定要回發,如果你發現任何東西:) – John

+1

我結束了使用EventKit得到它的工作。我不是傳入一個ics文件,而是通過解析原始數據並使用EventKit創建一個包含所有事件的日曆。我的猜測是,蘋果更喜歡開發者使用它(安全可能?)。這可能不是你想聽到的答案,但它似乎是唯一的選擇。對於它的價值,我經歷了許多根本無法讀取ICS文件的Android設備。我需要一個第三方導入程序才能將其存入我的設備日曆中。所以看起來ICS文件不是任何一個組的高優先級。 – Alex

回答

2

我最終通過(https://github.com/KiranPanesar/MXLCalendarManager)下載.ics文件。然後,我可以使用EventKit將下載的.ics文件解析爲EKEvent,並通過EKEventEditViewController(https://developer.apple.com/library/prerelease/ios/samplecode/SimpleEKDemo/Listings/Classes_RootViewController_m.html)打開它。繞了一圈,但似乎工作。以下是如何實現此設置我的web視圖控制器類:

@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的部分要準備好我的特定類型的.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"]; 
    }