1. 程式人生 > >Mac os上App開機自動啟動

Mac os上App開機自動啟動

Mac OS上執行的App,想要支援使用者登入後App自動啟動的功能,可以使用Service Management Framework 或 Shared File List實現。對於沙箱開啟的應用,蘋果推薦的做法是使用Service Management Framework;對於沙箱未開啟的應用,蘋果推薦使用Shared File List。Service Management Framework對於沙箱未開啟的APP也是可以實現登入後自動啟動的。

本文將介紹通過Service Management Framework來實現App自定啟動的方法。基本方式是建立一個輔助啟動的"Helper Application",將其註冊到系統中,在使用者登入後通過它來啟動主App。

The Helper App

在工程中新增一個Cocoa Application型別的target。

刪除AutoLaunchHelper中無用的內容:

  • 移除ViewController.h和ViewController.m
  • 移除Main.storyboard中ViewController
  • 移除Main.storyboard中WindowController

AutoLaunchHelper的Info.plist中,將Application is background only設定為 Yes。

在AutoLaunchHelper的AppDelegate.m中新增程式碼,用來啟動主App。

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    
    NSArray<NSRunningApplication *> *runningApps = [[NSWorkspace sharedWorkspace] runningApplications];
    
    __block BOOL isRunning = NO;
    [runningApps enumerateObjectsUsingBlock:^(NSRunningApplication * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([obj.bundleIdentifier isEqualToString:@"your.domain.AutoLaunchMain"]) {
            isRunning = YES;
            *stop = YES;
        }
    }];
    
    if (!isRunning) {

        NSArray<NSString *> *pathComponents = [[[NSBundle mainBundle] bundlePath] pathComponents];
        NSMutableArray *mutablePathComponents = [[NSMutableArray alloc] initWithArray:pathComponents];
        [mutablePathComponents removeLastObject];
        [mutablePathComponents removeLastObject];
        [mutablePathComponents removeLastObject];
        
        [mutablePathComponents addObject:@"MacOS"];
        [mutablePathComponents addObject:@"AutoLaunchMain"];
        
        NSString *mainAppPath = [NSString pathWithComponents:mutablePathComponents];
        [[NSWorkspace sharedWorkspace] launchApplication:mainAppPath];
    }
        
}

在AutoLaunchHelper的Build Settings中,將Skip Install設定為Yes。

檢視沙箱設定,預設情況下,沙箱是開啟的。

注:保證AutoLaunchHelper和AutoLaunchMain沙箱設定是相同的,都開啟或者都關閉,否則影響執行效果。

Main App

AutoLaunchMain target中新增ServiceManagement庫

進入AutoLaunchMain的AppDelegate.m檔案,新增如下程式碼。通過SMLoginItemSetEnabled方法啟用AutoLaunchHelper。

#import "AppDelegate.h"
#import <ServiceManagement/ServiceManagement.h>

@interface AppDelegate ()
@property (nonatomic, strong) NSStatusItem *statusItem;
@end

@implementation AppDelegate


- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // 啟動後在狀態列顯示“AutoLaunchMain”
    self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
    self.statusItem.button.title = @"AutoLaunchMain";
    
    // 啟用AutoLaunchHelper
    CFStringRef aCFString = (__bridge_retained CFStringRef)@"your.domain.AutoLaunchHelper";
    SMLoginItemSetEnabled(aCFString, true);
    CFRelease(aCFString);
}

為驗證自動啟動是否生效,給AutoLaunchMain在狀態列添加了名字為AutoLaunchMain的按鈕。機器重啟使用者登入後,狀態列有AutoLaunchMain名字的按鈕顯示,證明自動成功,否則自動啟動失敗。

為AutoLaunchMain target新增Copy Files Phase。

具體設定為:

  • Destination: Wrapper
  • Subpath: Contents/Library/LoginItems
  • 新增helper.app檔案

檢查AutoLaunchMain的沙箱設定,保證AutoLaunchHelper和AutoLaunchMain沙箱設定是相同的。

測試

1. 編譯AutoLaunchMain

2.在Finder中找到編譯結果AutoLaunchMain.app

3.雙擊AutoLaunchMain.app啟動主應用,啟動成功後狀態列中顯示AutoLaunchMain按鈕

4.重啟Mac,使用者登入後,檢視狀態列是否有AutoLaunchMain按鈕,有表示自動啟動成功,否則表示自動啟動失敗。