194

In Objective C, one could do the following to check for strings:

if ([myString isEqualToString:@""]) {
    NSLog(@"myString IS empty!");
} else {
    NSLog(@"myString IS NOT empty, it is: %@", myString);
}

How does one detect empty strings in Swift?

1
  • 4
    Your objective code is wrong. It fails badly for nil strings. In objective C one actually uses: if (myString.length) { 'its a string with length} . This works on nil strings as well . That's simple and easy to read. Commented Feb 1, 2018 at 19:27

16 Answers 16

273

There is now the built in ability to detect empty string with .isEmpty:

if emptyString.isEmpty {
    print("Nothing to see here")
}

Apple Pre-release documentation: "Strings and Characters".

Sign up to request clarification or add additional context in comments.

4 Comments

You can also use isEqualToString, which comes in handy if you're initializing the var with NSString ('var emptyString: NSString'): emptyString.isEqualToString("")
this condition fails when user enter spaces.
The isEmpty method should be a static method of the String class, like it is in C#, that way it could detect either emtpy and nil strings all at once.
132

A concise way to check if the string is nil or empty would be:

var myString: String? = nil

if (myString ?? "").isEmpty {
    print("String is nil or empty")
}

2 Comments

This is beautiful, but how would you use the unwrapped value? Force unwrap?
@halfnibble You can do either (implicit or forced unwrap) or you could do: if let myString = myString where !myString.isEmpty { ... }
68

I am completely rewriting my answer (again). This time it is because I have become a fan of the guard statement and early return. It makes for much cleaner code.

Non-Optional String

Check for zero length.

let myString: String = ""

if myString.isEmpty {
    print("String is empty.")
    return // or break, continue, throw
}

// myString is not empty (if this point is reached)
print(myString)

If the if statement passes, then you can safely use the string knowing that it isn't empty. If it is empty then the function will return early and nothing after it matters.

Optional String

Check for nil or zero length.

let myOptionalString: String? = nil

guard let myString = myOptionalString, !myString.isEmpty else {
    print("String is nil or empty.")
    return // or break, continue, throw
}

// myString is neither nil nor empty (if this point is reached)
print(myString)

This unwraps the optional and checks that it isn't empty at the same time. After passing the guard statement, you can safely use your unwrapped nonempty string.

Comments

54

In Xcode 11.3 swift 5.2 and later

Use

var isEmpty: Bool { get } 

Example

let lang = "Swift 5"

if lang.isEmpty {
   print("Empty string")
}

If you want to ignore white spaces

if lang.trimmingCharacters(in: .whitespaces).isEmpty {
   print("Empty string")
}

3 Comments

Is there a difference between your answer and the excepted one?
This doesn't work if the user just enters a bunch of spaces.
In typography whitespaces are considered as a character so its not empty. If you want then change condition to 'lang.trimmingCharacters(in: .whitespaces).isEmpty'
32

Here is how I check if string is blank. By 'blank' I mean a string that is either empty or contains only space/newline characters.

struct MyString {
  static func blank(text: String) -> Bool {
    let trimmed = text.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
    return trimmed.isEmpty
  }
}

How to use:

MyString.blank(" ") // true

3 Comments

As an addendum, you may want to consider using the whitespaceAndNewlineCharacterSet instead of just whitespace.
thanks @fwielstra, ignoring new lines will be very useful as well.
21

You can also use an optional extension so you don't have to worry about unwrapping or using == true:

extension String {
    var isBlank: Bool {
        return self.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
    }
}
extension Optional where Wrapped == String {
    var isBlank: Bool {
        if let unwrapped = self {
            return unwrapped.isBlank
        } else {
            return true
        }
    }
}

Note: when calling this on an optional, make sure not to use ? or else it will still require unwrapping.

7 Comments

Got excited about this, but it didn't work :( I'm on Swift 3.0
@teradyl By "didn't work," do you mean you're getting an error, having issues with autocomplete, or something else? It should work unless something changed that I'm not aware of, but autocomplete won't always pick the right version.
As in I still get a compile-time error when I try to use optionalString?isBlank that it need to be unwrapped.
For me, this is not working with currentIncident.priority?.description.isBlank. Says: Value of optional type 'Bool?' not unwrapped; did you mean to use '!' or '?'?. I have to do (currentIncident.priority?.description ?? "").isBlank which makes the extensions sorta pointless. Swift 4.1.
@CarstenHagemann That's because priority is the optional there. If just description were optional it would work, but you can't work around a parent object being optional like that (because if priority is nil, then it doesn't even have a description property to check for blank-ness in the first place).
|
9

To do the nil check and length simultaneously Swift 2.0 and iOS 9 onwards you could use

if(yourString?.characters.count > 0){}

Comments

5

isEmpty will do as you think it will, if string == "", it'll return true. Some of the other answers point to a situation where you have an optional string.

PLEASE use Optional Chaining!!!!

If the string is not nil, isEmpty will be used, otherwise it will not.

Below, the optionalString will NOT be set because the string is nil

let optionalString: String? = nil
if optionalString?.isEmpty == true {
     optionalString = "Lorem ipsum dolor sit amet"
}

Obviously you wouldn't use the above code. The gains come from JSON parsing or other such situations where you either have a value or not. This guarantees code will be run if there is a value.

Comments

3

I can recommend add small extension to String or Array that looks like

extension Collection {
    public var isNotEmpty: Bool {
        return !self.isEmpty
    }
}

With it you can write code that is easier to read. Compare this two lines

if !someObject.someParam.someSubParam.someString.isEmpty {}

and

if someObject.someParam.someSubParam.someString.isNotEmpty {}

It is easy to miss ! sign in the beginning of fist line.

Comments

3

Swift String (isEmpty vs count)

You should use .isEmpty instead of .count

  • .isEmpty Complexity = O(1)

  • .count Complexity = O(n)

isEmpty does not use .count under the hood, it compares start and end indexes startIndex == endIndex

Official doc Collection.count

Complexity: O(1) if the collection conforms to RandomAccessCollection; otherwise, O(n), where n is the length of the collection.

Single character can be represented by many combinations of Unicode scalar values(different memory footprint), that is why to calculate count we should iterate all Unicode scalar values

String = alex
String = \u{61}\u{6c}\u{65}\u{78}
[Char] = [a, l, e, x]

Unicode text = alex
Unicode scalar values(UTF-32) = u+00000061u+0000006cu+00000065u+00000078
1 Character == 1 extended grapheme cluster == set of Unicode scalar values

Example

//Char á == extended grapheme cluster of Unicode scalar values \u{E1}
//Char á == extended grapheme cluster of Unicode scalar values \u{61}\u{301}

let a1: String = "\u{E1}" // Unicode text = á, UTF-16 = \u00e1, UTF-32 = u+000000e1
print("count:\(a1.count)") //count:1

// Unicode text = a, UTF-16 = \u0061, UTF-32 = u+00000061
// Unicode text =  ́, UTF-16 = \u0301, UTF-32 = u+00000301
let a2: String = "\u{61}\u{301}" // Unicode text = á, UTF-16 = \u0061\u0301, UTF-32 = u+00000061u+00000301
print("count:\(a2.count)") //count:1

Comments

2

Check check for only spaces and newlines characters in text

extension String
{
    var  isBlank:Bool {
        return self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).isEmpty
    }
}

using

if text.isBlank
{
  //text is blank do smth
}

Comments

1

For optional Strings how about:

if let string = string where !string.isEmpty
{
    print(string)
}

Comments

1
if myString?.startIndex != myString?.endIndex {}

Comments

1

You can use this extension:

extension String {

    static func isNilOrEmpty(string: String?) -> Bool {
        guard let value = string else { return true }

        return value.trimmingCharacters(in: .whitespaces).isEmpty
    }

}

and then use it like this:

let isMyStringEmptyOrNil = String.isNilOrEmpty(string: myString)

1 Comment

I like this solution the best out of the working proposals, because it is the easiest to read when you use it, which is more important to me than clever Swift. One change I did make is to the function signature: I prefer static func isNilOrEmpty(_ string: String?) -> Bool, but of course that's just a preference
1
public extension Swift.Optional {
    
    func nonEmptyValue<T>(fallback: T) -> T {
        
        if let stringValue = self as? String, stringValue.isEmpty {
            return fallback
        }
        
        if let value = self as? T {
            return value
        } else {
            return fallback
        }
    }
}

Comments

0

What about

if let notEmptyString = optionalString where !notEmptyString.isEmpty {
    // do something with emptyString 
    NSLog("Non-empty string is %@", notEmptyString)
} else {
    // empty or nil string
    NSLog("Empty or nil string")
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.