Tuesday 13 March 2012

Monitor Network Status and Network Type in iOS


Hi All,

In most of the iOS application which uses server and server api's wants to a check whether network is available at any moment when application runs.
we all know how to check the network status (Using Apple's Reachability code we can check the network status by pinging to a hosted server).
But some cases instead of checking for network is available we need to get/alert about network status change and the network type change.

So here I got up with an implementation of a custom class that will alert the network status change.


//To get the Network Status/ Change in Network Type with NSNetworkMonitor,
(Here prefix NS means not 'Next Step' it just 'Naveen Shan' my name, if you don't like change it.)

1. Initialize the Network Monitor on App Launch.

 //for monitoring network connectivity  
 [NSNetworkMonitor initializeNetworkMonitor];  

2. To Catch the Network Status implement the following Notification.

 //to catch network status.  
 [[NSNotificationCenter defaultCenter] addObserver:self  
                      selector:@selector(changeInNetworkConnection:)  
                        name:KNETWORKNOTIFIER  
                       object:nil];  

3. The Response Method is implemented as follows,

 -(void)changeInNetworkConnection:(NSNotification *)notification {  
   NSDictionary *status = [notification object];  
   if ([[status objectForKey:@"NetworkAvailable"] boolValue]) {  
     NSLog(@"The NetworkConnection StatusDidChanged : NO Connection");  
   }  
   else  {  
     if ([[status objectForKey:@"NetworkType"] isEqualToString:@"WiFi"]) {  
       NSLog(@"The NetworkConnection StatusDidChanged : wifi Connection");  
     }  
     else  {  
       NSLog(@"The NetworkConnection StatusDidChanged : wann Connection");  
     }  
   }  
 }  

Some Helper Methods

 +(BOOL)isNetWorkConnectionAvailable;  
 +(NetworkAvailable)currentNetwork;  

One Important Tip

- we get a network change notification on app launch when the network status is changed while app is in minimize stage.

Dependencies

- Need to add Apple's Reachability Classes.
- Need to add SystemConfiguration.framework.

I attached Complete code here

if you need more details feel free to contact me

thanks,
Naveen Shan

Monday 5 March 2012

Label to display NSAttributedString (Label through a Path)


Hi All,

I don't know how many of you are familiar with NSAttributedString, if we simply write a definition "Attributed String is a string that itself contains its properties to display (like color, thickness, font, style all that are need to display the string)".

So the Attributed String help the programmer to display a long string, as different paragraph (with line breaks, justification etc) with different fonts and color for different part of string.
To achieve this iOS provide a framework called "CoreText" which is made available from Xcode 3.2 onwards. But in iOS as of now we have only limited access for this framework resource because Mac framework had lot of method to read and write Attributed String from files(like doc, docx etc).

While discussing the limitation of Attributed String processing in iOS the important think we can find is there is no UI (User Interface) elements to display Attributed String. The CoreText framework provide a method to draw the string in a path, which is not as simple like a string displayed in UILabel's.

So I got up with an implementation of a custom class that will draw the given Attributed String with a specified path.

See the screen Shots,




//To Display the NSAttributedString with NSAttributedLabel,
(Here prefix NS means not 'Next Step' it just 'Naveen Shan' my name, if you don't like change it.)

1. Create a object of NSAttributedLabel set Frame and Attributed String and addSubview the label where you need to show (here is the simplicity now this class acts like UILabel to display String).

Things to be noted is,
* We need to set enough attribute to the string before we addSubview the label. It is because, as we all know the drawRect method of a view will call at the time of setting superview for that view, if we set the attributes later we need to call a setNeedsDisplay method for proper functioning.
* We need to set Background color for that view. It is because I override the drawRect method of the view so if we not set the default background color s black.

 -(void)showAttributedLabel {  
   NSString *string = @"Lorem ipsum \n dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";  
   //normal font attributes  
   CTFontRef normalFontRef = CTFontCreateWithName((CFStringRef)@"Helvetica", 18, NULL);  
   NSDictionary* normalFontAttribute = [[NSDictionary alloc] initWithObjectsAndKeys:(__bridge id)normalFontRef,(NSString*)kCTFontAttributeName, nil];  
   //bold font attributes  
   CTFontRef boldFontRef = CTFontCreateWithName((CFStringRef)@"Helvetica-Bold", 20, NULL);  
   NSDictionary* boldFontAttribute = [[NSDictionary alloc] initWithObjectsAndKeys:(__bridge id)boldFontRef,(NSString*)kCTFontAttributeName, nil];  
   NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string];  
   //setting attributes.  
   [attributedString addAttributes:normalFontAttribute range:NSMakeRange(0, [attributedString length])];  
   [attributedString addAttributes:boldFontAttribute range:NSMakeRange(0, 11)];  
   NSAttributedLabel *objAttributedLabel = [[NSAttributedLabel alloc] init];  
   [objAttributedLabel setFrame:CGRectMake(50, 50, (self.view.frame.size.width/2), 500)];  
   [objAttributedLabel setBackgroundColor:[UIColor clearColor]];  
   [objAttributedLabel setAttributedString:attributedString];  
   [self.view addSubview:objAttributedLabel];  
   [objAttributedLabel release];  
   objAttributedLabel = nil;  
   string = nil;  
   [boldFontAttribute release];  
   boldFontAttribute = nil;  
   [normalFontAttribute release];  
   normalFontAttribute = nil;  
 }  

Some More Interesting Abilities of NSAttributedLabel,
Here I provide a flexibility of displaying string in columns(in vertical span).

First I like to tell how the NSAttributedLabel can be used just as a Label to display Attributed String
Set the KCOLUMNCOUNT in NSAttributedLabel.h as 0 .

if you need more than one column you need to set the required column count in KCOLUMNCOUNT at NSAttributedLabel.h
and specify the rect for each column in '-(CGRect)rectForColumnAtIndex:(int)index' method at NSAttributedLabel.m

One Important Tip
The Attributed String is drawn from its end point and from end of the path to start of the path. so if the specified path rect is not enough to show the string then the top (start) of the string is missing to draw (not the end). Similarly if you try to put some extra space at the bottom of path to hold lengthy string, I think its not possible.
To Sole this problem I can only be able to provide a function that will return the length of string that the given frame can accumulate, here it is,

 - (int)endIndexOfAttributtedString:(NSMutableAttributedString *)attributtedString InFrame:(CGRect)rect {  
   int currentIndex = 0; //now I map it from string beginning.  
   if (attributtedString != nil)  {  
     CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attributtedString);  
     CGMutablePathRef path = CGPathCreateMutable();  
     CGPathAddRect(path, NULL, rect);  
     CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(currentIndex, 0), path, NULL);  
     CFRange frameRange = CTFrameGetVisibleStringRange(frame);  
     currentIndex += frameRange.length;  
     CFRelease(frame);  
     CFRelease(path);  
     CFRelease(framesetter);  
   }  
   return currentIndex;  
 }  

I attached Complete code here

if you need more details feel free to contact me

thanks,
Naveen Shan