Skip to content

Commit 033e043

Browse files
authored
fix: Square payment SDK integration (#900)
## 📜 Description Fixed an integration with Square SDK. ## 💡 Motivation and Context The current problem is that `SQIPTextFieldInputModifier` always redirects call to an injected (`KCCompositeDelegate`) delegate - and it causes infinite loop that eventually leads to a crash 🤷‍♂️ I've tried to find source code of `SQIPTextFieldInputModifier` but it's closed, and I can not read it. So far I had two approaches to fix it: ### 1️⃣ Add state variable and prevent infinite calls While it solves the problem, it produces other problems - it looks like original delegate methods never gets called and in this case we break Square SDK, so it's not really an option. ### 2️⃣ Don't set delegate for `SQIPTextFieldInputModifier` While it breaks the principle that any focused input will intercept events it makes certain sense: - seems like Square did such "protection" intentionally; - Square handler keyboard appearance on their own and it's not possible to use `react-native-keyboard-controller` component there. So after thinking a while I decided that we **shouldn't inject** our delegate for `Square` SDK inputs. The solution may be not perfect, but for now it totally works. If it causes more issues, then I'll be glad to re-consider the solution with new info in mind. Closes #896 ## 📢 Changelog <!-- High level overview of important changes --> <!-- For example: fixed status bar manipulation; added new types declarations; --> <!-- If your changes don't affect one of platform/language below - then remove this platform/language --> ### iOS - don't substitute delegate for Square inputs; ## 🤔 How Has This Been Tested? tested manually on iPhone 15 Pro (iOS 17.5) in repro example. ## 📸 Screenshots (if appropriate): <!-- Add screenshots/video if needed --> <!-- That would be highly appreciated if you can add how it looked before and after your changes --> https://github.com/user-attachments/assets/e2ef6a65-9a09-4615-8ef1-c8310f56dcb6 ## 📝 Checklist - [x] CI successfully passed - [x] I added new mocks and corresponding unit-tests if library API was changed
1 parent 976cfe5 commit 033e043

File tree

3 files changed

+21
-3
lines changed

3 files changed

+21
-3
lines changed

cspell.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@
149149
"componentregistry",
150150
"mapbuffer",
151151
"nativemodule",
152-
"reactnative"
152+
"reactnative",
153+
"SQIP"
153154
],
154155
"ignorePaths": [
155156
"node_modules",

ios/delegates/KCTextInputCompositeDelegate.swift

+16-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class KCTextInputCompositeDelegate: NSObject, UITextViewDelegate, UITextFieldDel
6565
// MARK: setters/getters
6666

6767
public func setTextViewDelegate(delegate: UITextViewDelegate?) {
68-
// remove KVO from any old textField
68+
// remove KVO from any old textView
6969
if let oldTextField = observedTextFieldForSelection {
7070
removeSelectionRangeObserver(from: oldTextField)
7171
}
@@ -96,6 +96,21 @@ class KCTextInputCompositeDelegate: NSObject, UITextViewDelegate, UITextFieldDel
9696
}
9797
}
9898

99+
public func canSubstituteTextFieldDelegate(delegate: UITextFieldDelegate?) -> Bool {
100+
let type = String(describing: delegate)
101+
if type.range(of: "SQIPTextFieldInputModifier") != nil {
102+
// SQIPTextFieldInputModifier is a private class used internally by Square.
103+
// It forwards input events to the keyboard-controller delegate.
104+
// To prevent an infinite loop, we avoid setting our delegate in this case.
105+
// Since Square's SDK is used imperatively and doesn't allow adding custom components,
106+
// keyboard-controller components cannot be used in this context,
107+
// so it's safe to skip replacing the delegate.
108+
return false
109+
}
110+
111+
return true
112+
}
113+
99114
// Getter for the active delegate
100115
public var activeDelegate: AnyObject? {
101116
return textViewDelegate ?? textFieldDelegate

ios/observers/FocusedInputObserver.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,9 @@ public class FocusedInputObserver: NSObject {
228228

229229
private func substituteDelegate(_ input: UIResponder?) {
230230
if let textField = input as? UITextField {
231-
if !(textField.delegate is KCTextInputCompositeDelegate) {
231+
if !(textField.delegate is KCTextInputCompositeDelegate),
232+
delegate.canSubstituteTextFieldDelegate(delegate: textField.delegate)
233+
{
232234
delegate.setTextFieldDelegate(delegate: textField.delegate, textField: textField)
233235
textField.delegate = delegate
234236
}

0 commit comments

Comments
 (0)