I am trying to validate an email field using Regex in Swift - swift

I am simply trying to validate an email using an expression. I have created a Struct that I use for my form fields.
let emailRegEx = "[A-ZO-9a-z._%+-]+#[A-Za-zO-9.-J+|l.[A-Za-z]{2,64}"
var isEmailValid: Bool {
!email.isEmpty &&
if email.ranges(of: emailRegEx, options: .regularExpression) == nil {
return self
}
}
It keeps throwing this error...Cannot infer contextual base in reference to member 'regularExpression', and Expected expression after operator, lastly Extra argument 'options' in call.

Your if is in the wrong place, and .ranges should be .range.
Assuming your emailRegEx is correct, try this:
var isEmailValid: Bool = !email.isEmpty && (email.range(of: emailRegEx, options: .regularExpression) != nil)
Using a computed var, use this:
var isEmailValid: Bool {
!email.isEmpty && (email.range(of: emailRegEx, options: .regularExpression) != nil)
}
You could also try this regex for email:
let emailRegEx = #"^\S+#\S+\.\S+$"#
Or
let emailRegEx = #"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$"#
See also this SO post: How to validate an e-mail address in swift?

Related

How to use OR for a value that can be nil?

This is very basic but I'm kinda confused why my code isn't working. I have a user that has an optional username and I am trying to check whether the email or username contains my search query
struct ChatUser: Codable, Identifiable {
let email: String
var username: String?
}
#State var user: ChatUser
if user.email.lowercased().contains(search.lowercased()) ||
user.username.lowercased().contains(search.lowercased()) {...}
It works if I unwrap user.username! but then my App crashes due to unwrapping nil values. How do I check for user.username != nil and then force unwrap in the if check?
Calling lowercased() again and again is unnecessarily expensive.
But with your given syntax this is the swifty way
if user.email.lowercased().contains(search.lowercased()) ||
user.username?.lowercased().contains(search.lowercased()) == true {...}
The Optional Chaining expression returns nil immediately if username is nil.
However range(of:options: can handle the optional and the case
if user.email.range(of: search, options: .caseInsensitive) != nil ||
user.username?.range(of: search, options: .caseInsensitive) != nil {
}
You can use nil-coalescing(??) to unwrap your optional value.
if user.email.lowercased().contains(search.lowercased()) ||
user.username?.lowercased().contains(search.lowercased()) ?? false {
}
if user.email.lowercased().contains(search.lowercased()) ||
(user.username.map { $0.lowercased().contains(search.lowercased()) } ?? false) {
}

how I can get the domain extensions from UITextField?

I want to accept the users who're studying at University, so I need to only accept the email format as
studentname#inst**.edu** or
studentname#inst**.edu.tr**
how can I verify that by using regex or another method in Swift 5? Thx.
extension String {
func regex(_ regex: String) -> Bool {
return self.range(of: regex, options: .regularExpression) != nil
}
}
let email = "blah_email#inst.edu"
email.regex(#"^[\w]+#inst\.edu$"#)
// If email is of the form: "(...)#inst.edu", it will return true

How to specify the type of text in UITextField

I'm trying to determine whether or not a user is entering a proper email address into a UITextField . I'm using this code but am getting the following error message.
func isValidEmail(testStr:String) -> Bool {
let emailRegEx = "[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
let range = testStr.rangeOfString(emailRegEx, options:.RegularExpressionSearch) // I'm getting the error message here.
let result = range != nil ? true : false
return result
}
#IBAction func logIn(sender: AnyObject) {
let validLogin = isValidEmail(testStr: field.text!)
if validLogin {
print("User entered valid input")
} else {
print("Invalid email address")
}
}
This is the error message I'm getting: "Value of type 'String' has no member 'rangeOfString'"
I think this is because I don't have RegExKitLite installed but I'm not 100% sure. Even so, I tried installing the kit but I couldn't figure out how. I downloaded the file but I can't figure out how to add it in Xcode.
If you are using Swift 3 or later, the lines:
let range = testStr.rangeOfString(emailRegEx, options:.RegularExpressionSearch)
let result = range != nil ? true : false
return result
needs to be:
let range = testStr.range(of: emailRegEx, options: [ .regularExpression ])
return range != nil
None of this needs a third party library.
You probably also want to make sure the whole string matches so you should add ^ to the start of the regular expression and add $ to the end.

Should we do nil check for non-optional variables?

I have a function (abc) as follows and I should throw an error when the arguments passed are empty or nil, should I check for nil too or only empty is enough?
public func abc(forURL serviceUrl:String,serviceID:String, error:inout Error? )throws ->[AnyHashable : Any]{
guard serviceUrl != nil, !serviceUrl.isEmpty else {
let argError:Error = MapError.emptyArgumentUrl.error()
error = argError
throw argError
}
guard !serviceID.isEmpty else {
let argError:Error = MapError.emptyArgumentServiceId.error()
error = argError
throw argError
}
serviceID is not an optional.
That means it can't be nil.
So no, there is no need for that check.

Swift: Optional Text In Optional Value

How to remove Optional("") text on optional value when displaying without forcing to !.
Update
// I have somthing like this declared outside class
// I put question mark wrapper since I don't know when this session might have a value
var url = "\(self.session?.apiURL)/api/products.json"
// private session
private var _session:Session?
class MyClass
{
.
.
.
// the value of apiURL depends on session, session has optional value and declared as
// custom lazy loaded var session
var session:Session?
{
get
{
if _session == nil
{
_session = // fetch from coredata store if there is an active session. Might return nil
// if no active session
if _session == nil
{
// I just print "No active session"
}
}
// return _session may or may not contain any value
return _session
}
}
}
When the session has a value the url has a value:
Optional("my_api_url_here")/api/products.json
You can use this pod http://cocoapods.org/pods/NoOptionalInterpolation.
Alternatively, add this code to your project to remove the Optional(...) and nil text in string interpolation:
public protocol Unwrappable {
func unwrap() -> Any?
}
extension Optional: Unwrappable {
public func unwrap() -> Any? {
switch self {
case .None:
return nil
case .Some(let unwrappable as Unwrappable):
return unwrappable.unwrap()
case .Some (let some):
return some
}
}
}
public extension String {
init(stringInterpolationSegment expr: Unwrappable) {
self = String(expr.unwrap() ?? "")
}
}
Please note that simply overriding the description function of Optional won't work for string interpolation, although it works for print.
you can use ?? (null coalescing operator) to unwrap it and provide a default value if it is nil
let sessionApiURL = self.session?.apiURL ?? ""
var url = "\(sessionApiURL)/api/products.json"
If you want to without optional value you have to unwrap the Optional. You can use "optional binding" to unwrap an Optional:
if let url = self.session?.apiURL{
//you can use url without optional
print(url)
}
You can check my example in online swift playground for better understand.