Optionals In Swift

Introduction

 
Optionals in Swift can hold a value or not hold any value. An Optional is a container that might store a string in it, or it might be empty. It has a lot of extra support built into the language.
                       

Implicit Optional Behavior

 
The implicit optional behavior is similar to non-optional values. Unwrap techniques are used to handle optional chaining.
  1. var s : String! = "Hello"    
  2. s?.isEmpty    
  3. if let s = s     
  4. {    
  5.  print( s )    
  6. }    
  7. s = nil    
  8. s??"Good"    
If Let
 
The if let statement is used to check if optional values are nonnil and it unwraps the optionals. The type of idx is Int and the idx is a variable within the scope of the statement. The boolean clauses are used together with the if let and the element is not removed when it happened to the first one of the array. Multiple values can be bound to the if statement. The try is used when the data initializer throws an error.
  1. let urlString = "https://www.websta.unauc.com.png"    
  2. if let url = URL (string : urlString) ,    
  3. let data = try? Data( ContentsOf:url),    
  4. let image = UIImae (data : data)    
  5. {    
  6.  let view = UIImageView (image : image)    
  7.  PlaygroundPage.current.liveView = view    
  8. }    
While let
 
While let is a loop that terminates when the condition of the loop returns nil. The standard library readline is a function that is used to return an optional string from standard input. While let is used to implement a basic equivalent of Unix cat command. The loop is terminated by adding a clause to detect an empty string. collection protocol provides a make iterator method that returns an iterator and it has the next method.
  1. var  iterator2 = (0..<10). makeIterator ()  
  2. while let i = iterator2.next()  
  3. {  
  4.  guard i%2 == 0   
  5.  else  
  6. {  
  7.  continue  
  8. }  
  9. print(i)  
  10. }  

Double Nested Optionals

 
The type optional wraps can itself be optional, which leads to optionals nested inside optionals. The case-based pattern matching is a way that is used to apply the same rules that work in a switch statement to if statement, for statement, and while statement.
  1. for case let i? maybeInts  
  2. {  
  3.  print (i , teminator : " ")  
  4. }  
  5.   
  6. // only nil values  
  7.   
  8. for case nil in maybeInts  
  9. {  
  10.  print (" Not vales present ")  
  11. }  
  12.   
  13. //let j = 5  
  14.  if case 0..<10 = j  
  15. {  
  16.  print ("\(j) within range")  
  17. }  
Output
 
5 within range.
 
If var and while var
 
The if, while, and for statement is used instead of let statement. This allows us to mutate the variable inside the statement body. Optionals are value types that unwrap the copies from the value inside.
  1. let number = "1"  
  2. if var i = Int(number)  
  3. {  
  4.  i += 1  
  5.  print(i)  
  6. }  
Unwrapped Optionals
 
The first property returns an optional of the first element, or nil when the array is empty. The optional have to unwrap in order to use it. The unwrapped value is present inside the if let block. The compiler checks the code to confirm the two possible paths in which the function returns the period.
  1. extension String    
  2. {    
  3.  var fileExtension : String?    
  4. {    
  5.  let period : String.Index    
  6.  if let idx = lastIndex (of : ".")    
  7. {    
  8.  period = idx    
  9. }    
  10.  else    
  11. {    
  12.  return nil    
  13. }    
  14. let extensionStart = index (after : period)    
  15.  return String (self [ extensionStart ])    
  16. }    
  17. }    
Optional Chaining
 
Sending a message to nil is a no-op and it is implemented by the optional chaining and when the method is called by optional chaining it returns a result, and the result is optional. The result is optional when the optional chaining returns a result. The didChange property stores the callback function and the text field is called when the user edits the text.
  1. func textDidChange(newText: String) {  
  2.     text = newText  
  3.     didChange ? (text)  
  4. }  
  5. }