本文介绍: 搜索部分算法使用的是模糊搜索和普通的搜索,对于字符串的搜索,这里还是比较暴力的,并没有对这方面的内容优化可能历史记录并不会太多,所有搜索速度不会收到影响。都会跟着变化,所有比较核心部分其实就是获取剪切板的变化情况了,一旦我们知道剪切板的情况,很多事情就是逻辑问题了。它保留了您复制内容的历史记录,让您可以快速导航、搜索和使用以前的剪贴板内容。的使用非常的方便,用户界面也非常的简单,他的代码量并不多,大部分都是使用。是一个事件,当截切板的内容有变化的时候入门练习,做起来应该非常的有意思。

Maccy

Maccy一个轻量级macOS 剪贴板管理器。它保留了您复制内容的历史记录,让您可以快速导航、搜索和使用以前的剪贴板内容

Maccy用于 macOS Mojave 10.14 或更高版本

在这里插入图片描述
github地址这里

代码分析

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一个事件,当截切板的内容有变化的时候historymenu,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进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注