https://github.com/dagronf/dfsearchkit
Swift/Objective-C framework for macOS around Apple's SearchKit
https://github.com/dagronf/dfsearchkit
apple macos macosx search searchkit swift
Last synced: about 1 year ago
JSON representation
Swift/Objective-C framework for macOS around Apple's SearchKit
- Host: GitHub
- URL: https://github.com/dagronf/dfsearchkit
- Owner: dagronf
- License: mit
- Created: 2018-05-06T01:46:58.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2020-11-03T05:38:02.000Z (over 5 years ago)
- Last Synced: 2025-03-23T04:31:41.382Z (about 1 year ago)
- Topics: apple, macos, macosx, search, searchkit, swift
- Language: Swift
- Homepage:
- Size: 567 KB
- Stars: 27
- Watchers: 3
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# DFSearchKit
A framework implementing a search index and summary generator using SKSearchKit for both Swift and Objective-C
  
 [](https://cocoapods.org) [](https://swift.org/package-manager)
## Why?
I was interesting in learning about SKSearchKit and wanted a nice simple object to abstract away some of the unpleasantries when dealing with a C-style interface in Swift using native Swift types.
## Usage
The base library is split into three classes and an async controller.
### Copy
Copy everything from the `DFSearchKit` sub-folder into your own project
### Cocoapods
Add the following to your `Podfiles` file
`pod 'DFSearchKit', :git => 'https://github.com/dagronf/DFSearchKit'`
### Swift Package Manager
Import via Xcode.
## Classes
### DFSearchIndex.Memory
A class inheriting from DFSearchIndex that implements an in-memory index. This index exists purely in memory, and will be destroyed when the index is deallocated.
```swift
// Create a new memory index using the default settings
guard let indexer = DFSearchIndex.Memory() else {
assert(false)
}
indexer.add(textURL: "doc-url://d1.txt", text: "This is my first document")
let fileURL = //
indexer.add(fileURL, mimeType: "application/pdf")
// ... add more documents
indexer.flush()
let searchresult = indexer.search("first")
// Do something with the search results
```
`DFSearchIndex.Memory` provides methods to get the raw index data for storing, and to load from data
##### Load from a raw Data object
```swift
let indexData = Data(...)
guard let indexer = DFSearchIndex.Memory(data: indexData) else {
assert(false)
}
```
##### Extract the raw Data object from the search index
```swift
let newIndexData = indexer.data()
```
### DFSearchIndex.File
A class inheriting from DFSearchIndex that allows the creation and use of an index on disk.
```swift
// Create a index on disk
let newFileURL = //
let createProperties = DSFSearchIndex.CreateProperties() // search index properties
guard let newIndex = DFSearchIndex.File(fileURL: newFileURL, properties: createProperties) else {
assert(false)
}
// Open a file index
let existingFileURL = //
guard let fileIndex = DFSearchIndex.File(fileURL: existingFileURL, writable: true) else {
assert(false)
}
let documentURL = URL(string: ("doc-url://d1.txt")!
fileIndex.add(documentURL, text: "This is my first document"))
let fileURL = //
fileIndex.add(fileURL, mimeType: "application/pdf")
// Flush the index so that it is updated for searching
fileIndex.flush()
// Perform a basic search for the work 'first'
var result = indexer.search("first")
fileIndex.save()
fileIndex.close()
```
### DFSearchIndex.AsyncController
`DFSearchIndex.AsyncController` is a simple controller that takes an index object, and provides a safe method for handling async requests.
For example, to add a number of files asynchronously
```swift
guard let searchIndex = DFSearchIndex.Memory() else {
assert(false)
}
let asyncController = DFSearchIndex.AsyncController(index: searchIndex, delegate: nil)
// Create a file task containing the URLs to be indexed
let addTask = DFSearchIndex.AsyncController.FileTask()
asyncController.addURLs(async: addTask, complete: { task in
//
})
...
// Create a file task containing the URLs to be removed
let removeTask = DFSearchIndex.AsyncController.FileTask()
asyncController.removeURLs(async: removeTask, complete: { task in
//
})
```
Internally the async controller uses an operation queue for handling requests.
## Searching
There are two methods for search
### Search all
The search all is available on the indexer object, and returns all the results it can get. As such, for large indexes this may take quite a while to return. It is provided mostly as a convenience function for small indexes.
```swift
guard let searchIndex = DFSearchIndex.Memory() else {
assert(false)
}
// Add some documents...
searchIndex.add(textURL: "doc-url://d1.txt", text: "This is my first document"))
// Flush the index
searchIndex.flush()
// Search for the word 'first'
let searchResult = indexer.search("first")
// searchResult.count == 1
// searchResult[0].url == firstURL
// searchResult[0].score == 1
searchIndex.save()
searchIndex.close()
```
### Progressive Search
For large indexes, the results may take quite a while to return. Thus, the progressive index is more useful by returning limited sets of results progressively, and can be used on a background thread (as SKSearchIndex is thread safe) to progressively retrieve results in another thread (for example)
```swift
/// ... load documents ...
let search = indexer.progressiveSearch(query: "dog")
var hasMoreResults = true
repeat {
var searchChunk = search.next(10)
// ... do something with searchChunk...
hasMoreResults = searchChunk.moreResults
}
while hasMoreResults
```
## Summary Generation
The `DFSearchIndex.Summarizer` class provides a wrapper around the `SKSummary` interface, providing text rankings and orderings.
```swift
let text = //