// // FindInteractionController.swift // flutter_inappwebview // // Created by Lorenzo Pichilli on 07/10/22. // import Foundation import Flutter public class FindInteractionController : NSObject, Disposable { static var METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_find_interaction_"; var plugin: SwiftFlutterPlugin? var webView: InAppWebView? var channelDelegate: FindInteractionChannelDelegate? var settings: FindInteractionSettings? var shouldCallOnRefresh = false private var _searchText: String? = nil var searchText: String? { get { if #available(iOS 16.0, *), let interaction = webView?.findInteraction { return interaction.searchText } return _searchText } set { if #available(iOS 16.0, *), let interaction = webView?.findInteraction { interaction.searchText = newValue } self._searchText = newValue } } private var _activeFindSession: FindSession? = nil var activeFindSession: FindSession? { get { if #available(iOS 16.0, *), let interaction = webView?.findInteraction { if let activeFindSession = interaction.activeFindSession { return FindSession.fromUIFindSession(uiFindSession: activeFindSession) } return nil } return _activeFindSession } set { self._activeFindSession = newValue } } public init(plugin: SwiftFlutterPlugin, id: Any, webView: InAppWebView, settings: FindInteractionSettings?) { super.init() self.plugin = plugin self.webView = webView self.settings = settings if let registrar = plugin.registrar { let channel = FlutterMethodChannel(name: FindInteractionController.METHOD_CHANNEL_NAME_PREFIX + String(describing: id), binaryMessenger: registrar.messenger()) self.channelDelegate = FindInteractionChannelDelegate(findInteractionController: self, channel: channel) } } public func prepare() { // if let settings = settings { // // } } public func findAll(find: String?, completionHandler: ((Any?, Error?) -> Void)?) { guard let webView else { if let completionHandler = completionHandler { completionHandler(nil, nil) } return } var find = find if find == nil { find = searchText } else { // updated searchText searchText = find } guard let find else { if let completionHandler = completionHandler { completionHandler(nil, nil) } return } if #available(iOS 16.0, *), webView.isFindInteractionEnabled { if let interaction = webView.findInteraction { interaction.searchText = find interaction.presentFindNavigator(showingReplace: false) } if let completionHandler = completionHandler { completionHandler(nil, nil) } } else if find != "" { let startSearch = "window.\(JAVASCRIPT_BRIDGE_NAME)._findAllAsync('\(find)');" webView.evaluateJavaScript(startSearch, completionHandler: completionHandler) } } public func findNext(forward: Bool, completionHandler: ((Any?, Error?) -> Void)?) { guard let webView else { if let completionHandler = completionHandler { completionHandler(nil, nil) } return } if #available(iOS 16.0, *), webView.isFindInteractionEnabled { if let interaction = webView.findInteraction { if forward { interaction.findNext() } else { interaction.findPrevious() } } if let completionHandler = completionHandler { completionHandler(nil, nil) } } else { webView.evaluateJavaScript("window.\(JAVASCRIPT_BRIDGE_NAME)._findNext(\(forward ? "true" : "false"));", completionHandler: completionHandler) } } public func clearMatches(completionHandler: ((Any?, Error?) -> Void)?) { guard let webView else { if let completionHandler = completionHandler { completionHandler(nil, nil) } return } if #available(iOS 16.0, *), webView.isFindInteractionEnabled { if let interaction = webView.findInteraction { interaction.searchText = nil interaction.dismissFindNavigator() } if let completionHandler = completionHandler { completionHandler(nil, nil) } } else { webView.evaluateJavaScript("window.\(JAVASCRIPT_BRIDGE_NAME)._clearMatches();", completionHandler: completionHandler) } } public func dispose() { channelDelegate?.dispose() channelDelegate = nil webView = nil activeFindSession = nil plugin = nil } deinit { debugPrint("FindInteractionControl - dealloc") dispose() } }