objective-c - Mac OS X : start on launch while in app store?

标签 objective-c macos cocoa

我需要在系统启动时启动我的应用程序,但是问题是:它已经在App Store中,因此我必须遵循一些规则,例如使用沙箱。这导致所需功能失败,例如LSSharedFileListInsertItemURL和SMLoginItemSetEnabled。在这种情况下,我该怎么办?

最佳答案

最近,我经历了相同的过程,不幸的是,使用沙箱比以前做起来要容易得多。我制作了一个测试应用程序,其中包含非常详细的说明,现在为on Github

笔记

此演示应用程序和您的应用程序仅在中部署了,最好在/Applications/MyGreat.app中部署,并且将无法从Xcode调试文件夹可靠地运行

项目设定

这些是我的项目的设置,与该实现完美配合。

  • 创建一个启用了ARC的新项目
  • 将您的主应用程序和帮助程序应用程序都沙箱化(如果您还没有创建一个帮助程序,我们很快就会使用它)我还启用了代码签名
  • 因为这只是一个测试应用程序,所以我没有主应用程序或助手
  • 的有效权利
  • (如果还没有的话),创建一个助手应用程序。转到您的项目设置,然后单击“添加目标”,选择一个Cocoa应用程序。将其命名为MyAwesomeProjectHelper之类的名称,同时还要启用ARC。 (我将其“App Store类别”留为空白)
  • 现在选择主应用程序的目标。转到构建阶段->添加构建阶段->添加复制文件。
  • 将目标更改为包装器。仅当未选中安装时,才使Subpath Contents/Library/LoginItems离开Copy。将您的帮助程序从左侧的“产品”拖到表格 View 中。

  • 主要应用程式程式码设定
  • 将ServiceManagement.framework导入到您的主应用程序(而不是您的助手)中,并将#import <ServiceManagement/ServiceManagement.h>包括在您的.h文件中
  • 从Github获取StartAtLoginController。这是Alex Zielenski易于使用的类,用于处理添加,删除和查询登录项的复杂性。将StartAtLoginController.h导入到您的h文件中。
  • 创建想要控制该设置的任何接口(interface)。如果您的应用程序自动启用了此功能,则Mac App Store中将拒绝该功能(根据准则#2.26)
  • 实现诸如- (IBAction)checkChanged:(id)sender之类的方法,我将一个简单的复选框与StandardUserDefaults绑定(bind)在一起。 (如果选择执行其他操作,则此实现可能会有所不同。)我还将复选框绑定(bind)到IBOutlet NSButton *loginCheck;以确定其状态。这也可以通过[[NSUserDefaults standardUserDefaults] boolForKey:YourKey]
  • 完成
  • 在.m文件中实现与此类似的代码。
    StartAtLoginController *loginController = [[StartAtLoginController alloc] init];
    [loginController setBundle:[NSBundle bundleWithPath:[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Contents/Library/LoginItems/HelperApp.app"]]]; 
    // Change "HelperApp.app" to the name of your helper
    
    if ([loginCheck state]) {
        if (![loginController startAtLogin]) {
            [loginController setStartAtLogin: YES];
        }
    } else {
        if ([loginController startAtLogin]) {
            [loginController setStartAtLogin:NO];
        }
    }
    
  • 就是这样。正如您在该项目中看到的那样,您可能还需要使用其他一些方法,例如:
    if ([loginController startAtLogin]) {
        NSLog(@"Error");
    }
    

    在启用或禁用设置以确保其正常工作后进行检查。或这个:
    BOOL startsAtLogin = [loginController startAtLogin];
    if (startsAtLogin) {
        // Do stuff
    }
    

    如果启用了登录帮助器,请执行某些操作。

  • 助手应用程序代码设置

    确保在您的实现中大力测试此代码。
  • 通过导航到默认情况下位于“支持文件”组中的HelperApp.plist,使您的助手应用程序成为UIElement。在底部添加一行,将键Application is agent (UIElement)YES作为值(这将抑制应用程序每次用户启用登录时都会启动停靠图标)我还删除了所有内容,除了界面构建器
  • 中的“应用程序委托(delegate)”
  • 删除默认方法- (void)applicationDidFinishLaunching:(NSNotification *)aNotification并将其替换为- (void)applicationWillFinishLaunching:(NSNotification *)aNotification
  • 在此方法中,实现类似于此的代码。
    NSString *appPath = [[[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent];
    // This string takes you from MyGreat.App/Contents/Library/LoginItems/MyHelper.app to MyGreat.App This is an obnoxious but dynamic way to do this since that specific Subpath is required
    NSString *binaryPath = [[NSBundle bundleWithPath:appPath] executablePath]; // This gets the binary executable within your main application
    [[NSWorkspace sharedWorkspace] launchApplication:binaryPath];
    [NSApp terminate:nil];
    

    此代码找到您的主应用程序,确定它是二进制可执行文件(需要在沙箱中启动该应用程序)打开您的应用程序,然后退出
  • 就是这样。

  • 部署

    为自己或Mac App Store部署应用程序时,您应该做的最后一件事是从“已存档”项中删除“助手”应用程序。为此,请导航至HelperApp的目标->build设置->跳过安装,然后为发布设置为是。 Apple在(http://developer.apple.com/library/ios/#documentation/ToolsLanguages/Conceptual/Xcode4UserGuide/000-About_Xcode/about.html)提供了更多信息。

    关于objective-c - Mac OS X : start on launch while in app store?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11536477/

    相关文章:

    c++ - Cocoa 选择器的行为可以用 C++ 重新实现吗?

    iOS 如何在没有自动布局的情况下设置动态 tableview 单元格高度?

    ios - 为什么给 addArcWithCenter 一个 0 度的 startAngle 会使它从 90 度开始?

    ios - 现有项目的 XCTest

    iphone - 如何解析Json对象

    c++ - 错误启动过程。无法创建 pty - Mac 上的 Eclipse

    macos - 具有自定义 View 的 NSCollectionViewItem

    php - 将 xdebug 与 Netbeans 结合使用来处理 php - 套接字异常

    cocoa - 创建自定义框架的步骤

    iphone - 如何跟踪 AVAssetWriter 的写入进度?