Macos Swift-在启动时启动Mac应用程序

Macos Swift-在启动时启动Mac应用程序,macos,cocoa,swift,Macos,Cocoa,Swift,在过去的几周里,我一直在用swift编写一个mac应用程序,这既是为了进入mac编程,也是为了在我的工作场所迁移到它时练习swift。我目前正试图通过裁剪上提供的代码,将我的应用程序添加为“启动时启动”应用程序 经过几个小时的胡闹,我得出了以下结论: func itemRefInLoginItems () -> LSSharedFileListItemRef? { var itemRef: LSSharedFileListItemRef? = nil var itemURL

在过去的几周里,我一直在用swift编写一个mac应用程序,这既是为了进入mac编程,也是为了在我的工作场所迁移到它时练习swift。我目前正试图通过裁剪上提供的代码,将我的应用程序添加为“启动时启动”应用程序

经过几个小时的胡闹,我得出了以下结论:

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, 0, &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, kLSSharedFileListSessionLoginItems.takeRetainedValue(), NSMutableDictionary())

        let appURL = NSURL(fileURLWithPath: NSBundle.mainBundle().bundlePath) as CFURLRef
        let itemRef = LSSharedFileListInsertItemURL(loginItemsRef.takeRetainedValue(), kLSSharedFileListItemLast.takeRetainedValue(), nil, nil, appURL, nil, nil)
    }
}
func itemRefInLoginItems()->LSSharedFileListItemRef?
{
var itemRef:LSSharedFileListItemRef?=nil
var itemURL:非托管?
让appURL=NSURL.fileURLWithPath(NSBundle.mainBundle().bundlePath)
如果让loginItemsRef=LSSharedFileListCreate(kCFAllocatorDefault,kLSSharedFileListSessionLoginItems.takeRetainedValue(),NSMutableDictionary()){
var unretainedLoginItemsRef=loginItemsRef.takeUnretainedValue()
如果var loginItems=LSSharedFileListCopySnapshot(未维护的loginitemsRef,nil){
对于中的项(loginItems.takeRetainedValue()作为NSArray){
让currentItemRef=项目作为LSSharedFileListItemRef
变量outRef:FSRef
if(LSSharedFileListItemResolve(currentItemRef,0,&itemURL,nil)=noErr){
如果(appURL?.isEqual(itemURL?.takeRetainedValue())!=nil){//问题1
itemRef=currentItemRef
}
}
}
}
}
返回itemRef
}
func isLaunchAtStartup()->Bool{
设itemRef=self.itemRefInLoginItems()
返回itemRef!=nil
}
func makeLaunchAtStartup(){//Compile似乎落在这一行上。。。
if!self.isLaunchAtStartup(){
让loginItemsRef=LSSharedFileListCreate(kCFAllocatorDefault,kLSSharedFileListSessionLoginItems.takeRetainedValue(),NSMutableDictionary())
将appURL=NSURL(fileURLWithPath:NSBundle.mainBundle().bundlePath)设为CFURLRef
让itemRef=lsSharedFileListEnterItemUrl(loginItemsRef.takeRetainedValue(),kLSSharedFileListItemLast.takeRetainedValue(),nil,nil,appURL,nil,nil)
}
}
然而,我遇到了两个问题

问题1

斯威夫特不希望我将NSURL与CFURLRef进行比较。。。现在,我使用Xcode建议只是为了让应用程序运行,但我100%确定它没有达到我认为的效果。(见问题1)

在objective-c中,NSURL和CFURLRef(或CFURL)之间似乎允许进行免费桥接,但在尝试强制转换时,条件强制转换或任何形式的swift as(在此处插入正确字符)都不可避免地无法生成我的代码。我会遇到如下错误:

非托管不是NSURL的子类型:
如果appURL为非托管==itemURL

e、 t.c

问题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,
            kLSSharedFileListSessionLoginItems.takeRetainedValue(),
            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, 0, 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,
        kLSSharedFileListSessionLoginItems.takeRetainedValue(),
        nil
        ).takeRetainedValue() as LSSharedFileListRef?
    if loginItemsRef != nil {
        if shouldBeToggled {
            if let appUrl : CFURLRef = NSURL.fileURLWithPath(NSBundle.mainBundle().bundlePath) {
                LSSharedFileListInsertItemURL(
                    loginItemsRef,
                    itemReferences.lastReference,
                    nil,
                    nil,
                    appUrl,
                    nil,
                    nil
                )
                println("Application was added to login items")
            }
        } else {
            if let itemRef = itemReferences.existingReference {
                LSSharedFileListItemRemove(loginItemsRef,itemRef);
                println("Application was removed from login items")
            }
        }
    }
}
func应用程序sinStartupItems()->Bool{
返回(itemReferencesInLoginItems().existingReference!=nil)
}
func itemReferencesInLoginItems()->(现有引用:LSSharedFileListItemRef?,上次引用:LSSharedFileListItemRef?){
var itemUrl:UnsafeMutablePointer=UnsafeMutablePointer.alloc(1)
如果让appUrl:NSURL=NSURL.fileURLWithPath(NSBundle.mainBundle().bundlePath){
让loginItemsRef=LSSharedFileListCreate(
无
kLSSharedFileListSessionLoginItems.takeRetainedValue(),
无
).takeRetainedValue()作为LSSharedFileListRef?
如果loginItemsRef!=nil{
让loginItems:NSArray=LSSharedFileListCopySnapshot(loginItemsRef,nil)。将restainedValue()作为NSArray
println(“有\(loginItems.count)个登录项”)
将lastItemRef:LSSharedFileListItemRef=loginItems.lastObject设为LSSharedFileListItemRef
对于变量i=0;ifunc 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,
            kLSSharedFileListSessionLoginItems.takeRetainedValue(),
            nil
            ).takeRetainedValue() as LSSharedFileListRef?
        if loginItemsRef != nil {
            let loginItems: NSArray = LSSharedFileListCopySnapshot(loginItemsRef, nil).takeRetainedValue() as NSArray
            println("There are \(loginItems.count) login items")
            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 LSSharedFileListItemResolve(currentItemRef, 0, 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)
            }
            else
            {
                let addatstart: LSSharedFileListItemRef = kLSSharedFileListItemBeforeFirst.takeRetainedValue()

                return(nil,addatstart)
            }
        }
    }
    return (nil, nil)
}
let loginItems: NSArray = LSSharedFileListCopySnapshot(loginItemsRef, nil).takeRetainedValue() as NSArray
else
{
    let addatstart: LSSharedFileListItemRef = kLSSharedFileListItemBeforeFirst.takeRetainedValue()
    return(nil,addatstart)
}