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

sam*_*sam 4 macos cocoa calendar osx-mountain-lion

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

这适用于OS X Mountain Lion.

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

编辑:FWIW,这就是我现在正在做的事情:

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

我知道硬编码这样的道路是一个坏主意,这就是为什么我在问这个问题.

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

- (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];
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

NSG*_*God 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!");
}
Run Code Online (Sandbox Code Playgroud)

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

view calendar at date "Sunday, April 8, 2012 4:28:43 PM"
Run Code Online (Sandbox Code Playgroud)

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

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

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

SBCalendarApplication *calendarApp = [SBApplication
              applicationWithBundleIdentifier:@"com.apple.iCal"];
[calendarApp viewCalendarAt:[self.datePicker dateValue]];
Run Code Online (Sandbox Code Playgroud)

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