Showing posts with label isKindOfClass. Show all posts
Showing posts with label isKindOfClass. Show all posts

Friday, January 27, 2017

Swift 3.0 Object’s class checking isKindOfClass

We frequently need this type checking when getting response from the server. Where we need to check the type of objects based on which we need to parse the response.

In this post let’s see how can we check this using Swift 3.0.

In Objective-C/ Swift, It’s NSObject’s method isKindOfClass which helps for type checking.

I have two types of classes.

Employee



  
    var firstName: String?

    var lastName: String?
    var email: String?
    var gender: String?
    var isMarried: Bool = false
    

    init(firstName: String, lastName: String, email: String, gender: String, 
                                                                              isMarried: Bool) {
        self.firstName = firstName
        self.lastName = lastName
        self.email = email
        self.gender = gender
        self.isMarried = isMarried
    }


Employer



  
    var firstName: String?

    var lastName: String?
    var email: String?
    var gender: String?
    var isMarried: Bool = false
    var employeesCount:Int = 0    

    init(firstName: String, lastName: String, email: String, gender: String, 
                                                    isMarried: Bool, employeesCount:Int) 
    {
        self.firstName = firstName
        self.lastName = lastName
        self.email = email
        self.gender = gender
        self.isMarried = isMarried
        self.employeesCount = employeesCount
    }


Only Employer will have employees count.

Let’s take an array of Employee and Employer objects.


  
           let employee1 = Employee.init(firstName: "employee-1", 
                                                          lastName: "lastname-1", 
                                                          email: "employee1@gmail.com", 
                                                          gender: "Male", 
                                                          isMarried: true)

           let employee2 = Employee.init(firstName: "employee-2", 
                                                          lastName: "lastname-2", 
                                                          email: "employee2@gmail.com", 
                                                          gender: "Male", 
                                                          isMarried: true)

           let employer1 =  Employer.init(firstName: "XXX", 
                                                          lastName: "YYY", 
                                                          email: "xyz@gmail.com", 
                                                          gender: "Male", 
                                                          isMarried: true,
                                                          employeesCount: 32)
        
        
           let employees = [employee1, employee2, employer1]



I have taken 2 Employee objects and 1 Employer object and added them to an array. This is kind of Any Array in Swift.

Now the task is, We need to loop through this array and print employee count if the object is an Employer. Let’s see how this can be using Swift 3.0


  
        let employees = [employee1, employee2, employer1]

        
        for employee in employees {
            
            if (employee.isKind(of: Employer.self)) {
                
                let employeesCount = (employee as! Employer).employeesCount
                
                print("employeesCount : \(employeesCount)")   // employeesCount : 32
                
            }
            
        }



Hope this post is useful. Feel free to comment incase of any queries.



Sunday, June 26, 2016

Objective C Checking JSON format

In iOS applications, We use JSON format for web services as it is fast and easy to parse. JSON could be either in array or in dictionary format. It is a good practice to JSON format before parsing the response from a web service though we have perfect handshake with web service developers.


Let's take an example of fetching all the employees using a web service and there is a chance of JSON coming in any format as shown below.

JSON Dictionary:


 {"employees":

   [

     {"firstName":"Tim""lastName":"Cook"},

     {"firstName":"Will""lastName":"Smith"},

     {"firstName":"Leonardo""lastName":"Dicaprio"}

   ]


 }



JSON Array:


 [

    {"firstName":"Tim""lastName":"Cook"},

    {"firstName":"Anna""lastName":"Smith"},

    {"firstName":"Peter""lastName":"Jones"}


 ]



Using introspection methods in Objective C, We can check the type of JSON.


                         




  if([response isKindOfClass:[NSArray class]]){

      //JSON is in Array Format
  }

  if([response isKindOfClass:[NSDictionary class]]){

      //JSON is in Dictionary Format

  }




Hope this post is useful. Feel free to comment in case of any queries.




Wednesday, May 18, 2016

Objective C Dynamic Typing

When declaring property we give the data type strongly If we know what is the data that the variable is going to hold like shown below.



     
NSString *userName;
     float employeeSalary;
     BOOL isAvailable;


This is Static Typing as we declared (fixed) the data type of those variables.

Once we statically fix the data type of a variable, If we try to assign another data type value like shown below,



     
NSString *userName = 1; 


We will get a compile time error saying,

Implicit conversion of 'int' to 'NSString *' is disallowed in ARC

It means, we statically typed a variable and trying to assign a different data type.

What If we don't know the data type of a variable holding something?

For this, Objective-C has any object type called id. id data type variables can hold any data type.



     
id someObject;


Let's take example of some JSON coming from a web service response. This JSON format could be an array () or a dictionary {}. In this case let take this response into an id and check the data type of the response using the NSObject introspection methods.

Please check my post Objective C NSObject Root Class to know what are introspection methods.



     
id response = NSURLResponse;

     if([id isKindOfClass:[NSArray class]]){

            // Response is in Array format
   
     }

     if([id isKindOfClass:[NSDictionary class]]){

           // Response is in Dictionary format
   
     }


With this example, Hope you have understood what is Dynamic Typing and it's use case in Objective-C programming. id enables Dynamic Typing in Objective C. The data type of object is decided at run time.

As per Apple's Documentation,

A variable is dynamically typed when the type of the object it points to is not checked at compile time. Objective-C uses the id data type to represent a variable that is an object without specifying what sort of object it is. This is referred to as dynamic typing.

Dynamic typing contrasts with static typing, in which the system explicitly identifies the class to which an object belongs at compile time. Static type checking at compile time may ensure stricter data integrity, but in exchange for that integrity, dynamic typing gives your program much greater flexibility. And through object introspection (for example, asking a dynamically typed, anonymous object what its class is), you can still verify the type of an object at runtime and thus validate its suitability for a particular operation.



Hope this post is useful. Feel free to comment in case of any queries.

Friday, February 5, 2016

Objective C tagging views

We can tag views in Objective C using the UIView's tag property. Any object whose class is sub class of UIView class can be tagged like shown below.



  
[myView setTag:1234];


Let's say I have a view and it is having some sub views in it.



  
UIView *superView = [UIView alloc] init];


And I have some sub views added to it.



  
UIButton *subView1 = [UIButton alloc] init];
  [superView addSubView: subView1];

  UITextField *subView2 = [UITextField alloc] init];
  [superView addSubView: subView2];

  UILabel *subView3 = [UILabel alloc] init];
  [superView addSubView: subView3];



I have 3 sub views in my super view and to access these sub views fro my super view at run time, I have to go with below 

1. I need to make those subview objects (subView1, subView2, subView3) as global variables.


                         


(or)

2. I need to write a loop to access sub views of my super view based on their class as shown below.



  
for(UIView v in superView.views){
     
    if([v isKindOfClass:[UILabel class]]){
       //subView3
    }

    if([v isKindOfClass:[UITextField class]]){
       //subView2
    }

    if([v isKindOfClass:[UIButton class]]){
       //subView1
    }

 }



Here, superView.views gives an array of all the views that are added to the super view. Though these 2 approaches solves our need, they are having some limitations and result in bad coding practice.

The first approach makes me to declare variables globally to access them and gives a bunch of global variables finally.

The second approach fails when there are more than one label or one button added to my superview.

We can avoid these approaches and the limitations they cause by using the tagging funda. Let's see how we can tag views to access them easily from their super view whenever we need them.



  
[subView1 setTag:111];
  [subView2 setTag:112];
  [subView3 setTag:113];


I have tagged sub views at the time of adding it to my super view as shown above.

Now I can access them as shown below using the viewWithTag method of UIView class.



  
for(UIView v in superView.views){

     UILabel *lbl     = [superView viewWithTag:113];

     UITextField *tf = [superView viewWithTag:112];

     UIButton *btn  = [superView viewWithTag:111];

  }



Very simple and handy. Isn't it?



                         


All you have to do is to remember the tags assigned to the views. :)

Here, even though I have bunch of same type of controls, my logic doesn't fail.


Hope this post is useful. Feel free to comment incase of any queries.


Wednesday, September 16, 2015

Objective C NSObject Root Class

All the Objective C programmers know that the root class of all Objective C classes is NSObject. It is part of NSFoundation framework. Root class inherits from no other class. Let's see why it a root class and what it gives us to maintain that big name called 'Root Class'.

Here I am just detailing the information given in the Apple Documentation. I feel like the information is briefed in that documentation. I Just want to discuss in detail on this topic in this article. So If any one finds it similar to that apple documentation, please don't come back here and call me a copy cat :)

1. NSObject declares the fundamental object interface and 
    implements basic object behaviour.

2. NSObject gives us Introspection methods :

  • Methods like isKindOfClass and isMemberOfClass, to determine if an object inherits directly or indirectly from a particular class. For more information on these methods, checkout out my article here.
  • Methods like respondsToSelector, to find out if an object's class or super class implements a method.
  • Methods like confirmsToProtocol, to find out if a class confirms a particular protocol or not.


      So from this, and also as per the Apple Documentation,


  • You can call introspection methods as runtime checks to help you avoid problems such as exceptions, which, for example, would occur if you send a message to an object that cannot respond to it.
  • You can also use introspection to help locate an object in the inheritance hierarchy, which would give you information about the object’s capabilities.
3. NSObject gives us Memory management methods :

     Methods like alloc, dealloc, retain, copy etc.

4. NSObject gives us Method Invocation methods.



As it is giving us all these, we call NSObject as the root class of all Objective C classes.

Tuesday, September 15, 2015

Objective C isKindOfClass VS isMemberOfClass

We all know that NSObject is the base class in Objective c. Some times, We need to inherit the built in classes like NSArray, NSString and NSDictionary etc to add our required functionalities which are not given by those core classes. Like, I want an array which should give me all the elements by removing the duplicates if any. We can go for NSSet also for this feature. But, I need NSArray for a specific reason. In this case we need to write our own class which inherits from NSArray class. Suppose if I need that same functionality on NSString also, I need to create another sub class of NSString class.


                         



Instead of creating two separate sub classes for that similar functionality, We can write a method which accepts any data type as input, removes duplicates and returns the same data type as the return value.

Here is the method I am using to remove duplicates in NSArray or NSString.


- (id)removeDuplicates:(id)input{
    
    id output = nil;
    
    if([input isKindOfClass:[NSArray class]]){
        //loop array elements and remove duplicates and return an array
    }
    
    if([input isKindOfClass:[NSString class]]){
        //loop string characters and remove duplicates and return a string
    }
    
    return output;
    
}

If you observe, the input is of type id and output is of type id, which means any data type in Objective c. Here the point is how we can check whether the input is of type array or a string. In this case we can use NSObject's isKindOfClass to check whether the supplied input is of type NSArray or NSString. Based on the data type of the input, we can write that removing duplicates logic and return the result.

Now, let's see what is the use of NSObject's isMemberOfClass.

Let's say we have a Animal class. We have two sub classes of Animal class called Lion and Dog. I am not going to explain how to write such a classes as we are all much aware of that much object oriented programming using Objective c :)

 Lion *lion = [Lion alloc] init];  // Base class is Animal
 Dog *dog  = [Dog alloc] init];   // Base class is Animal


Let's say these animals have to make sound if they see their enemy. We all know that dogs bark and lions roar :). Let's say we have common method for that called 'makeSound'. 

- (id)makeSound:(id)input{    
      
    if([input isKindOfClass:[Lion class]]){
        [input roar];
    }    
    if([input isKindOfClass:[Dog class]]){
        [input bark];
    }      
}


In this case, like shown in the above code, if you use isKindOfClass, our dog is never gonna bark and our lion is never gonna roar :). It is because, isKindOfClass doesn't give you 'true' bool value for Lion and Dog classes. It will give you true value only if you write like the below code. But this always gives you roar sound though it's a dog or a lion.


- (id)makeSound:(id)input{    
      
    if([input isKindOfClass:[Animal class]]){
        [input roar];
    }    
    if([input isKindOfClass:[Animal class]]){
        [input bark];
    }      
}


Here comes isMemberOfClass, which gives true for immediate base class as shown in the below code.

- (id)makeSound:(id)input{    
      
    if([input isMemberOfClass:[Lion class]]){
        [input roar];
    }    
    if([input isMemberOfClass:[Dog class]]){
        [input bark];
    }      
}


Hope, you got an idea on the use cases of both isKindOfClass and isMemberOfClass and the difference between those two.



                         


Feel free to comment in case of any queries/concerns.