checking validation of whitespace on string - swift

Inputting a value with 2 spaces and a string would enable the button " test"
but my code already detects " " whitespaces where the button is disabled but adding additional string on the whitespace enables the button
func validateAccountName(with accountName: String) -> Bool {
let regex = "[^A-Za-zA-O-o-y]"
let accountName = accountName.replacingOccurrences(of: " ", with: "")
return accountName.isEmpty == false && accountName.range(of: regex, options: .regularExpression) == nil
}
func edited() {
// check user input and allow update button to be enabled
guard let inputText = textField.text, let viewModel = viewModel else {
return
}
if !inputText.isEmpty
&& inputText != viewModel.accountName
&& viewModel.validateAccountName(with: inputText) {
self.navigationItem.rightBarButtonItem?.isEnabled = true
} else {
self.navigationItem.rightBarButtonItem?.isEnabled = false
}
}

Well what do you want to achieve?
If the goal is to reject everything that has any whitespaces you can use:
accountName.rangeOfCharacter(from: .whitespaces) == nil
But your regex already checks this as only Characters A-Z, a-z, A-O, - and o-y are allowed.
Maybe this is already what you want?
func validateAccountName(with accountName: String) -> Bool {
let regex = "[^A-Za-z]"
return accountName.range(of: regex, options: .regularExpression) == nil
}

Related

Fixing character count, decimal count, and "0" character count in swift

When I run this code, I can only insert the "." once. If it is already in one of the text fields I can't use another "." in another text field, this is the same with the character count. If 8 characters are entered in one text field no characters can be entered in any of the other text fields.
func textField(_ textField: UITextField, shouldChangeCharactersIn range:NSRange, replacementString string: String) -> Bool {
// cost of materials
if (costOfMaterialsTXT.text?.contains("."))! && string == "." {
return false
}
// tech hours
if (techHoursTXT.text?.contains("."))! && string == "." {
return false
}
// helper hours
if (helperHoursTXT.text?.contains("."))! && string == "." {
return false
}
//Prevent "0" characters as the first characters
// cost of materials
if (costOfMaterialsTXT.text == "0" && string.isEmpty) {
return true
} else if (costOfMaterialsTXT.text == "0" && string != ".") {
return false
}
// tech hours
if (techHoursTXT.text == "0" && string.isEmpty) {
return true
} else if (techHoursTXT.text == "0" && string != ".") {
return false
}
// helper hours
if (helperHoursTXT.text == "0" && string.isEmpty) {
return true
} else if (helperHoursTXT.text == "0" && string != ".") {
return false
}
//Limit the character count to 8
// cost of materials
if ((costOfMaterialsTXT.text!) + string).count > 8 {
return false
}
// tech hours
if ((techHoursTXT.text!) + string).count > 8 {
return false
}
// helper hours
if ((helperHoursTXT.text!) + string).count > 8 {
return false
}
// Only Numbers And Decimal-Point Allowed
let allowedCharacters = "0123456789."
let allowedCharacterSet = CharacterSet(charactersIn: allowedCharacters)
let typedCharactersSet = CharacterSet(charactersIn: string)
return allowedCharacterSet.isSuperset(of: typedCharactersSet)
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range:NSRange, replacementString string: String) -> Bool {
guard [costOfMaterialsTXT, techHoursTXT, helperHoursTXT].contains(textField) else {
return true //It's another textfield, is it even possible? Do you have more textField?
}
if (textField.text?.contains("."))! && string == "." {
return false
}
//Prevent "0" characters as the first characters
if (textField.text == "0" && string.isEmpty) {
return true
} else if (textField.text == "0" && string != ".") {
return false
}
//Limit the character count to 8
if ((textField.text!) + string).count > 8 {
return false
}
let allowedCharacters = "0123456789."
let allowedCharacterSet = CharacterSet(charactersIn: allowedCharacters)
let typedCharactersSet = CharacterSet(charactersIn: string)
return allowedCharacterSet.isSuperset(of: typedCharactersSet)
}
Here's the minima factorization.
You check at start if it's one of your UITextField with that behavior. Read the textField parameter.
You do the SAME behavior for each UITextField, so you shouldn't care about costOfMaterialsTXT, techHoursTXT, nor helperHoursTXT, it's any of these UITextField.
Now, about the code in itself...
You can remove the guard at the beginning if you only have those 3.
You should unwrap correctly here textField.text?.contains("."))! and textField.text!. What if string is "./.." (from a copy/paste) for instance?

Swift. How to delete the character at the beginning and end of the string?

It is necessary to remove the quotes at the beginning and end of the line, if they are in the line
Could it be more beautiful?
var str = "\"Hello, playground\""
let quotes = "\""
if str.hasPrefix(quotes) && str.hasSuffix(quotes) {
let v = str.dropFirst()
str = String(v.dropLast())
}
print(str)
If you like a one liner:
let str = "\"\"\"Hello, playground\"\""
let unquoted = String(str.drop(while: { $0 == "\""}).reversed().drop(while: { $0 == "\""}).reversed())
print(unquoted) //Hello, playground
You could define these extensions to make it look a tad prettier:
extension String {
private func removeQuotesAndReverse() -> String {
return String(self.drop(while: { $0 == "\""}).reversed())
}
func unquote() -> String {
return self.removeQuotesAndReverse().removeQuotesAndReverse()
}
}
And use it like so:
let unquoted = "\"\"\"Hello, playground\"\"".unquote()
If you only need to remove the first and last quotes, if they are both present, then I would only add a check that the count is at least 2 characters, since a string like "\"" has quotes in both the prefix and suffix, but it's not between quotes:
extension String {
func withoutDoubleQuotes() -> String {
if self.hasPrefix("\""), self.hasSuffix("\""), self.count > 1 {
return String(self.dropFirst().dropLast())
}
return self
}
}
and use it like so:
"\"Hello, playground\"".withoutDoubleQuotes() //Hello, playground
"\"\"\"Hello, playground\"\"".withoutDoubleQuotes() //""Hello, playground"
"\"".withoutDoubleQuotes() //"
"\"\"".withoutDoubleQuotes() //
You can use Collection removeFirst and removeLast mutating methods:
var str = "\"Hello, playground\""
let quotes = "\""
if str.hasPrefix(quotes) && str.hasSuffix(quotes) && str != quotes {
str.removeFirst()
str.removeLast()
}
print(str) // "Hello, playground\n"
you can do so:
let str = "\"Hello, playground\""
let new = str.filter{$0 != "\""}

In textfield i have to check Unicode SWIFT CODE is "\u{ef}"

In Swift i am found one Unicode so I Have use one check if textfield have this unicode "\u{ef}" condition is false
Here is my code
But is not Working
let getMessage = self.txtChat_View?.text?.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines)
if(String(describing: getMessage?.characters) == "\u{ef}")
{
print("gdfsds")
}
print(String(describing: getMessage?.characters)) //ANS Blank
print("-------------------------------")
print("---------->",getMessage ?? String()) //ANS Blank
print(getMessage?.characters.count) //ANS count is 1
if(getMessage ?? String() == "\u{ef}")
{
print("This is unicode")
}
if(getMessage == "")
{
print("This is null")
}
if(getMessage == nil)
{
print("####NIL#####")
}

Sort a string to determine if it is a Anagram or Palindrome in Swift Xcode

I have a extension names String, with two functions names isAnagramOf and isPalindrome. The first function is supposed to take input as a String, then first it will replace whitespace with no space then sort and compare the string and return a Bool to determine if anagram or not.
The second function named isPalindrome and will also ignore whitespaces and capitalization, it will then reverse the String and compare to return if it is reversed.
I am new to swift and following a tutorial, but I kept getting these errors no matter how I tried to write it. I have gone through it at least 10 times now and cant get it to work
If anyone can help with this code that would be great, I would also be open to someone showing me another way to write. Perhaps as a array first then to sort the string, I am not sure though.
extension String {
func isAnagramOf(_ s: String) -> Bool {
let lowerSelf = self.lowercased().replacingOccurrences(of: " ", with: "")
let lowerOther = s.lowercased().replacingOccurrences(of: " ", with: "")
return lowerSelf.sorted() == lowerOther.sorted() // first error:Value of type 'String' has no member 'sorted
}
func isPalindrome() -> Bool {
let f = self.lowercased().replacingOccurrences(of: " ", with: "")
let s = String(describing: f.reversed()) //second error:Value of type 'String' has no member 'reversed'
return f == s
}
}
In Swift 3 a String itself is not a collection, so you have to
sort or reverse its characters view:
extension String {
func isAnagramOf(_ s: String) -> Bool {
let lowerSelf = self.lowercased().replacingOccurrences(of: " ", with: "")
let lowerOther = s.lowercased().replacingOccurrences(of: " ", with: "")
return lowerSelf.characters.sorted() == lowerOther.characters.sorted()
}
func isPalindrome() -> Bool {
let f = self.lowercased().replacingOccurrences(of: " ", with: "")
return f == String(f.characters.reversed())
}
}
A slightly more efficient method to check for a palindrome is
extension String {
func isPalindrome() -> Bool {
let f = self.lowercased().replacingOccurrences(of: " ", with: "")
return !zip(f.characters, f.characters.reversed()).contains(where: { $0 != $1 })
}
}
because no new String is created, and the function "short-circuits",
i.e. returns as soon as a non-match is found.
In Swift 4 a String is collection of its characters, and
the code simplifies to
extension String {
func isAnagramOf(_ s: String) -> Bool {
let lowerSelf = self.lowercased().replacingOccurrences(of: " ", with: "")
let lowerOther = s.lowercased().replacingOccurrences(of: " ", with: "")
return lowerSelf.sorted() == lowerOther.sorted()
}
func isPalindrome() -> Bool {
let f = self.lowercased().replacingOccurrences(of: " ", with: "")
return !zip(f, f.reversed()).contains(where: { $0 != $1 })
}
}
Note also that
let f = self.lowercased().replacingOccurrences(of: " ", with: "")
returns a string with all space characters removed. If you want
to remove all whitespace (spaces, tabulators, newlines, ...) then use
for example
let f = self.lowercased().replacingOccurrences(of: "\\s", with: "", options: .regularExpression)

Use of unresolved identifier while using extension in swift 3

I have made a String extension for validating the form in Swift 3 language.
The code is below:
import UIKit
extension String {
// Validating Email ID
func isValidEmail(testStr:String) -> Bool {
let emailRegEx = "[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
let emailTest = NSPredicate(format:"SELF MATCHES %#", emailRegEx)
return emailTest.evaluate(with: testStr)
}
// Validating the User name
func isValidUserName(testStr:String) -> Bool {
let RegEx = "\\A\\w{7,18}\\z"
let Test = NSPredicate(format:"SELF MATCHES %#", RegEx)
return Test.evaluate(with: testStr)
}
// Validating the phone number
var isPhoneNumber: Bool {
do {
let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.phoneNumber.rawValue)
let matches = detector.matches(in: self, options: [], range: NSMakeRange(0, self.characters.count))
if let res = matches.first {
return res.resultType == .phoneNumber && res.range.location == 0 && res.range.length == self.characters.count
} else {
return false
}
} catch {
return false
}
}
// validating the password
/*
Use the function of Swift 3.0.
1. 8 characters length
2. alphabet
3. special character
regex Syntax Explanation :
(?=.[a-z]) for Character.
(?=.[$#$#!%?&]) for special character.
{8,} for length which you want to prefer.
*/
func isPasswordValid(_ password : String) -> Bool{
let passwordTest = NSPredicate(format: "SELF MATCHES %#", "^(?=.*[a-z])(?=.*[$#$#!%*?&])[A-Za-z\\d$#$#!%*?&]{8,}")
return passwordTest.evaluate(with: password)
}
// validating the password and confirm password are same........................
func isPasswordSame(password: String , confirmPassword : String) -> Bool {
if password == confirmPassword{
return true
} else {
return false
}
}
// validating Blank Text........................
var isBlank:Bool {
return self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).isEmpty
}
}
But when i am trying to use this extension class in other view controller through the code :
if isValidEmail("kirit#gmail.com"){
print("Validate EmailID")
}
else{
print("invalide EmailID")
}
I am getting the error:
isValidEmail is not a loose function. You have defined it as an instance function on String. You would need to say
"someString".isValidEmail(testStr:"someOtherString")
That makes no sense, but that's how you've configured it. If you write it that way, your code will compile (though it will be very silly code).
Just change your definition to something like
extension String {
// Validating Email ID
func isValidEmail() -> Bool {
self.validate...
}
and then use it in your code as
#someString".isValidEmail()