从我的应用程序以编程方式启动Mac Calendar.app(并选择特定日期)?

时间:2013-04-08 16:07:45

标签: macos cocoa calendar osx-mountain-lion

我想在我的Mac应用程序中包含一个按钮,当按下该按钮时,将启动用户的默认日历应用程序。我希望日历可以在某个日期开放。

这适用于OS X Mountain Lion。

有没有一般的方法来做到这一点?

修改: FWIW,这就是我现在正在做的事情:

- (IBAction)launchCalendarApp:(id)sender
{
    [[NSWorkspace sharedWorkspace] launchApplication:@"/Applications/Calendar.app"];
}

我知道硬编码这样的道路是一个坏主意,这就是我提出这个问题的原因。

更新: 这就是我最终做的事情:

- (IBAction)launchCalendarApp:(id)sender
{
    NSWorkspace *sharedWorkspace = [NSWorkspace sharedWorkspace];
    NSString *iCalPath = [sharedWorkspace absolutePathForAppBundleWithIdentifier:@"com.apple.iCal"];
    BOOL didLaunch = [sharedWorkspace launchApplication:iCalPath];
    if (didLaunch == NO) {
        NSString *message = NSLocalizedString(@"The Calendar application could not be found.", @"Alert box message when we fail to launch the Calendar application");
        NSAlert *alert = [NSAlert alertWithMessageText:message defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@""];
        [alert setAlertStyle:NSCriticalAlertStyle];
        [alert runModal];
    }
}

听起来,在开发更好的API之前,所有可行的方法都是可行的。我的解决方案类似于Jay的建议。我正在使用包标识符来获取路径,因为我认为它不那么脆弱。即使他们(或用户)决定重命名应用程序,Apple也不太可能在未来更改软件包ID。不幸的是,这种方法并没有让我到达特定日期。当我有更多时间时,我会进一步调查一些其他建议(使用ical://等)。

更新2 : NSGod下面有一个很棒的答案,如果您的应用程序没有沙盒,也可以打开日历到特定日期。

4 个答案:

答案 0 :(得分:8)

注意:当你使用你所使用的内容进行更新时,我仍在研究这个,但我会添加这个FWIW。

使用应用程序的包标识符通常是一种更健壮的方式来引用应用程序然后单独使用该名称,因为用户可以在OS X中移动或重命名应用程序,但是他们无法轻松更改包标识符。此外,即使Apple将iCal.app重命名为Calendar.app,CFBundleIdentifier仍为com.apple.iCal

if (![[NSWorkspace sharedWorkspace]
                launchAppWithBundleIdentifier:@"com.apple.iCal"
                                      options:NSWorkspaceLaunchDefault
               additionalEventParamDescriptor:nil
                             launchIdentifier:NULL]) {
    NSLog(@"launching Calendar.app failed!");
}

即使您的应用是沙盒,上述代码也能正常运行。您可能会尝试创建一个自定义NSAppleEventDescriptor,它将指定类似于以下AppleScript代码的内容,但由于沙箱可能会被拒绝:

view calendar at date "Sunday, April 8, 2012 4:28:43 PM"

如果您的应用不必沙盒,那么使用Scripting Bridge会更容易,并且使用该方法可以选择特定的NSDate

使用ScriptingBridge的示例项目:OpenCalendar.zip

在该项目中,我使用以下代码:

SBCalendarApplication *calendarApp = [SBApplication
              applicationWithBundleIdentifier:@"com.apple.iCal"];
[calendarApp viewCalendarAt:[self.datePicker dateValue]];

这将启动Calendar.app/iCal.app并将日历更改为指定日期。

答案 1 :(得分:4)

所以现在听起来你要么采用硬接线方法,例如

// Launches Calendar.app on 10.7+
[[NSWorkspace sharedWorkspace] launchApplication:@"Calendar"];

或者使用URL方案,使用OS X上的Calendar / iCal支持的URL(NSGod在下面的评论中指出),类似于URL Scheme for opening the iCal app at a date or event?

// Launches iCal (works at least with 10.6+)
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"ical://"]];

答案 2 :(得分:1)

您可以尝试使用EventKit创建所需日期和时间的EKCalendarItem实例,打开该事件,然后立即将其删除。如果时机合适,它甚至可能无法在用户的日历上显示闪烁。

这是另一个问题,但是在NSWorkspace有一个-openDate:方法之前,kludges是唯一的办法。

答案 3 :(得分:0)

正如在这个帖子中讨论的那样,似乎没有推出iCal的网址方案

URL Scheme for opening the iCal app at a date or event?