Book Image

iOS Programming Cookbook

Book Image

iOS Programming Cookbook

Overview of this book

Do you want to understand all the facets of iOS programming and build complex iOS apps? Then you have come to the right place. This problem-solution guide will help you to eliminate expensive learning curves and focus on specific issues to make you proficient at tasks and the speed-up time involved. Beginning with some advanced UI components such as Stack Views and UICollectionView, you will gradually move on to building an interface efficiently. You will work through adding gesture recognizer and touch elements on table cells for custom actions. You will work with the Photos framework to access and manipulate photos. You will then prepare your app for multitasking and write responsive and highly efficient apps. Next, you will integrate maps and core location services while making your app more secure through various encryption methods. Finally, you will dive deep into the advanced techniques of implementing notifications while working with memory management and optimizing the performance of your apps. By the end of the book, you will master most of the latest iOS 10 frameworks.
Table of Contents (22 chapters)
iOS Programming Cookbook
Credits
About the Author
About the Reviewer
www.PacktPub.com
Customer Feedback
Preface

Using extensions to extend classes functionality


For its name, extensions are used to extend an existing functionality. In Swift, you can extend classes, structures, protocols, and enumerations. Extensions are similar to categories in Objective-C except that extensions don't have names. It's very useful to add functionality to any type that you don't have access to its source code, such as native classes String, NSArray, and so on.

Getting ready

In Swift, syntax is pretty easy, and that's why it is awesome. To extend any type, just type the following:

extension TypeToBeExtended{ 
} 

Inside the curly braces, you can add your extensions to the type to be extended. In extension, you can do the following:

  • Adding instance- or class-computed properties

  • Adding instance or class methods

  • Adding new initializers

  • Defining subscripts

  • Adding nested types

  • Conforming to protocols

Once you create an extension to any type, the new functionality will be available for all instances in the whole project.

How to do it...

  1. Create a new playground file in Xcode called Extensions.

  2. Create extension for double value by adding computing properties, as follows:

       extension Double{ 
        
            var absoluteValue: Double{ 
              return abs(self) 
            } 
        
            var intValue: Int{ 
              return Int(self) 
            } 
          } 
     
          extension String{ 
        
            var length: Int{ 
              return self.characters.count 
            } 
          } 
     
          let doubleValue: Double = -19.5 
          doubleValue.absoluteValue // 19.5 
          doubleValue.intValue // 19 
     
          extension Int{ 
        
            func isEven() ->Bool{ 
              return self % 2 == 0 
            } 
        
            func isOdd() ->Bool{ 
              return !isEven() 
            } 
        
            func digits() -> [Int]{ 
              var digits = [Int]() 
              var num = self 
              repeat { 
                
                let digit = num % 10 
                digits.append(digit) 
                num /= 10 
                
              } while num != 0 
            
              return digits 
            } 
          } 
     
          let num = 12345 
          num.digits()  // [5, 4, 3, 2, 1] 
    

How it works...

In Double type, we have added two computed properties. The computed properties are properties that will be calculated every time when it's called. We've added a property called absoluteValue, which returns the absolute value; same for intValue, which returns the integer value of double. Then, for any double value in the whole project, these two properties are accessible and can be used.

In the Int type, we have defined three new instance methods. The isEven() method should return true if this number is even, false otherwise, and the same logic applies for isOdd(). The third method that has some more logic is digits(), which returns array of digits in the number. The algorithm is simple; we get the last digit by getting the remainder of dividing the number by 10, and then skip the last digit by dividing by 10.

There's more...

Extensions are not meant to add new properties and methods only. You extend types by adding new initializers, mutating methods, and by defining subscripts.

Mutating instance methods

When you add instance methods, you can let them mutate (modify) the instance itself. In methods we've added before, we just do some logic and return a new value, and the instance value remains the same. With mutating, the value of instance itself will be changed. To do so, you have to mark your instance method with the mutating keyword. Let's take a look at an example:

extension Int{ 
   mutating func square(){ 
       self = self * self 
   } 
    
   mutating func double(){ 
       self = self * 2 
   } 
} 
 
var value = 8 
value.double() // 16 
value.square() // 256 

When you mark your method as mutating, it lets you to change self and assign new value to it.

Adding new initializer

Extensions allow you to add new initializer to the currently available initializer for any particular type. For example, let's take a look at the CGRect class. CGRect has three initializers: empty init; init with origin and size; and init with x, y, width, and height. We will add new initializer with a center point and a rectangular size. Let's take a look at how to do it:

extension CGRect{ 
   init(center:CGPoint, size:CGSize){ 
       let x = center.x - size.width / 2 
       let y = center.y - size.height / 2 
       self.init(x: x, y: y, width: size.width, height: size.height) 
   } 
} 
 
let rect = CGRect(center: CGPoint(x: 50, y: 50), size: CGSizeMake(100, 80)) // {x 0 y 10 w 100 h 80} 

Define subscripts

One of features that extensions provide to us is the ability to define subscripts to a particular type. Subscripting allows you to get value by calling [n] to get information at index n. Like array, when you access item at that index, you can do the same with any type you want. In the following example, we will add subscripting support to the String type:

extension String{ 
   subscript(charIndex: Int) -> Character{ 
       let index = startIndex.advancedBy(charIndex) 
       return self[index] 
   } 
} 
let str = "Hello" 
str[0] // "H" 

To add subscript to type, just add the keyword subscript followed by index and the return type. In our preceding example, the subscript will return the character at a given index. We advanced the startIndex, which is a property in the String type and points to the first character by the input charIndex. Then, we return the character at that Index.