在过去的几个星期里,我一直在迅速编写一个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
我已经设法得到一个基于Brian Dunagan的Objective C方法的工作实现.
我也碰到你的编译器seg故障问题,但这是由于尝试转换为无效类型引起的;获得正确的类型修复了问题.
原文链接:https://www.f2er.com/swift/319806.html我也碰到你的编译器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") } } } }