Created
August 31, 2022 15:13
-
-
Save robinkunde/76247953c91513705ffc63e455684c06 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if DEBUG | |
import Foundation | |
import UIKit | |
class SimPasteboardHelper { | |
static let shared = SimPasteboardHelper() | |
private var handle: FileHandle? | |
private var dispatchSource: DispatchSourceFileSystemObject? | |
private var pbContents: String? | |
func activate() -> Bool { | |
#if !targetEnvironment(simulator) | |
return false | |
#endif | |
if let handle = self.handle { | |
try? handle.close() | |
self.handle = nil | |
} | |
if let dispatchSource = self.dispatchSource { | |
dispatchSource.cancel() | |
self.dispatchSource = nil | |
} | |
guard let home = ProcessInfo.processInfo.environment["SIMULATOR_HOST_HOME"] else { return false } | |
let mobileFolderUrl = URL(fileURLWithPath: home).appendingPathComponent("mobile", isDirectory: true) | |
var isDirectory: ObjCBool = false | |
guard | |
FileManager.default.fileExists(atPath: mobileFolderUrl.path, isDirectory: &isDirectory), | |
isDirectory.boolValue | |
else { return false } | |
let proxyFileUrl = mobileFolderUrl.appendingPathComponent("simPasteboard", isDirectory: false) | |
if FileManager.default.fileExists(atPath: proxyFileUrl.path, isDirectory: &isDirectory) { | |
if isDirectory.boolValue { | |
return false | |
} | |
} else { | |
try! "".write(to: proxyFileUrl, atomically: true, encoding: .utf8) | |
} | |
guard let handle = try? FileHandle(forReadingFrom: proxyFileUrl) else { return false } | |
self.handle = handle | |
readFromProxyFile() | |
let dispatchSource = DispatchSource.makeFileSystemObjectSource( | |
fileDescriptor: handle.fileDescriptor, | |
eventMask: [.write], | |
queue: DispatchQueue.main | |
) | |
self.dispatchSource = dispatchSource | |
dispatchSource.setEventHandler { [weak self] in | |
self?.readFromProxyFile() | |
} | |
dispatchSource.activate() | |
return true | |
} | |
private func readFromProxyFile() { | |
guard let handle = self.handle else { return } | |
do { | |
try handle.seek(toOffset: 0) | |
let data = handle.readDataToEndOfFile() | |
// swiftlint:disable:next force_unwrapping | |
let string = String(data: data, encoding: .utf8)! | |
self.pbContents = string.trimmingCharacters(in: .whitespacesAndNewlines) | |
} catch { | |
print("SimPasteboardHelper failed with error: \(error.localizedDescription)") | |
} | |
} | |
@objc | |
func paste() { | |
guard let pbContents = pbContents, let responder = UIResponder.currentFirstResponder else { | |
return | |
} | |
if let textfield = responder as? UITextField { | |
textfield.insertText(pbContents) | |
} else if let textview = responder as? UITextView { | |
textview.insertText(pbContents) | |
} | |
} | |
} | |
extension UIResponder { | |
private weak static var _currentFirstResponder: UIResponder? | |
public static var currentFirstResponder: UIResponder? { | |
UIResponder._currentFirstResponder = nil | |
UIApplication.shared.sendAction(#selector(findFirstResponder(sender:)), to: nil, from: nil, for: nil) | |
return UIResponder._currentFirstResponder | |
} | |
@objc | |
private func findFirstResponder(sender: AnyObject) { | |
UIResponder._currentFirstResponder = self | |
} | |
} | |
extension AppDelegate { | |
override var keyCommands: [UIKeyCommand]? { | |
var commands = super.keyCommands ?? [] | |
commands.append(UIKeyCommand(input: "v", modifierFlags: [.control], action: #selector(pasteboardHelperPaste))) | |
return commands | |
} | |
@objc | |
private func pasteboardHelperPaste() { | |
SimPasteboardHelper.shared.paste() | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment