Tuesday, 25 February 2014

iOS Tutorial on Enumeration 

So as we are talking about enumeration in iOS,the first thing comes into mind are Collections such as Arrays , Sets and Dictionaries.Why?? Because we need to enumerate i.e go one by one over the objects contained in the collection objects.For example we have a following array

NSArray *exampleArray = @[@"A",@"B",@"C",@"D"];

For accessing the elements of the array you can follow the standard method of C using For Loops i.e

for (<#initialization#>; <#condition#>; <#increment#>) {
        <#statements#>
    }

But its best practice to follow the following techniques described.

In Cocoa there are there basic techniques of enumeration

1)Fast Enumeration
2)Block Based Enumeration
3)Using an Enumerator.

Fast Enumeration

Fast enumeration is the most preferred way of enumerating the collections.

Why??
  • More efficient.
  • Easy syntax.
  • Doesn't allow to mutate(change) the collection you are trying to enumerate.
  • Perform multiple enumerations concurrently.

How to use it?

Syntax - 

for (<#type *object#> in <#collection#>) {
        <#statements#>
    }

Examples :-

NSArray *exampleArray = @[@"A",@"B",@"C",@"D"];
NSDictionary *exampleDictionary = @{@"Key1"@"A",@"Key2":@"B",@"Key3":@"C"};
    
    for (NSString *element in exampleArray) {
        NSLog(@"Element %@ \n",element);
    }

    for (NSString *key in exampleDictionary) {
        NSLog(@"Element %@ with Key %@",[exampleDictionary objectForKey:key],key);

    }

Output :
Element A 
Element B 
Element C 
Element D 
Element B with Key Key2
Element A with Key Key1
Element C with Key Key3

Arrays and sets enumerate their contents, and dictionaries enumerate their keys. NSIndexSet and NSIndexPath do not support fast enumeration.In case of Array the enumeration of objects occurs in the order in which they are inserted.

Block Based Enumeration

The collection objects allow to enumerate their objects using blocks(If you don't know them then you can read about them I would be posting a tutorial for them soon).So how to do it.Stay with me and you will get everything its easy.

How to use it?

Syntax For Dictionary:-

[exampleDictionary enumerateKeysAndObjectsUsingBlock:<#^(id key, id obj, BOOL *stop)block#>];

Example :-

[exampleDictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key,NSString *element,BOOL *stop){
     NSLog(@"Element %@ with Key %@",[exampleDictionary objectForKey:key],key);
        if ([key isEqualToString:@"Key2"]) {
            *stop = YES;
        }
    
    }];


Syntax For Array:-

[exampleArray enumerateObjectsUsingBlock:<#^(id obj, NSUInteger idx, BOOL *stop)block#>];

Example :-

[exampleArray enumerateObjectsUsingBlock:^(NSString *element,NSUInteger index,BOOL *stop){
        
        NSLog(@"Element %@ Index %d ",element,index);
        if (index == 2) {
            *stop = YES;
        }
    }];


The example is quite self explanatory but then also if you didn't got it I would explain one example. 

exampleDictionary is the dictionary we created earlier in the tutorial.

enumerateKeysAndObjectsUsingBlock is the instance method called upon the exampleDictionary and which takes a block with parameters  (id key, id obj, BOOL *stop).

(id key, id obj, BOOL *stop) 

id is used to represent the generic type  and BOOL *stop parameter is used to check whether to stop enumerating or not i.e when the *stop is equal to YES the enumeration of collection will be stopped.




The block-based enumeration methods for the other collections are slightly different in name and in block signature. See the respective class references for the method definitions.

WHY would i need to stop the enumeration ??
 To increase the performance.You should stop enumerating the collection as soon as you find your object or complete your task.

if you have any doubts comment them i would be happy to clear your doubts.Stay tunned :)

Sunday, 16 February 2014

iOS BLOCK BASED API's - UNIT TESTING

UNIT TESTING?

First of all just for the definition sake we can define unit testing as a method used to check the validity and consistency of individual units of your source code


WHAT DO YOU MEAN BY UNITS?

Units can be defined as sets of modules of your computer program.Intuitively a unit can be defined as the smallest part of the application which can be tested.But it is not necessary it would be the smallest part of the application.In procedural programming it can be entire module,but commonly we test individual functions whereas in object oriented programming units are often an entire interface,but could be individual methods.


WHY SHOULD I USE IT?

Unit Tests are very useful for those large projects where you might loose sight of everything that’s going on and while you are adding new code to add feature Y you might be silently breaking feature X without even suspecting.



SO WHAT ARE WE GOING TO LEARN TODAY?

Are we going to learn the complete unit testing?? No, i am going to discuss only about  unit testing block based API's. If you are not familiar with the blocks i would recommend you to go through the Blocks Programming Topics of Apple.If you have worked with the blocks one of the problems you might have faced is unit testing them.

HOW DO WE UNIT TEST THOSE BLOCKS ?

If you are already using Xcode 5.The unit tests are already part of your project.For example If you keep the name of your project as Dedicate you would be saying something like following in your project.











So lets start with what we are trying to learn.Write a test case .Don't just copy paste the code.My assumption is you would be having a block based code similar to the following.












So run the test case and you would never get into the block where we print the log "I am inside the block".What the hell why i am not getting inside that code?. The reason is that the test case doesn't wait for the completion of your block.As a consequence you would be not able to test the block code in any condition.

So Whats the solution?

Have  you heard the term semaphore?If you have then you might begin to think in the direction i am taking you too.But Hey wait I just googled the definition of Semaphore,and the wiki says :

In computer science, particularly in operating systems, semaphore is a variable or abstract data type that is used for controlling access, by multiple processes, to a common resource in a parallel programming or a multi user environment.

We are not  talking about the multiple processes here,but just focus on the highlighted definition . Oh yeah baby, now it  is making some sense.But there is still a question how to implement it.
Implement a new class name Semaphore or whatever you like to keep it.
Add the following lines in Semaphore.h file or xyz.h file whatever you have the kept the name of the class.Add the following lines.














Open the implementation file that is .m file and write the following code.

@implementation Semaphor

@synthesize flags;

+(Semaphor *)sharedInstance
{   
    static Semaphor *sharedInstance = nil;
    static dispatch_once_t once;
    
    dispatch_once(&once, ^{
        sharedInstance = [Semaphor alloc];
        sharedInstance = [sharedInstance init];
    });
    
    return sharedInstance;
}

-(id)init
{
    self = [super init];
    if (self != nil) {
        self.flags = [NSMutableDictionary dictionaryWithCapacity:10];
    }
    return self;
}

-(void)dealloc
{
    self.flags = nil;
}

-(BOOL)isLifted:(NSString*)key
{
    return [self.flags objectForKey:key]!=nil;
}

-(void)lift:(NSString*)key
{
    [self.flags setObject:@"YES" forKey: key];
}

-(void)waitForKey:(NSString*)key
{
    BOOL keepRunning = YES;
    while (keepRunning && [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]) {
        keepRunning = ![[Semaphor sharedInstance] isLifted: key];
    }

}

@end


 Just add the following lines in your block code.







Run the test case and Voila you would be able to go inside your block code.Stay connected for more interesting posts of iOS.:)