Skip to content

Commit 3810e2c

Browse files
authored
feat: add support for uitextview autocapture (#195)
* Fix indentation issue * feat: add user interactions capture * fix: fix typo * fix: remove support for UITextField action message capture * refactor: add dispatch once for method swizzling * fix: remove support for UISlider to reduce noise * feat: add support for UITextField and UISlider event capture * style: remove return keyword for one line functions * fix: fix typo * feat: add support for text field gained/lost focus * fix: fix lint * fix: remove tag as textfield title * refactor: refactor title and shouldTrack * refactor: add a protocol to track control elements * refactor: guard on action name * feat: add support for uitextview capture * fix: disable action method tracking support for UITextView * fix: fix lint issue * style: remove amp_ prefix from objc methods
1 parent c0522a7 commit 3810e2c

File tree

1 file changed

+30
-26
lines changed

1 file changed

+30
-26
lines changed

Sources/Amplitude/Plugins/iOS/UIKitUserInteractions.swift

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,14 @@ class UIKitUserInteractions {
66

77
private static let lock = NSLock()
88

9-
private static let initializeSwizzle: () = {
10-
swizzleSendAction()
9+
private static let addNotificationObservers: () = {
10+
NotificationCenter.default.addObserver(UIKitUserInteractions.self, selector: #selector(didBeginEditing), name: UITextField.textDidBeginEditingNotification, object: nil)
11+
NotificationCenter.default.addObserver(UIKitUserInteractions.self, selector: #selector(didEndEditing), name: UITextField.textDidEndEditingNotification, object: nil)
12+
NotificationCenter.default.addObserver(UIKitUserInteractions.self, selector: #selector(didBeginEditing), name: UITextView.textDidBeginEditingNotification, object: nil)
13+
NotificationCenter.default.addObserver(UIKitUserInteractions.self, selector: #selector(didEndEditing), name: UITextView.textDidEndEditingNotification, object: nil)
1114
}()
1215

13-
private static let initializeNotificationListeners: () = {
14-
NotificationCenter.default.addObserver(UIKitUserInteractions.self, selector: #selector(UIKitUserInteractions.amp_textFieldDidBeginEditing), name: UITextField.textDidBeginEditingNotification, object: nil)
15-
NotificationCenter.default.addObserver(UIKitUserInteractions.self, selector: #selector(UIKitUserInteractions.amp_textFieldDidEndEditing), name: UITextField.textDidEndEditingNotification, object: nil)
16-
}()
17-
18-
static func register(_ amplitude: Amplitude) {
19-
lock.withLock {
20-
amplitudeInstances.add(amplitude)
21-
}
22-
initializeSwizzle
23-
initializeNotificationListeners
24-
}
25-
26-
private static func swizzleSendAction() {
16+
private static let swizzleSendAction: () = {
2717
let applicationClass = UIApplication.self
2818

2919
let originalSelector = #selector(UIApplication.sendAction)
@@ -45,19 +35,27 @@ class UIKitUserInteractions {
4535
originalSelector,
4636
swizzledImp,
4737
method_getTypeEncoding(swizzledMethod))
38+
}()
39+
40+
static func register(_ amplitude: Amplitude) {
41+
lock.withLock {
42+
amplitudeInstances.add(amplitude)
43+
}
44+
swizzleSendAction
45+
addNotificationObservers
4846
}
4947

50-
@objc static func amp_textFieldDidBeginEditing(_ notification: NSNotification) {
51-
guard let textField = notification.object as? UITextField else { return }
52-
let userInteractionEvent = textField.eventFromData(with: "didBeginEditing")
48+
@objc static func didBeginEditing(_ notification: NSNotification) {
49+
guard let view = notification.object as? UIView else { return }
50+
let userInteractionEvent = view.eventFromData(with: "didBeginEditing")
5351
amplitudeInstances.allObjects.forEach {
5452
$0.track(event: userInteractionEvent)
5553
}
5654
}
5755

58-
@objc static func amp_textFieldDidEndEditing(_ notification: NSNotification) {
59-
guard let textField = notification.object as? UITextField else { return }
60-
let userInteractionEvent = textField.eventFromData(with: "didEndEditing")
56+
@objc static func didEndEditing(_ notification: NSNotification) {
57+
guard let view = notification.object as? UIView else { return }
58+
let userInteractionEvent = view.eventFromData(with: "didEndEditing")
6159
amplitudeInstances.allObjects.forEach {
6260
$0.track(event: userInteractionEvent)
6361
}
@@ -68,13 +66,15 @@ extension UIApplication {
6866
@objc func amp_sendAction(_ action: Selector, to target: Any?, from sender: Any?, for event: UIEvent?) -> Bool {
6967
let sendActionResult = amp_sendAction(action, to: target, from: sender, for: event)
7068

71-
guard
72-
sendActionResult,
69+
guard sendActionResult,
7370
let view = sender as? UIView,
74-
view.amp_shouldTrack(action, for: event)
71+
view.amp_shouldTrack(action, for: event),
72+
let actionName = NSStringFromSelector(action)
73+
.components(separatedBy: ":")
74+
.first
7575
else { return sendActionResult }
7676

77-
let userInteractionEvent = view.eventFromData(with: NSStringFromSelector(action).components(separatedBy: ":").first ?? "")
77+
let userInteractionEvent = view.eventFromData(with: actionName)
7878

7979
UIKitUserInteractions.amplitudeInstances.allObjects.forEach {
8080
$0.track(event: userInteractionEvent)
@@ -156,6 +156,10 @@ extension UITextField {
156156
override func amp_shouldTrack(_ action: Selector, for event: UIEvent?) -> Bool { false }
157157
}
158158

159+
extension UITextView {
160+
override func amp_shouldTrack(_ action: Selector, for event: UIEvent?) -> Bool { false }
161+
}
162+
159163
#if !os(tvOS)
160164
extension UISlider {
161165
override func amp_shouldTrack(_ action: Selector, for event: UIEvent?) -> Bool {

0 commit comments

Comments
 (0)