I want to make a small SDK for Adding a credit card form. Idea is to make SDK so application can use TextField component from SDK but with limited access. For example, an application can enter text, change UI but I want to disable direct access to read text. I want to expose only the last 4 digits. The application shouldn't access secure data like all 16 digits of the card. I'm not sure how I can disable reading text property from UITextField in this case
CodePudding user response:
I don't think you can absolutely restrict reading UITextField.text
property. Even if you don't directly expose UITextField
object, if somebody wants to get the text they can at least recursively scan your view hierarchy and find desired textfield.
But if your goal is just to restrict direct access to the text, you may just create a custom view with encapsulated textField.
/// expose the data you'd like to SDK users
public protocol CreditCardInput {
var theLastFourDigits: String? { get }
}
///
open final class CreditCardTextField: UIView, CreditCardInput {
// It's private and not accessible directly for SDK users
private let textField = UITextField()
var theLastFourDigits: String? {
// TODO: get the last 4 digits from `textField`, if there are any
}
}
SDK users will create a CreditCardTextField
instance and will gain direct access only to the stuff you explicitly exposed in it.
CodePudding user response:
Vadim Popov's comments are correct. In swift and iOS generally, there's no way to remove functionality from a class (e.g. remove readable property .text from the UITextField class). You can override the value returned with something like
override var text: String? { get { return "text hidden" } }
But your issue is that you can't do even something like that for just one text field. You have to change the class definition, which changes every UITextField in the app.
So what you want, I think, is to take one of two paths:
As Vadim said, you can create a UI component that has a managed text field as a subview, and have apps use your component where they would normally use a UITextView. The problem of course is that your component is a UIView, with a subview (the UITextField) which makes it accessible to being found via .subviews property inherited from UIView.
Write your own control from primitives. This means drawing the box yourself using graphics drawing primitives, drawing text using text drawing primitives, manage the text value yourself with an internal property, add keyboard event responders to accept input from user, etc. Complicated.
Basically, your problem is that you're trying to use a component (UITextView) that you don't control and remove some of the functionality that the author (Apple) put into the class definition. Swift doesn't allow you to do that without impacting every instance of that class.