cocoa - que - importancia de la vision de una empresa



Registrarse como elemento de inicio de sesión con Cocoa? (5)

Consulte aquí un ejemplo de código abierto: https://github.com/invariant/rhpnotifier (LoginItem.m, LoginItem.h)

Google me dio: http://developer.apple.com/samplecode/LoginItemsAE/index.html

Y pensé que debe haber una mejor manera que usar eventos de AppleScript.

Así que descargué las fuentes de Growl. Usan las fuentes exactas de ese artículo de desarrollador de Apple.

¿Hay una mejor manera?

(Me refiero a Elementos de inicio de sesión en Cuentas en Preferencias del sistema, es decir, hacer que mi programa se inicie cuando el usuario se conecta, mediante programación)


Esto funciona en xcode 5.

- (BOOL)isLaunchAtStartup {
    // 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;
}

- (void)toggleLaunchAtStartup {
    // Toggle the state.
    BOOL shouldBeToggled = ![self isLaunchAtStartup];
    // Get the LoginItems list.
    LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
    if (loginItemsRef == nil) return;
    if (shouldBeToggled) {
        // Add the app to the LoginItems list.
        CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
        LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL);
        if (itemRef) CFRelease(itemRef);
    }
    else {
        // Remove the app from the LoginItems list.
        LSSharedFileListItemRef itemRef = [self itemRefInLoginItems];
        LSSharedFileListItemRemove(loginItemsRef,itemRef);
        if (itemRef != nil) CFRelease(itemRef);
    }
    CFRelease(loginItemsRef);
}

- (LSSharedFileListItemRef)itemRefInLoginItems {
    LSSharedFileListItemRef res = nil;

    // Get the app's URL.
    NSURL *bundleURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
    // 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 (id item in loginItems) {
        LSSharedFileListItemRef itemRef = (__bridge LSSharedFileListItemRef)(item);
        CFURLRef itemURLRef;
        if (LSSharedFileListItemResolve(itemRef, 0, &itemURLRef, NULL) == noErr) {
            // Again, use toll-free bridging.
            NSURL *itemURL = (__bridge NSURL *)itemURLRef;
            if ([itemURL isEqual:bundleURL]) {
                res = itemRef;
                break;
            }
        }
    }
    // Retain the LoginItem reference.
    if (res != nil) CFRetain(res);
    CFRelease(loginItemsRef);
    CFRelease((__bridge CFTypeRef)(loginItems));

    return res;
}


Lo hago en una aplicación que estoy escribiendo :

Consulte UKLoginItemRegistry para obtener una forma fácil de hacerlo de forma pragmática. Afaik, no hay forma de que Tiger haga esto sin Apple Events; en Leopard hay una mejor manera, pero si usas UKLoginItemRegistry realmente no hay problema. Aquí está el código completo para implementar un elemento de menú "Abrir al iniciar sesión"

+ (bool)isAppSetToRunAtLogon {
  int ret = [UKLoginItemRegistry indexForLoginItemWithPath:[[NSBundle mainBundle] bundlePath]];
  NSLog(@"login item index = %i", ret);
  return (ret >= 0);
}

- (IBAction)toggleOpenAtLogon:(id)sender {
  if ([PopupController isAppSetToRunAtLogon]) {
    [UKLoginItemRegistry removeLoginItemWithPath:[[NSBundle mainBundle] bundlePath]];
  } else {
    [UKLoginItemRegistry addLoginItemWithPath:[[NSBundle mainBundle] bundlePath] hideIt: NO];
  }
}





cocoa