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.
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))
}
}
Testing the
mdfind "kMDItemKind == 'Application'"
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:
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!
The dealloc message seems like the query is missing a strong reference.
I'd suggest using a different predicate as kMDItemKind is a localized key according to John's comment here
so
let predicate = NSPredicate(format: "kMDItemContentType == 'com.apple.application-bundle'")would work for what we're doing.In swift 3 this could look like this: