diff --git a/Sources/Amplitude/Plugins/iOS/UIKitUserInteractions.swift b/Sources/Amplitude/Plugins/iOS/UIKitUserInteractions.swift index e6b93ae..193f4c1 100644 --- a/Sources/Amplitude/Plugins/iOS/UIKitUserInteractions.swift +++ b/Sources/Amplitude/Plugins/iOS/UIKitUserInteractions.swift @@ -6,24 +6,14 @@ class UIKitUserInteractions { private static let lock = NSLock() - private static let initializeSwizzle: () = { - swizzleSendAction() + private static let addNotificationObservers: () = { + NotificationCenter.default.addObserver(UIKitUserInteractions.self, selector: #selector(didBeginEditing), name: UITextField.textDidBeginEditingNotification, object: nil) + NotificationCenter.default.addObserver(UIKitUserInteractions.self, selector: #selector(didEndEditing), name: UITextField.textDidEndEditingNotification, object: nil) + NotificationCenter.default.addObserver(UIKitUserInteractions.self, selector: #selector(didBeginEditing), name: UITextView.textDidBeginEditingNotification, object: nil) + NotificationCenter.default.addObserver(UIKitUserInteractions.self, selector: #selector(didEndEditing), name: UITextView.textDidEndEditingNotification, object: nil) }() - private static let initializeNotificationListeners: () = { - NotificationCenter.default.addObserver(UIKitUserInteractions.self, selector: #selector(UIKitUserInteractions.amp_textFieldDidBeginEditing), name: UITextField.textDidBeginEditingNotification, object: nil) - NotificationCenter.default.addObserver(UIKitUserInteractions.self, selector: #selector(UIKitUserInteractions.amp_textFieldDidEndEditing), name: UITextField.textDidEndEditingNotification, object: nil) - }() - - static func register(_ amplitude: Amplitude) { - lock.withLock { - amplitudeInstances.add(amplitude) - } - initializeSwizzle - initializeNotificationListeners - } - - private static func swizzleSendAction() { + private static let swizzleSendAction: () = { let applicationClass = UIApplication.self let originalSelector = #selector(UIApplication.sendAction) @@ -45,19 +35,27 @@ class UIKitUserInteractions { originalSelector, swizzledImp, method_getTypeEncoding(swizzledMethod)) + }() + + static func register(_ amplitude: Amplitude) { + lock.withLock { + amplitudeInstances.add(amplitude) + } + swizzleSendAction + addNotificationObservers } - @objc static func amp_textFieldDidBeginEditing(_ notification: NSNotification) { - guard let textField = notification.object as? UITextField else { return } - let userInteractionEvent = textField.eventFromData(with: "didBeginEditing") + @objc static func didBeginEditing(_ notification: NSNotification) { + guard let view = notification.object as? UIView else { return } + let userInteractionEvent = view.eventFromData(with: "didBeginEditing") amplitudeInstances.allObjects.forEach { $0.track(event: userInteractionEvent) } } - @objc static func amp_textFieldDidEndEditing(_ notification: NSNotification) { - guard let textField = notification.object as? UITextField else { return } - let userInteractionEvent = textField.eventFromData(with: "didEndEditing") + @objc static func didEndEditing(_ notification: NSNotification) { + guard let view = notification.object as? UIView else { return } + let userInteractionEvent = view.eventFromData(with: "didEndEditing") amplitudeInstances.allObjects.forEach { $0.track(event: userInteractionEvent) } @@ -68,13 +66,15 @@ extension UIApplication { @objc func amp_sendAction(_ action: Selector, to target: Any?, from sender: Any?, for event: UIEvent?) -> Bool { let sendActionResult = amp_sendAction(action, to: target, from: sender, for: event) - guard - sendActionResult, + guard sendActionResult, let view = sender as? UIView, - view.amp_shouldTrack(action, for: event) + view.amp_shouldTrack(action, for: event), + let actionName = NSStringFromSelector(action) + .components(separatedBy: ":") + .first else { return sendActionResult } - let userInteractionEvent = view.eventFromData(with: NSStringFromSelector(action).components(separatedBy: ":").first ?? "") + let userInteractionEvent = view.eventFromData(with: actionName) UIKitUserInteractions.amplitudeInstances.allObjects.forEach { $0.track(event: userInteractionEvent) @@ -156,6 +156,10 @@ extension UITextField { override func amp_shouldTrack(_ action: Selector, for event: UIEvent?) -> Bool { false } } +extension UITextView { + override func amp_shouldTrack(_ action: Selector, for event: UIEvent?) -> Bool { false } +} + #if !os(tvOS) extension UISlider { override func amp_shouldTrack(_ action: Selector, for event: UIEvent?) -> Bool {