【问题标题】:Programmatically launch Mac Calendar.app (and choose specific date) from my app?从我的应用程序中以编程方式启动 Mac Calendar.app(并选择特定日期)?
【发布时间】:2013-04-08 16:07:44
【问题描述】:

我想在我的 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 之前,所有可能的方法都是变通方法。我的解决方案类似于杰的建议。我使用捆绑标识符来获取路径,因为我认为它不那么脆弱。即使他们(或用户)决定重命名应用程序,Apple 也不太可能在未来更改捆绑 ID。不幸的是,这种方法不能让我到达一个特定的日期。当我有更多时间时,我将进一步研究其他一些建议(使用 ical:// 等)。

更新 2: NSGod 在下面有一个很棒的答案,如果您的应用没有被沙盒化,它还会将日历打开到特定日期。

【问题讨论】:

    标签: macos cocoa calendar osx-mountain-lion


    【解决方案1】:

    注意:当你更新你使用的东西时,我仍在研究这个,但我会添加这个 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 并将日历更改为指定日期。

    【讨论】:

    • 很好的答案。在我接受了另一个答案之后,我不确定 Stackoverflow 的礼仪,但我确实对此表示赞同。
    • 天哪,这就是它!谢谢!
    • 这可以快速完成吗?我使用let celendarURL = URL(string: "calshow:\(interval)") 然后UIApplication.shared.open(celendarURL, options: [:], completionHandler: nil) 但如果我将其更改为ical 日历打开但不是日期
    【解决方案2】:

    所以现在听起来你要么不得不诉诸硬连线方法,例如

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

    或者使用 OS X 上的 Calendar/iCal 支持的 URL 方案(由 NSGod 在下面的 cmets 中指出)类似于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://"]];
    

    【讨论】:

    • 这就是我现在正在做的事情,但我不喜欢这样做,因为它非常脆弱,而且无法让我到达特定的日期。
    • 这不是很好但很实用 - 只要不重命名 iCal 你应该没问题。如何创建一个临时。 .ics 使用您想要的约会动态文件并使用 URL 方案打开该约会?
    • .ics 的想法很有趣。我会调查的。
    • 不直接相关,但包含指向 github 项目的链接,可以帮助您开始编写 .ics 文件:stackoverflow.com/questions/6290484/how-to-create-an-ics-file
    • @jay iCal 在 Lion 中重命名为 Calendar,只是说而已。
    【解决方案3】:

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

    这是另一种组合,但在 NSWorkspace 具有 -openDate: 方法之前,组合是唯一的资源。

    【讨论】:

    • 听起来对我来说是最强大的方法。
    • 你能解释一下我使用 EventKit 创建事件后如何从我的应用中“打开”事件吗?
    • Jay 在他的回答中的calshow:// 代码如果没有 EventKit 方法来“在默认查看器中显示此事件”或类似的东西,则应该这样做。除了临时事件“闪烁”的可能性之外,我能看到的唯一陷阱是潜在的时间问题,等待事件在日历中显示后再将其删除。需要实验。
    【解决方案4】:

    正如在此线程中所讨论的,似乎没有启动 iCal 的 url 方案

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-28
      • 2020-09-01
      相关资源
      最近更新 更多