Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I condense unwrapping multiple optionals in Swift?

I want to unwrap these 6 optional variables, and if they are null i want to give them a blank String value. This is so I can send these variables packaged into a parameters array that's sent to an API.

I'm still a beginner at Swift, and this is the only easiest way I have understood how to implement this, but the inner coder in me is saying this looks redundant and crappy as ****.

Can someone help me condense this or make it simpler?

    if let fbEmail = self.fbEmail {

    }else{
        self.fbEmail = ""
    }

    if let fbDob = self.fbDob {

    }else{
        self.fbDob = ""
    }

    if let fbGender = self.fbGender {

    }else{
        self.fbGender = ""
    }
    if let fbUserIp = self.fbUserIp {

    }else{
        self.fbUserIp = ""
    }
    if let fbFacebookId = self.fbFacebookId {

    }else{
        self.fbFacebookId = ""
    }
    if let fbFacebookAccessToken = self.fbFacebookAccessToken {

    }else{
        self.fbFacebookAccessToken = ""
    }
like image 644
trixmasta Avatar asked Dec 15 '22 11:12

trixmasta


2 Answers

You can do that in exactly 6 lines of code:

self.fbEmail  = self.fbEmail  ?? ""
self.fbDob    = self.fbDob    ?? ""
self.fbGender = self.fbGender ?? ""
self.fbUserIp = self.fbUserIp ?? ""
self.fbFacebookId = self.fbFacebookId ?? ""
self.fbFacebookAccessToken = self.fbFacebookAccessToken ?? ""

Edit: what's up with the ?? syntax: It's a shortcut "if nil assign another value":

let c = a ?? b

will assign c = a if a != nil, otherwise c = b.

like image 117
Code Different Avatar answered Dec 17 '22 01:12

Code Different


You can unwrap more than one at a time. But if you do, you will have no way of knowing which one is nil. You will only know that either some are nil or none are.

Aside from that do they all need to be optional? Can't you init them with the default values you are giving them when they are nil?


Snippets:

Just avoid the issue altogether.

// just init with a default value without them being an optional
var fbEmail : String = ""
var fbDob : String = ""

Replace checking for nil with .isEmpty

var string : String = ""

string.isEmpty // returns true

string = "SomeString"

string.isEmpty // returns false

Optionals with starting values.

// init wit default values while still optional
var fbEmail : String? = ""
var fbDob : String? = ""

Unwrap more than one at a time.

if let unwrfbEmail = fbEmail, let unwrfbDob = fbDob {
    // stuff available here
} else {
    // handle the error
}

guard let unwrfbEmail = fbEmail, let unwrfbDob = fbDob else {
    // put return/break here and handle the error
}
// stuff available here

A container for all values. They are optionals but when set to nil they will reset to a default value. You can also declare them as forced unwrapped optionals !. Or unwrap them all at once with a method found above. Obviously copy paste and alter the didSet to all variables.

// container stuct that uses didSet to avoid nil and reset to default values
struct container {

    var fbEmail : String? = "" {
        didSet {
            if fbEmail == nil {
                fbEmail = ""
            }
        }
    }
    var fbDob : String? = ""
    var fbGender : String? = ""
    var fbUserIp : String? = ""
    var fbFacebookId : String? = ""
    var fbFacebookAccessToken : String? = ""

}
like image 39
R Menke Avatar answered Dec 17 '22 00:12

R Menke