# Can this Swift code be simplified?

let name_cache = NSCache<NSString, NSString>()

if let name = name_cache.object(forKey: "name") {
self.name_text_field.text = name as String
}
else if let name = dictionary["name"] as? String {
name_cache.setObject(name, forKey: "name")
self.name_text_field.text = name as String
}


Is there any way to condence this block? The if let statements both save to a variable of the same name (name), and I write the same line of code in each case (self.name_text_field.text = name as String).

• Please explain what "this Swift code" does, and what the name_cache is for. See How to Ask. Apr 1 '17 at 20:29

Optional chaining can be used to condense the check into a single line.

Example:

let name_cache = NSCache<NSString, NSString>()
if let name = name_cache.object(forKey: "name") ?? (dictionary["name"] as? String) {
name_cache.setObject(name, forKey: "name")
self.name_text_field.text = name as String
}


This first tries to unwrap the value from name_cache. If the result is nil then it tries to unwrap the value from dictionary. If one of these has a value then name will be defined. The inner block will execute and set the cache value and the text field.

Advice: Encapsulating the cache and dictionary into a helper class would lead to cleaner separation of responsibilities. E.g.

Model

struct Model {
var cache = NSCache<NSString, NSString>()
var dictionary = Dictionary<String, String>()
mutating func value(forKey key: String) -> String? {
guard let value = cache.object(forKey: key) ?? dictionary[key] else {
return nil
}
cache.setObject(value, forKey: key)
return value
}
}


Usage

var model = Model()
self.name_text_field.text = model.value(forKey: "name")