微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在OS X 10.11上启动Swift Cocoa应用程序

我需要编写一个函数,将我的应用程序添加到OS X 10.11上的Startup项目中.这就是我现在所发现的:
func applicationIsInStartUpItems() -> Bool {
    return (itemReferencesInLoginItems().existingReference != nil)
}

func itemReferencesInLoginItems() -> (existingReference: LSSharedFileListItemRef?,lastReference: LSSharedFileListItemRef?) {

    if let appUrl : NSURL = NSURL.fileURLWithPath(NSBundle.mainBundle().bundlePath) {
        let loginItemsRef = LSSharedFileListCreate(nil,kLSSharedFileListSessionLoginItems.takeRetainedValue(),nil).takeRetainedValue() as LSSharedFileListRef?
        if loginItemsRef != nil {
            let loginItems: NSArray = LSSharedFileListcopySnapshot(loginItemsRef,nil).takeRetainedValue() as NSArray
            if(loginItems.count > 0) {
                let lastItemRef: LSSharedFileListItemRef = loginItems.lastObject as! LSSharedFileListItemRef
                for var i = 0; i < loginItems.count; ++i {
                    let currentItemRef: LSSharedFileListItemRef = loginItems.objectAtIndex(i) as! LSSharedFileListItemRef
                    if let itemURL = LSSharedFileListItemcopyResolvedURL(currentItemRef,nil) {
                        if (itemURL.takeRetainedValue() as NSURL).isEqual(appUrl) {
                            return (currentItemRef,lastItemRef)
                        }
                    }
                }
                return (nil,lastItemRef)
            } else {
                let addatstart: LSSharedFileListItemRef = kLSSharedFileListItemBeforeFirst.takeRetainedValue()
                return(nil,addatstart)
            }
        }
    }
    return (nil,nil)
}

func toggleLaunchAtStartup() {
    let itemReferences = itemReferencesInLoginItems()
    let shouldBetoggled = (itemReferences.existingReference == nil)
    if let loginItemsRef = LSSharedFileListCreate( nil,nil).takeRetainedValue() as LSSharedFileListRef? {
        if shouldBetoggled {
            if let appUrl : CFURLRef = NSURL.fileURLWithPath(NSBundle.mainBundle().bundlePath) {
                LSSharedFileListInsertItemURL(loginItemsRef,itemReferences.lastReference,nil,appUrl,nil)
            }
        } else {
            if let itemRef = itemReferences.existingReference {
                LSSharedFileListItemRemove(loginItemsRef,itemRef);
            }
        }
    }
}

但是OS X 10.11中不推荐使用LSSharedFileListCreate,LSSharedFileListInsertItemURL,LSSharedFileListItemRemove,kLSSharedFileListItemBeforeFirst,LSSharedFileListItemcopyResolvedURL,LSSharedFileListcopySnapshot,kLSSharedFileListSessionLoginItems.如何在最新版本的Mac OS上运行?如何更改或重写此代码

在Swift 3.0中它看起来像这样:

在您的主应用程序AppDelegate中:

func applicationDidFinishLaunching(_ aNotification: Notification) {
    // Check if the launcher app is started
    var startedAtLogin = false
    for app in NSWorkspace.shared().runningApplications {
        if app.bundleIdentifier == NCConstants.launcherApplicationIdentifier {
            startedAtLogin = true
        }
    }

    // If the app's started,post to the notification center to kill the launcher app
    if startedAtLogin {
        distributedNotificationCenter.default().postNotificationName(NCConstants.KILLME,object: Bundle.main.bundleIdentifier,userInfo: nil,options: distributedNotificationCenter.Options.deliverImmediately)
    }
}

在Launcher应用程序AppDelegate中:

func applicationDidFinishLaunching(_ aNotification: Notification) {

    let mainAppIdentifier = "<main-app-bundle-id>"
    let running = NSWorkspace.shared().runningApplications
    var alreadyRunning = false

    // loop through running apps - check if the Main application is running
    for app in running {
        if app.bundleIdentifier == mainAppIdentifier {
            alreadyRunning = true
            break
        }
    }

    if !alreadyRunning {
        // Register for the notification killme
        distributedNotificationCenter.default().addobserver(self,selector: #selector(self.terminate),name: NCConstants.KILLME,object: mainAppIdentifier)

        // Get the path of the current app and navigate through them to find the Main Application
        let path = Bundle.main.bundlePath as Nsstring
        var components = path.pathComponents
        components.removeLast(3)
        components.append("MacOS")
        components.append("<your-app-name>")

        let newPath = Nsstring.path(withComponents: components)

        // Launch the Main application
        NSWorkspace.shared().launchApplication(newPath)
    }
    else {
        // Main application is already running
        self.terminate()
    }

}

func terminate() {
    print("Terminate application")
    NSApp.terminate(nil)
}

最后,在主应用程序中,我添加一个带有切换按钮的用户界面.用户可以选择是否在登录时启动应用程序.该选项存储在UserDefaults中.
在视图控制器中:

@IBAction func toggleLaunchAtLogin(_ sender: Any) {
    if toggleOpenAppLogin.selectedSegment == 0 {
        if !SMLoginItemSetEnabled(NCConstants.launcherApplicationIdentifier as CFString,true) {
            print("The login item was not successfull")
            toggleOpenAppLogin.setSelected(true,forSegment: 1)
        }
        else {
            UserDefaults.standard.set("true",forKey: "appLoginStart")
        }
    }
    else {
        if !SMLoginItemSetEnabled(NCConstants.launcherApplicationIdentifier as CFString,false) {
            print("The login item was not successfull")
            toggleOpenAppLogin.setSelected(true,forSegment: 0)
        }
        else {
            UserDefaults.standard.set("false",forKey: "appLoginStart")
        }
    }

}

我希望这可以帮助别人.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐