在Swift 2.2中使用Spotlight列出El Capitan上已安装的应用程序 [英] List installed Applications on El Capitan using Spotlight in Swift 2.2

查看:59
本文介绍了在Swift 2.2中使用Spotlight列出El Capitan上已安装的应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在构建一个Mac应用程序,将来应该可以在OS X上终止并启动该应用程序.

I am currently building a mac app which in the future should be able to kill and start apps on OS X.

为此,我需要找到一种方法来获取计算机上所有已安装应用程序的列表.

For that to be possible, I need to find a way to get a list of all the installed applications on the machine.

我已经进行了大量研究,并决定将Spotlight与NSMetadataQuery结合使用以获取列表.

I already did quite a bit of research and have decided to use Spotlight with NSMetadataQuery to be able to get the list.

我能够以编程方式找到

I was able to find this post about the mentioned topic and started to implement the functionality in Swift 2.2 (the weapon of choice for the project). With a bit of translation I was able to make it work and the code now successfully builds and runs. During runtime, however, I seem to be having a problem with the query itself:

<NSMetadataQuery: 0x6080000e3880> is being deallocated without first calling -stopQuery. To avoid race conditions, you should first invoke -stopQuery on the run loop on which -startQuery was called

这是我当前正在使用的代码.

This is the code I am currently using.

    public func doSpotlightQuery() {
    query = NSMetadataQuery()
    let predicate = NSPredicate(format: "kMDItemKind ==[c] %@", "Application")
    let defaultNotificationCenter = NSNotificationCenter()
    defaultNotificationCenter.addObserver(self, selector: #selector(queryDidFinish(_:)), name: NSMetadataQueryDidFinishGatheringNotification, object: nil)
    query.predicate = predicate
    query.startQuery()
}

public func queryDidFinish(notification: NSNotification) {
    for i in 0 ... query.resultCount {
        print(query.resultAtIndex(i).valueForAttribute(kMDItemDisplayName as String))
    }
}

测试

mdfind "kMDItemKind == 'Application'"

我的Mac终端中的

命令(具有各种变体)也没有给我任何结果,这使我想到了这个问题:

command (with variations of all kind) in the terminal of my mac didn't give me any results either which brings me to my question:

我是否以错误的方式设置了查询,或者此命令在"El Capitan"中不起作用?

Did I set up the query in a wrong way or does this command not work in 'El Capitan'?

有人可以帮我找到我的错误吗?我肯定很想最终完成这项工作!

Can someone please help me find my mistake? I'd sure love to finally make this work!

推荐答案

dealloc消息似乎查询缺少强引用.

The dealloc message seems like the query is missing a strong reference.

var query: NSMetadataQuery? {
    willSet {
        if let query = self.query {
            query.stopQuery()
        }
    }
}

public func doSpotlightQuery() {
    query = NSMetadataQuery()
    let predicate = NSPredicate(format: "kMDItemKind ==[c] %@", "Application")
    let defaultNotificationCenter = NSNotificationCenter()
    defaultNotificationCenter.addObserver(self, selector: #selector(queryDidFinish(_:)), name: NSMetadataQueryDidFinishGatheringNotification, object: nil)
    query?.predicate = predicate
    query?.startQuery()
}

public func queryDidFinish(notification: NSNotification) {
    guard let query = notification.object as? NSMetadataQuery else {
        return
    }

    for i in 0 ... query.resultCount {
        print(query.resultAtIndex(i).valueForAttribute(kMDItemDisplayName as String))
    }
}

根据约翰的评论,我建议使用其他谓词,因为kMDItemKind是本地化的键.此处

I'd suggest using a different predicate as kMDItemKind is a localized key according to John's comment here

因此 let predicate = NSPredicate(格式:"kMDItemContentType =='com.apple.application-bundle'")可以满足我们的工作.

so let predicate = NSPredicate(format: "kMDItemContentType == 'com.apple.application-bundle'") would work for what we're doing.

在Swift 3中,它可能看起来像这样:

In swift 3 this could look like this:

var query: NSMetadataQuery? {
    willSet {
        if let query = self.query {
            query.stop()
        }
    }
}

public func doSpotlightQuery() {
    query = NSMetadataQuery()
    let predicate = NSPredicate(format: "kMDItemContentType == 'com.apple.application-bundle'")
    NotificationCenter.default.addObserver(self, selector: #selector(queryDidFinish(_:)), name: NSNotification.Name.NSMetadataQueryDidFinishGathering, object: nil)
    query?.predicate = predicate
    query?.start()
}

public func queryDidFinish(_ notification: NSNotification) {
    guard let query = notification.object as? NSMetadataQuery else {
        return
    }

    for result in query.results {
        guard let item = result as? NSMetadataItem else {
            print("Result was not an NSMetadataItem, \(result)")
            continue
        }
        print(item.value(forAttribute: kMDItemDisplayName as String))
    }
}

这篇关于在Swift 2.2中使用Spotlight列出El Capitan上已安装的应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆