osx – Swift – 获取Mac App在启动时启动

在过去的几个星期里,我一直在迅速编写一个mac应用程序,既可以进入mac编程,也可以在我的工作场所迁移到这个程序中.我正在尝试通过在 BDungan’s blog上提供的代码修改代码,将我的应用程序添加为“启动启动”应用程序

到目前为止,搞砸了好几个小时后,我想出了以下几点:

func itemRefInLoginItems () -> LSSharedFileListItemRef?
{
    var itemRef: LSSharedFileListItemRef? = nil
    var itemURL: Unmanaged<CFURLRef>?

    let appURL = NSURL.fileURLWithPath(NSBundle.mainBundle().bundlePath)


    if let loginItemsRef = LSSharedFileListCreate(kcfAllocatorDefault,kLSSharedFileListSessionLoginItems.takeRetainedValue(),NSMutableDictionary()) {

        var unretainedLoginItemsRef = loginItemsRef.takeUnretainedValue()

        if var loginItems = LSSharedFileListcopySnapshot(unretainedLoginItemsRef,nil) {

            for item in (loginItems.takeRetainedValue() as NSArray) {

                let currentItemRef = item as LSSharedFileListItemRef

                var outRef: FSRef
                if (LSSharedFileListItemResolve(currentItemRef,&itemURL,nil) == noErr) {

                    if (appURL?.isEqual(itemURL?.takeRetainedValue()) != nil) { //PROBLEM 1

                        itemRef = currentItemRef
                    }
                }
            }
        }
    }

    return itemRef
}

func isLaunchAtStartup () -> Bool {

    let itemRef = self.itemRefInLoginItems()
    return itemRef != nil
}

func makeLaunchAtStartup () { // Compile seems to fall down on this line...

    if !self.isLaunchAtStartup() {

        let loginItemsRef = LSSharedFileListCreate(kcfAllocatorDefault,NSMutableDictionary())

        let appURL = NSURL(fileURLWithPath: NSBundle.mainBundle().bundlePath) as CFURLRef
        let itemRef = LSSharedFileListInsertItemURL(loginItemsRef.takeRetainedValue(),kLSSharedFileListItemLast.takeRetainedValue(),nil,appURL,nil)
    }
}

我遇到两个问题.

问题1

Swift不希望我将NSURL与CFURLRef进行比较,现在我用Xcode的建议,只是为了让应用程序运行,但我100%肯定不会做我认为的事情. (见//问题1).

在目标c中,似乎在NSURL和CFURLRef(或CFURL)之间允许自由桥接,但是试图投射,有条件的转换或任何各种各样的swift,因为(插入正确的角色)接近我的代码不可避免地不会建立.我收到错误,如:

非管理不是NSURL的子类型:
如果appURL为非管理< CFURLRef> == itemURL

等等.

问题2

虽然这个代码当前没有提供任何警告或错误…当尝试编译我得到一个命令失败,由于信号:分段故障:11,这是坦白的…超出了我.

我已经设法得到一个基于Brian Dunagan的Objective C方法的工作实现.
我也碰到你的编译器seg故障问题,但这是由于尝试转换为无效类型引起的;获得正确的类型修复了问题.

我无法获取kLSSharedFileListItemLast以正确返回最后一个文件项引用,因为它总是会导致seg错误.为了解决这个问题,我修改了itemReferencesInLoginItems函数来返回一个元组的引用.

元组中的第一个项目是现有应用程序引用(如果存在),第二个项目是列表的最后一个引用.使用这种方法,我们可以避免不必依赖于kLSSharedFileListItemLast.

这里是代码,随意使用它!我想知道是否有办法让kLSSharedFileListItemLast工作.

func applicationIsInStartUpItems() -> Bool {
    return (itemReferencesInLoginItems().existingReference != nil)
}

func itemReferencesInLoginItems() -> (existingReference: LSSharedFileListItemRef?,lastReference: LSSharedFileListItemRef?) {
    var itemUrl : UnsafeMutablePointer<Unmanaged<CFURL>?> = UnsafeMutablePointer<Unmanaged<CFURL>?>.alloc(1)
    if let appUrl : NSURL = NSURL.fileURLWithPath(NSBundle.mainBundle().bundlePath) {
        let loginItemsRef = LSSharedFileListCreate(
            nil,nil
        ).takeRetainedValue() as LSSharedFileListRef?
        if loginItemsRef != nil {
            let loginItems: NSArray = LSSharedFileListcopySnapshot(loginItemsRef,nil).takeRetainedValue() as NSArray
            println("There are \(loginItems.count) login items")
            let lastItemRef: LSSharedFileListItemRef = loginItems.lastObject as LSSharedFileListItemRef
            for var i = 0; i < loginItems.count; ++i {
                let currentItemRef: LSSharedFileListItemRef = loginItems.objectAtIndex(i) as LSSharedFileListItemRef
                if LSSharedFileListItemResolve(currentItemRef,itemUrl,nil) == noErr {
                    if let urlRef: NSURL =  itemUrl.memory?.takeRetainedValue() {
                        println("URL Ref: \(urlRef.lastPathComponent)")
                        if urlRef.isEqual(appUrl) {
                            return (currentItemRef,lastItemRef)
                        }
                    }
                } else {
                    println("UnkNown login application")
                }
            }
            //The application was not found in the startup list
            return (nil,lastItemRef)
        }
    }
    return (nil,nil)
}

func toggleLaunchAtStartup() {
    let itemReferences = itemReferencesInLoginItems()
    let shouldBetoggled = (itemReferences.existingReference == nil)
    let loginItemsRef = LSSharedFileListCreate(
        nil,nil
        ).takeRetainedValue() as LSSharedFileListRef?
    if loginItemsRef != nil {
        if shouldBetoggled {
            if let appUrl : CFURLRef = NSURL.fileURLWithPath(NSBundle.mainBundle().bundlePath) {
                LSSharedFileListInsertItemURL(
                    loginItemsRef,itemReferences.lastReference,appUrl,nil
                )
                println("Application was added to login items")
            }
        } else {
            if let itemRef = itemReferences.existingReference {
                LSSharedFileListItemRemove(loginItemsRef,itemRef);
                println("Application was removed from login items")
            }
        }
    }
}

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...