Search code examples
iosswiftswift5property-wrapper

Swift property wrappers initilaization error


I am trying to use PropertWrapper for email validation. But when i try to initialize the eamilId varaible with empty string i am getting error : Incorrect argument label in call (have 'wrappedValue:', expected 'emailId:')

Here is the code of My view controller

class ViewController: UIViewController {
    var name: String = ""
    @EmailWrapper var emailId: String = ""

  override func viewDidLoad() {
    super.viewDidLoad()
    name = "User Name"
    emailId = "user123@gmail.com"
    updateUserDetails()
  }

  func updateUserDetails() {
    if name.isEmpty || emailId.isEmpty {
        print("Please enter valid Name and emailId")
    }
    else {
        print("User data updated successfully")
    }
  }
}

And the code for my property wrapper is

@propertyWrapper
struct EmailWrapper {
    private var value = ""
    var wrappedValue: String {
        set {
            value = newValue
        }
        get {
            return isValidEmail(value) ? value : ""
        }
    }

    init(emailId: String) {
        self.value = emailId
    }
    private func isValidEmail(_ email: String) -> Bool {
        let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
        let emailPred = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
        return emailPred.evaluate(with: email)
    }
}

How can I initialize the emailId with default value (String()) in ViewController while using the EmailWrapper


Solution

  • When you apply a property wrapper:

    @EmailWrapper var emailId: String = ""
    

    the Swift compiler actually generates a call to the initialiser to the initialiser of the property wrapper like this:

    EmailWrapper(wrappedValue: "")
    

    However, EmailWrapper doesn't have such an initialiser. Its only initialiser has the argument label emailId: instead.

    To fix this, you just need to change the argument label of the initialiser:

    init(wrappedValue: String) {
        self.value = wrappedValue
    }