192

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?

Marcus Leon
  • 55,199
  • 118
  • 297
  • 429
chrisjlee
  • 21,691
  • 27
  • 82
  • 112
  • 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. – Tom Andersen Feb 01 '18 at 19:27

16 Answers16

267

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".

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
chrisjlee
  • 21,691
  • 27
  • 82
  • 112
  • 1
    You can also use isEqualToString, which comes in handy if you're initializing the var with NSString ('var emptyString: NSString'): emptyString.isEqualToString("") – Sven Sep 17 '14 at 19:17
  • 2
    this condition fails when user enter spaces. – Shanu Singh Feb 29 '20 at 12:36
  • Update: Here's isEmpty: https://developer.apple.com/documentation/swift/string/2946268-isempty – chrisjlee Mar 03 '20 at 17:16
131

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")
}
Vadim
  • 5,154
  • 2
  • 20
  • 18
Albert Bori
  • 9,832
  • 10
  • 51
  • 78
67

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.

Community
  • 1
  • 1
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
53

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")
}
Saranjith
  • 11,242
  • 5
  • 69
  • 122
31

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
emp
  • 3,350
  • 1
  • 22
  • 19
Evgenii
  • 36,389
  • 27
  • 134
  • 170
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.

John Montgomery
  • 6,739
  • 9
  • 52
  • 68
  • 1
    Got excited about this, but it didn't work :( I'm on Swift 3.0 – teradyl Sep 07 '17 at 02:02
  • @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. – John Montgomery Sep 07 '17 at 06:14
  • As in I still get a compile-time error when I try to use `optionalString?isBlank` that it need to be unwrapped. – teradyl Sep 07 '17 at 22:28
  • @teradyl Do you still have the `?` in there? You need to remove that, otherwise it'll try to call the `String` version rather than the `Optional` version - that's what I meant by autocomplete messing up. – John Montgomery Sep 07 '17 at 22:34
  • 1
    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. – Carsten Hagemann Aug 03 '18 at 14:44
  • 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). – John Montgomery Aug 03 '18 at 17:14
  • one liner `self?.isBlank ?? true` – Leo Dabus Sep 16 '20 at 01:38
9

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

if(yourString?.characters.count > 0){}
MadNik
  • 7,713
  • 2
  • 37
  • 39
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.

Swiftly
  • 51
  • 1
  • 2
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
}
UnRewa
  • 2,462
  • 2
  • 29
  • 31
2

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
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
yoAlex5
  • 29,217
  • 8
  • 193
  • 205
1

For optional Strings how about:

if let string = string where !string.isEmpty
{
    print(string)
}
PiXeL16
  • 808
  • 8
  • 5
1
if myString?.startIndex != myString?.endIndex {}
IceMan
  • 71
  • 1
  • 4
1

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.

moonvader
  • 19,761
  • 18
  • 67
  • 116
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
        }
    }
}
0-1
  • 702
  • 1
  • 10
  • 30
Aymen A4
  • 21
  • 2
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")
}
0

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)
rgreso
  • 496
  • 1
  • 7
  • 19