Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift - Check nil of an unwrapped optional variable

I am having a model class as follows, which is in a library written in Objective-C. I am consuming this class in my swift project. In swift it becomes property of type String!. Sometimes that property will be nil. So, I am testing the nil validation as follows:

Vendor.h

@interface Vendor: NSObject {

@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSString *middleName;
}

In my Swift project, I am checking the nil validation for the middleName property as below:

if anObject.middleNam != nil { // Here, It throws runtime error: fatal error: Unexpectedly found nil while unwrapping an Optional value
}

It throws me an following runtime error:

fatal error: unexpectedly found nil while unwrapping an Optional value

If the objective-C properties exposed in swift as String? then I would have used the following:

if let middleName = anObject.middleName {

}

How would I check for the unwrapped optional variable.

Thanks in advance.

like image 942
Shanmugaraja G Avatar asked Jun 28 '16 08:06

Shanmugaraja G


2 Answers

If you want ObjectiveC property to be exposed in Swift as optional, mark it with _Nullable tag like

@property (nonatomic, strong) NSString * _Nullable middleName;

Now middleName name would be optional of type String? instead of String! and you could conditionally unwrap it.

Read more about Nullability in ObjC

like image 177
Anil Varghese Avatar answered Sep 27 '22 23:09

Anil Varghese


As Anil mentioned, the best solution would be to edit your objective-c code to add some _Nullable. But, as I understand, your Objective-C code is a library that you cannot edit. So, you have to deal with these String! that can be nil.

But you can simply use if let technique like this:

if let firstName = vendor.firstName {
    print("Here is my firstName: \(firstName)")
} else {
    print("I have no firstName")
}
if let middleName = vendor.middleName {
    print("Here is my middleName: \(middleName)")
} else {
    print("I have no middleName")
}

if let lastName = vendor.lastName {
    print("Here is my name: \(lastName)")
} else {
    print("I have no lastName")
}

With this Vendor code, it returns the following result:

@interface Vendor: NSObject
    @property (nonatomic, strong) NSString *firstName;
    @property (nonatomic, strong) NSString *lastName;
    @property (nonatomic, strong) NSString *middleName;
@end
@implementation Vendor
- (instancetype)init
{
    self = [super init];
    if (self) {
        self.firstName = @"Julien";
        self.middleName = nil;
        self.lastName = @"Quere";
    }

    return self;
}
@end

Result:

Here is my firstName: Julien 
I have no middleName 
Here is my name: Quere
like image 38
Julien Quere Avatar answered Sep 28 '22 00:09

Julien Quere