尝试在时间间隔后清除粘贴板

Trying to wipe out pasteboard after time interval

我正在尝试在 10 秒后复制一个字符串后清除粘贴板。要求如下:

  1. 10 秒后,复制的文本被清除,因此无法粘贴到 当前应用和其他应用(例如 iMessage、Safari)
  2. 如果复制不相同文本,当 10 秒到时,计时器不会将其清除

尝试次数

  1. 我试过只用 DispatchQueue.main.async 这样做,但是,这会冻结原始应用程序。
  2. 我试过只用 DispatchQueue.global(qos: .background).async 但是,当我切换到另一个应用程序 (iMessage) 时,10 秒后我仍然可以粘贴数字。我必须返回到原始应用程序并返回到 iMessage 才能将其清除
  3. 这是我的最新尝试,它的行为与 #2 相同,只有当我返回原始应用程序并返回 iMessage 时才会消失
    private func clearTextAfterDelay(_ copiedCardNumber: String) {
        expirationTimer?.invalidate()
        expirationTimer = Timer.scheduledTimer(withTimeInterval: 10, repeats: false) { timer in
            DispatchQueue.main.async {
                let currentTextOnClipBoard = UIPasteboard.general.string
                if currentTextOnClipBoard == copiedCardNumber {
                    UIPasteboard.general.setValue("", forPasteboardType: UIPasteboard.Name.general.rawValue)
                }
            }
        }

        DispatchQueue.global(qos: .background).async {
            let runLoop = RunLoop.current
            runLoop.add(self.expirationTimer!, forMode: .default)
            runLoop.run()
        }
    }

2 号不起作用,因为您的应用程序在退出活动状态后几乎立即被暂停。因此,您需要使用后台任务来延长应用的活动时间。

看看 beginBackgroundTaskWithExpirationHandler docs.

This method requests additional background execution time for your app. Call this method when leaving a task unfinished might be detrimental to your app’s user experience. For example, call this method before writing data to a file to prevent the system from suspending your app while the operation is in progress.

连同这篇文章和上面的评论,我能够弄明白 https://medium.com/@abhimuralidharan/finite-length-tasks-in-background-ios-swift-60f2db4fa01b。干杯

class ViewController: MvpViewController {

    private var expirationTimerforBackground: Timer?
    private var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier.invalid

    private func clearTextAfterDelay(_ copiedCardNumber: String) {
        backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in
            self?.endBackgroundTask()
        }

        assert(backgroundTask != UIBackgroundTaskIdentifier.invalid)

        self.expirationTimerforBackground?.invalidate()
        self.expirationTimerforBackground = Timer.scheduledTimer(withTimeInterval: 10, repeats: false) { [weak self] _ in
            let currentTextOnClipBoard = UIPasteboard.general.string
            if currentTextOnClipBoard == copiedCardNumber {
                UIPasteboard.general.setValue("", forPasteboardType: UIPasteboard.Name.general.rawValue)
            }
            self?.endBackgroundTask()
        }
    }

    private func endBackgroundTask() {
        UIApplication.shared.endBackgroundTask(backgroundTask)
        backgroundTask = UIBackgroundTaskIdentifier.invalid
    }
}