Ios 在Mac OS El Capitan中安装后自动启动应用程序

Ios 在Mac OS El Capitan中安装后自动启动应用程序,ios,objective-c,macos,osx-elcapitan,xcode7.1,Ios,Objective C,Macos,Osx Elcapitan,Xcode7.1,我正在开发一个OSX应用程序,它将在应用程序商店外发布。我已经存档并创建了pkg文件,但当我安装应用程序时,它不会自动启动。我必须从启动板手动启动它。下面是我在appdelegate中添加的代码,用于在启动时显示它 - (void)installAppIntoLoginItems { if (![self appIsInLoginItems]) { // Get the LoginItems list. LSSharedFileListRef login

我正在开发一个OSX应用程序,它将在应用程序商店外发布。我已经存档并创建了pkg文件,但当我安装应用程序时,它不会自动启动。我必须从启动板手动启动它。下面是我在appdelegate中添加的代码,用于在启动时显示它

- (void)installAppIntoLoginItems {

    if (![self appIsInLoginItems]) {
        // Get the LoginItems list.
        LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
        if (loginItemsRef == nil) return;

        // Add the app to the LoginItems list.
        LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, (__bridge CFURLRef)helperAppURL, NULL, NULL);
        if (itemRef) {
            CFRelease(itemRef);
        }
        CFRelease(loginItemsRef);
    }
    else {
        // App is in the LoginItems List
        NSLog(@"App is already in LoginItems List");
    }
}



- (BOOL) appIsInLoginItems {
    // See if the app is currently in LoginItems.
    LSSharedFileListItemRef itemRef = [self itemRefInLoginItems];
    // Store away that boolean.
    BOOL isInList = (itemRef != nil);
    // Release the reference if it exists.
    if (itemRef != nil) CFRelease(itemRef);

    return isInList;
}


- (LSSharedFileListItemRef)itemRefInLoginItems {
    LSSharedFileListItemRef itemRef = nil;
    CFURLRef itemUrl = NULL;

    // Get the LoginItems list.
    LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
    if (loginItemsRef == nil) return nil;
    // Iterate over the LoginItems.
    NSArray *loginItems = (__bridge NSArray *)LSSharedFileListCopySnapshot(loginItemsRef, nil);
    for (int currentIndex = 0; currentIndex < [loginItems count]; currentIndex++) {
        // Get the current LoginItem and resolve its URL.
        LSSharedFileListItemRef currentItemRef = (__bridge LSSharedFileListItemRef)[loginItems objectAtIndex:currentIndex];
//        if (LSSharedFileListItemResolve(currentItemRef, 0, (CFURLRef *) &itemUrl, NULL) == noErr) { //Replacing deprecated method
          if( LSSharedFileListItemCopyResolvedURL(currentItemRef, 0, NULL) == noErr) {
            // Compare the URLs for the current LoginItem and the app.
            if ([(__bridge NSURL*)itemUrl isEqual:helperAppURL]) {
                // Save the LoginItem reference.
                itemRef = currentItemRef;
            }
        }
    }
    // Retain the LoginItem reference.
    if (itemRef != nil) CFRetain(itemRef);
    // Release the LoginItems lists.
    CFRelease(loginItemsRef);

    return itemRef;
}
-(无效)installAppIntoLoginItems{
如果(![self-appIsInLoginItems]){
//获取LoginItems列表。
LSSharedFileListRef loginItemsRef=LSSharedFileListCreate(NULL,kLSSharedFileListSessionLoginItems,NULL);
如果(loginItemsRef==nil)返回;
//将应用程序添加到LoginItems列表。
LSSharedFileListItemRef itemRef=lsSharedFileListItemUrl(loginItemsRef,kLSSharedFileListItemLast,NULL,NULL,(u-bridge CFURLRef)helperAppURL,NULL,NULL);
if(itemRef){
CFRelease(itemRef);
}
CFRelease(loginItemsRef);
}
否则{
//应用程序位于LoginItems列表中
NSLog(@“应用程序已在LoginItems列表中”);
}
}
-(BOOL)应用项目{
//查看应用程序当前是否在LoginItems中。
LSSharedFileListItemRef=[self-itemRefInLoginItems];
//把那个布尔存储起来。
BOOL isInList=(itemRef!=nil);
//释放引用(如果存在)。
如果(itemRef!=nil)CFRelease(itemRef);
返回isInList;
}
-(LSSharedFileListItemRef)itemRefInLoginItems{
LSSharedFileListItemRef=nil;
CFURLRef itemUrl=NULL;
//获取LoginItems列表。
LSSharedFileListRef loginItemsRef=LSSharedFileListCreate(NULL,kLSSharedFileListSessionLoginItems,NULL);
如果(loginItemsRef==nil)返回nil;
//迭代登录项。
NSArray*loginItems=(\uu桥NSArray*)LSSharedFileListCopySnapshot(loginItemsRef,nil);
对于(int currentIndex=0;currentIndex<[loginItems计数];currentIndex++){
//获取当前登录项并解析其URL。
LSSharedFileListItemRef currentItemRef=(u桥LSSharedFileListItemRef)[loginItems对象索引:currentIndex];
//if(LSSharedFileListItemResolve(currentItemRef,0,(CFURLRef*)&itemUrl,NULL)=noErr){//替换不推荐使用的方法
if(lsSharedFileListItemCopySolveDurl(currentItemRef,0,NULL)==noErr){
//比较当前登录项和应用程序的URL。
if([(\uuuu-bridge-NSURL*)itemUrl isEqual:helperAppURL]){
//保存LoginItem引用。
itemRef=currentItemRef;
}
}
}
//保留LoginItem引用。
如果(itemRef!=nil)CFRetain(itemRef);
//释放LoginItems列表。
CFRelease(loginItemsRef);
返回itemRef;
}

我是否必须使用任何其他替代方案?是否也可以参考任何示例?

您可以使用launch agent:


我想把它作为登录项的好处是,用户自己可能知道如何删除它。如果你使用LaunchAgent,你可能需要建立一个“登录时启动”将首选项选项插入应用程序。

我能够使用SMLoginItemSetEnabled方法解决登录时自动启动应用程序的问题,并且能够使用postinstall脚本实现安装后自动启动

     if (!SMLoginItemSetEnabled ((__bridge CFStringRef)helperAppBundleIdentifier, YES))
         {
                NSAlert *alert = [NSAlert alertWithMessageText:@"An error ocurred" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"Couldn't add Helper App to launch at login item list."];
                [alert runModal];
            }

我的应用程序仅用于在菜单栏中显示,它不会出现在dock上。一旦我手动启动它,它就会出现并添加到登录项目中。在安装我的应用程序后,我应该如何触发它启动?