我们使用新的 MacOS Ventura SMAppService 功能为用户提供“登录时启动”功能。我们以非常简单的方式做到这一点:
SMAppService.mainApp.register()
如果我们在启动/登录时启动,我们希望进行一些特定的处理,而如果只是定期启动,我们就不会这样做。具体来说,如果在启动时作为菜单栏应用程序启动,我们的用户不希望看到任何窗口/UI。
有什么方法可以检测我们的应用程序是否已在启动/登录时启动,而不是常规用户启动的启动?
也许是命令行参数或者我们可以寻找特殊的父进程?似乎没有办法传递命令行参数,而且我们不知道可以寻找任何特殊的父进程。
回答我自己的问题,事实证明这是可能的。受到这个旧答案的启发,它适用于非 Ventura API/范式。
在您的 AppDelegate 中:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSAppleEventDescriptor* event = NSAppleEventManager.sharedAppleEventManager.currentAppleEvent;
BOOL launchedAsLoginItem = (event.eventID == kAEOpenApplication &&
[event paramDescriptorForKeyword:keyAEPropData].enumCodeValue == keyAELaunchedAsLogInItem);
...
}
和斯威夫特:
let event = NSAppleEventManager.shared().currentAppleEvent
let launchedAsLogInItem =
event?.eventID == kAEOpenApplication &&
event?.paramDescriptor(forKeyword: keyAEPropData)?.enumCodeValue == keyAELaunchedAsLogInItem
在您的助手应用程序中
- (void)applicationDidFinishLaunching: (NSNotification *)aNotification
{
// Prepare a dictionary to pass to the App
NSDictionary *env = @{@"launcher" : [[NSBundle mainBundle] bundleIdentifier]};
NSWorkspaceOpenConfiguration *configuration = [NSWorkspaceOpenConfiguration new];
[configuration setEnvironment:env];
// Let's say your bundleIdentifier is "com.yourdomain.Helper"
// I used "--a" but you can use your arguments
[configuration setArguments:@[@"--a", [[NSBundle mainBundle] bundleIdentifier]]];
[configuration setPromptsUserIfNeeded:YES];
// This is the path to your App
NSArray *pathComponents = [[[NSBundle mainBundle] bundlePath] pathComponents];
pathComponents = [pathComponents subarrayWithRange:NSMakeRange(0, pathComponents.count - 4)];
NSString *path = [NSString pathWithComponents:pathComponents];
// Now the helper launches your App
[[NSWorkspace sharedWorkspace] openApplicationAtURL:[NSURL fileURLWithPath:path]
configuration:configuration completionHandler:^(NSRunningApplication* app, NSError* error)
{
if(error){
NSLog(@"•••• Helper applicationDidFinishLaunching: Failed to run the app: %@", error.localizedDescription);
}
else{
//NSLog(@"•••• Helper applicationDidFinishLaunching: OK to run the app.");
}
exit(0);
}];
}
在您的应用程序中
- (void)applicationDidFinishLaunching:(NSNotification*)aNotification
{
NSArray *arguments = [[NSProcessInfo processInfo] arguments];
NSLog(@"•••• App applicationDidFinishLaunching!!! >>>>>>>>>> arguments %@", arguments);
// You will get the log with an array like the following one, containing
// The path to your app
// The argument --a you defined above
// The Helper identifier you defined above
/*
•••• App applicationDidFinishLaunching!!! >>>>>>>>>> arguments (
"/PathToYourApp.app/Contents/MacOS/YourApp",
"--a",
"com.yourdomain.Helper"
)
*/
BOOL launchedByHelper = [arguments indexOfObject:@"com.yourdomain.Helper"] != NSNotFound;
if(launchedByHelper){
// Here you can run your code when the app
// has been launched by the Helper
}
else{
}
}