本文介绍: 搜索部分的算法,使用的是模糊搜索和普通的搜索,对于字符串的搜索,这里还是比较暴力的,并没有对这方面的内容做优化,可能历史记录并不会太多,所有搜索速度不会收到影响。都会跟着变化,所有比较核心的部分其实就是获取剪切板的变化情况了,一旦我们能知道剪切板的情况,很多事情就是逻辑的问题了。它保留了您复制内容的历史记录,让您可以快速导航、搜索和使用以前的剪贴板内容。的使用非常的方便,用户界面也非常的简单,他的代码量并不多,大部分都是使用。是一个事件,当截切板的内容有变化的时候,入门的练习,做起来应该非常的有意思。
Maccy
Maccy
是一个轻量级的 macOS
剪贴板管理器。它保留了您复制内容的历史记录,让您可以快速导航、搜索和使用以前的剪贴板内容。
Maccy
适用于 macOS Mojave 10.14
或更高版本。
代码分析
Maccy
的使用非常的方便,用户界面也非常的简单,他的代码量并不多,大部分都是使用swift
写成,可以用来做swift
入门的练习,做起来应该非常的有意思。
private func start() {
statusItem.behavior = .removalAllowed
statusItem.isVisible = UserDefaults.standard.showInStatusBar
statusItem.menu = menuLoader
if let button = statusItem.button {
button.image = NSImage(named: "StatusBarMenuImage")
button.imagePosition = .imageRight
(button.cell as? NSButtonCell)?.highlightsBy = []
}
clipboard.onNewCopy(history.add)
clipboard.onNewCopy(menu.add)
clipboard.onNewCopy(updateMenuTitle)
clipboard.startListening()
populateHeader()
populateItems()
populateFooter()
updateStatusItemEnabledness()
}
onNewCopy
是一个事件,当截切板的内容有变化的时候,history
,menu
,updateMenuTitle
都会跟着变化,所有比较核心的部分其实就是获取剪切板的变化情况了,一旦我们能知道剪切板的情况,很多事情就是逻辑的问题了。
历史记录:
func add(_ item: HistoryItem) {
if let existingHistoryItem = findSimilarItem(item) {
item.contents = existingHistoryItem.contents
item.firstCopiedAt = existingHistoryItem.firstCopiedAt
item.numberOfCopies += existingHistoryItem.numberOfCopies
item.pin = existingHistoryItem.pin
item.title = existingHistoryItem.title
item.application = existingHistoryItem.application
remove(existingHistoryItem)
} else {
if UserDefaults.standard.playSounds {
NSSound(named: NSSound.Name("write"))?.play()
}
}
CoreDataManager.shared.saveContext()
}
历史记录在剪切板变化的时候,会有所变化,这里直接保存在数据库CoreDataManager
中。在一开始程序启动的时候,会加载历史的数据。
搜索
搜索部分的算法,使用的是模糊搜索和普通的搜索,对于字符串的搜索,这里还是比较暴力的,并没有对这方面的内容做优化,可能历史记录并不会太多,所有搜索速度不会收到影响。
private func fuzzySearch(string: String, within: [Searchable]) -> [SearchResult] {
let pattern = fuse.createPattern(from: string)
let searchResults: [SearchResult] = within.compactMap({ item in
fuzzySearch(for: pattern, in: item.title, of: item) ??
fuzzySearch(for: pattern, in: item.value, of: item)
})
let sortedResults = searchResults.sorted(by: { ($0.score ?? 0) < ($1.score ?? 0) })
return sortedResults
}
private func fuzzySearch(for pattern: Fuse.Pattern?, in searchString: String, of item: Searchable) -> SearchResult? {
var searchString = searchString
if searchString.count > fuzzySearchLimit {
// shortcut to avoid slow search
let stopIndex = searchString.index(searchString.startIndex, offsetBy: fuzzySearchLimit)
searchString = "(searchString[...stopIndex])"
}
if let fuzzyResult = fuse.search(pattern, in: searchString) {
return SearchResult(
score: fuzzyResult.score,
object: item,
titleMatches: fuse.search(pattern, in: item.title)?.ranges ?? []
)
} else {
return nil
}
}
private func simpleSearch(string: String, within: [Searchable]) -> [SearchResult] {
return within.compactMap({ item in
simpleSearch(for: string, in: item.title, of: item) ??
simpleSearch(for: string, in: item.value, of: item)
})
}
private func simpleSearch(for string: String, in searchString: String, of item: Searchable) -> SearchResult? {
if searchString.range(
of: string,
options: .caseInsensitive,
range: nil,
locale: nil
) != nil {
var result = SearchResult(
score: nil,
object: item,
titleMatches: []
)
let title = item.title
if let titleRange = title.range(of: string, options: .caseInsensitive, range: nil, locale: nil) {
let lowerBound = title.distance(from: title.startIndex, to: titleRange.lowerBound)
let upperBound = title.distance(from: title.startIndex, to: titleRange.upperBound) - 1
result.titleMatches.append(lowerBound...upperBound)
}
return result
} else {
return nil
}
原文地址:https://blog.csdn.net/weixin_40425640/article/details/126953533
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_48748.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。