• Skip to main content
  • Skip to primary sidebar

Ravi Shankar

Tweaking Apps

  • About
  • Portfolio
  • Privacy Policy

Extensions

Closures, Extensions and Generics in Swift

May 22, 2015 By Ravi Shankar Leave a Comment

Closures

Closures are self contained lines of code that can be passed around the application and similar to blocks in Objective-C. A typical closure syntax in Swift looks as shown below

Closure Syntax

[code language=”swift”]{ (parameters) -> return type in
statements
}[/code]

Example closure in Swift

[code language=”swift”]{ (name:String, message:String -> (String) in
message + ” ” + name + ” !!!”
}
greetings(“Ravi”,”Welcome”)
[/code]

 

In the above code example, a closure has been assigned to a variable. The purpose of this closure is to concatenate the string parameters and return the appended message as return parameter.

Type Inference

The example closure can modified to ignore to the parameter types and closure supports type inference.

[code language=”swift”]var greetings = { (name, message) -> (String) in
return message + ” ” + name + ” !!!”
}

greetings(“Ravi”,”Welcome”)[/code]

Implicit return

In single expression closure, you can omit the return keyword.

[code language=”swift”]var numbers = [23,45,67,89,89,78]
numbers.sort { (number1, number2) -> Bool in
return number1 < number2
}

// numbers.sort { number1, number2 in return number1 < number2 }
numbers.sort { number1, number2 in number1 < number2 } // Shorthand argument syntax
numbers.sort { $0 < swift }[/code]

Shorthand Argument Syntax

Swift supports shorthand argument names for inline closures. In the above example used for implicit returns, the two parameters can be removed and represented in shorthand arguments as shown below.

[code language=”swift”]numbers.sort { $0 < swift }
[/code]

Trailing Closure

In a function with closure as the last parameter, the closure can be treated as trailing closures i.e closures outside the function parenthesis call. This is quite helpful in reducing the long closure expression. For example, the sorted function has closure as the last parameter and with trailing closure this becomes as shown below.

[code language=”swift”]var numbers = [23,45,67,89,89,78]
var sortedNumbers = sorted(numbers, {$0 > swift}) // Without trailing closure
// var sortedNumbers = sorted(numbers) {$0 > swift} // represented as trailing closure

sortedNumbers[/code]

Extensions

Swift extensions are similar to category in Objective-C which adds new functionally to existing class, enumeration or Struct. Extension does not require the source code of original class or enumeration type or struct to extend their functionality.

Listed below is an example which extends String class. A new function fromDouble has been added to String class which takes a double value and returns String.

[code language=”swift”] extension String {
static func fromDouble(doubleValue: Double) -> String {
var temp = String(format: “%.2f”, doubleValue)
return temp as String
}
}
String.fromDouble(24.50)[/code]

Generics

Generics are code that produces the same result irrespective of the data type. Listed below is a function that accepts an array of type string and reverses the array items.

[code language=”swift”]let strTemp = [“Deepak”,”John”,”Steve”,”Ravi”,”Ganesh”]

// reverse array with String
func reverseString(items: Array) -> Array {
var temp = Array()
return items.reverse()
}
reverseString(strTemp)[/code]

Now the below function accepts array of number and reverses the items

[code language=”swift”] let numbers = [23,45,56,78,98]
// reverse array with numbers
func reverseNumber(items: Array) -> Array {
return items.reverse()
}
reverseNumber(numbers)[/code]

Generics solves the problem of having different set of code for different data types by implemting the functionality for a generic type.

[code language=”swift”]let strTemp = [“Deepak”,”John”,”Steve”,”Ravi”,”Ganesh”]
let numbers = [23,45,56,78,98]

func reverseItems(items:[T])-> [T] {
return items.reverse()
}
reverseItems(strTemp)
reverseItems(numbers)[/code]

You can also implement a Generic class with this function as shown below.

[code language=”swift”]let strTemp = [“Deepak”,”John”,”Steve”,”Ravi”,”Ganesh”]

class ReverseDemo {
func reverseItems(items:[P])-> [P] {
return items.reverse()
}
}
let reverseDemo = ReverseDemo()
reverseDemo.reverseItems(strTemp)
[/code]

Swift Operations with Generics

Let us say you want to create a generic function that returns the square value of the given number. The immediate solution that comes to your mind is

[code language=”swift”]func squareOfNumber(number:M -> M{
return number * number
}
[/code]

This is not as straight forward as we think, you would notice an error – “Binary operator ‘*’ cannot be applied to two M operands”. The generic data type does not recogonize the operator ‘*’. We can fix this by creating a new protocol that tells about this operator ‘*’ and Generic type should conform to this protocol as shown below.

[code language=”swift”]protocol Multipliable {
func *(lhs:Self, rhs: Self) -> Self
}

func squareOfNumber(number:M -> M{
return number * number
}
[/code]

Then add an extension to Int, Float and other required types and make them conform to Multipliable protocol.

[code language=”swift”]extension Int: Multipliable {}
extension Float: Multipliable {}

squareOfNumber(20)[/code]

Download source code from gitHub (Generic)

Filed Under: Apple, Develop, Programming Tagged With: Closures, Extensions

Primary Sidebar

Recent Posts

  • We have blocked all requests from this device – Firebase Phone Authentication
  • iPhone is not available error message in Xcode
  • Clear CocoaPods cache, re-download and reinstall all pods
  • PDFKit – View, Annotate PDF file in Swift
  • Tab Bar Controller with WebView

Archives

  • September 2020
  • April 2020
  • December 2019
  • November 2019
  • October 2019
  • February 2019
  • October 2017
  • June 2017
  • May 2017
  • March 2017
  • September 2016
  • March 2016
  • February 2016
  • January 2016
  • December 2015
  • November 2015
  • October 2015
  • September 2015
  • August 2015
  • July 2015
  • June 2015
  • May 2015
  • April 2015
  • March 2015
  • February 2015
  • January 2015
  • December 2014
  • November 2014
  • October 2014
  • September 2014
  • August 2014
  • July 2014
  • June 2014
  • April 2014
  • March 2014
  • February 2014
  • January 2014
  • December 2013
  • October 2013
  • August 2013
  • July 2013
  • June 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • November 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • April 2011
  • March 2011
  • January 2011
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • July 2009
  • March 2008

Copyright 2020 © rshankar.com