iPhone Development

Just another iPhone Blog

Capturing Exceptions while debugging

This one is a simple but could be time-saving ūüôā

Scenario: If you are debugging and caught with awkward situation where the application crashes with an exception, like NSInvalidArgumentException and so on, but never take you to the place in the code where the problem exists.

 

Solution:

Remember, This solution is for Xcode 4.2.1 for Lion.

1.  Select View->Navigators->Show Breakpoint Navigator

Screen Shot 2012 02 22 at 4 42 58 PM

2. At the Bottom-left cornet, Click the ‘+’ symbol and Select ‘Add Exception Breakpoint’ Menu

Screen Shot 2012 02 22 at 4 43 20 PM

3. In the popped-up window you may select [All | Objective-C | C++ ] options to select what type of Exception should the execution stop.

Screen Shot 2012 02 22 at 4 44 15 PM

 

4. Click Done.

Restart your debug process and you should see the line of code that is causing the hassle for you ūüôā

 

Courtesy: Apple Developer Document.

 

 

Advertisements

An Idea for replacement of TweetLonger!

Hey Folks,

Just got this crazy idea which I would like to share.

I was just annoyed for the way we have to read the tweets with 140+ characters. With most of the twitter clients ( almost all ) it takes the user to a website to read the whole tweet which in the process is truncating the user experience of reading the tweets within the client and disconnecting the user from the twitter client.

With due respect for 140 characters limit twitter has placed, we could use below trick to solve this issue. This trick uses the in-reply-to feature of the twitter and the ability of most twitter clients to align the chain of tweets (tweets which have been originated as a reply of other tweet) in a linear fashion which helps read the broken tweets without any fuss.

 

Screen shot 2011-11-09 at 8.51.57 PM.png

Fig: A Snapshot of Linked tweets from Twitter for Mac Read the text in the image excluding the twitter handle (i.e. bharath2020) at the start of each tweet.

 

Screen shot 2011-11-09 at 9.10.31 PM.png

Fig: One more way of displaying linked tweets by Twitter Application for Mac

 

This trick could be deployed in all twitter clients with the user typing the whole tweet and twitter client will takes care of breaking the tweets and creating a link between them,

Let me know what do you think of this.

[self class] and static methods in Objective-C

Its been 5+ years of Objective-C programming and If I turn back and see, I have still a lot to learn.

I recently was working on a project, where a small design mistake look costlier. To overcome that, I had to override a set of static methods.

Let me give some insight into what happened before this.

 

I have seen many people use [self class] method in a static method, and I had always thought (my fault, i did not test it ūüė¶ ) that this would be always equal to the class name where the method is defined. But, I was wrong

 

So I had the following static method to create the Message model object

 

+(BBMessage*)newMessage

{

return [[[BBMessage alloc] init] autorelease];

}

+(BBMessage*)messageFromDictionary:(NSDictionary*)messageInfoDict

{

BBMessage *newMessage = [BBMessage newMessage];

….

}

 

This method was widely used to create the BBMessage object throughout the application. As it turned out be at the near end of the project, I had to add a subclass of BBMessage named BBHistoryMessage. However, the difference between BBHistoryMessage and BBMessage was a couple of  attributes in BBHistoryMessage, but their creation using method messageFromDictionary: remained same.

However, since it had [BBMessage newMessage] statement, the object created by messageFromDictionary: always created BBMessage instance rather than BBHistoryMessage’s instance

This is when I realized that replacing the appearances of BBMessage class name with [self class] as the [self class] would return the name of the class which invoked the method

 

For eg: if the BBHistoryMessage class  is used to invoke messageFromDictionary: then [self class] will be BBHistoryMessage class and hence newMessage would be creating BBHistoryMessage Class.

 

 

Pattern Drawing with CGPattern in iOS or Mac

If you are looking for help on how to stroke or fill up a pattern in iOS or Mac OS X, then You have landed at the right place.

NOTE: A reader of this post is assumed to have prior knowledge of custom drawing in iOS’s UIView, CGContext, and Quartz 2D basics

You can find the Code sample from Github

The Sample code demonstrates the following things:

  • Creation of 3 Different kinds of patterns using CGPattern
  • In the Sample, tap “Change Pattern” to switch to next pattern
  • Use the slider, to increase the size of pattern cell

A pattern is an image, usually small, used for filling regions by tiling, that is, by placing copies of the pattern side by side like ceramic tiles. Here we see how we can achieve pattern filling in iOS or Mac using CGPattern.

A step by step explanation on usage of CGPatterns

Quartz draw the patterns using cell based drawing technique, where it would provide us the option to draw a single pattern cell in a context, and uses the context to tile across the remaining area evenly.

STEP 1 : Create a CGPattern instance as below

//Pattern Callback methods

// drawPatternCell – callback to draw a single cell

//PatternReleaseInfoCallback – invoked when a pattern is released

CGPatternCallbacks callBack;

callBack.drawPattern = &drawPatternCell;

callBack.releaseInfo = &PatternReleaseInfoCallback;

callBack.version = 0;

 

// param1 – &patters_types[patternCount] –¬†a context info, here which defines which pattern to be drawn


// param2 – rect of a single pattern cell

 

// param3 – transformation matrix

 

// offsetX – a offset or horizontal gap between each cell.. minimum should be width of the cell

 

// offsetY – a offset of vertical gap between each cell. minimum should be heigh of the cell

 

// Style of – how the pattern cell are to be placed where are drawn on a region bigger than the single pattern cell

 

// shouldColor Р  a pattern can also be used as a mask, where the color is applied during the actual context where the pattern is drawn. So, literally you have to say true, if the pattern cell can chose its color, or no if the color at its main context is to be chosen

 

// callback – 2 callbacks encapsulated in a struct CGPatterCallbacks

 

_patterns[patternCount] = CGPatternCreate(&patters_types[patternCount], CGRectMake(0.0, 0.0, PATTERN_CELL_WIDTH, PATTERN_CELL_HEIGHT), CGAffineTransformIdentity, PATTERN_CELL_WIDTH, PATTERN_CELL_HEIGHT, kCGPatternTilingConstantSpacing, true, &callBack);

 

 

STEP 2: ¬†(Important) define the drawPattern callback as below. This is the place where you are allowed to draw a single cell of a pattern. The drawing technique of pattern cell is same as one would draw in View’s drawRect method or drawing with any CGBitmapContext.

 

Pattern 1 – Chequered flag –

Chequered Flag Pattern

//Chequered Flag

//Fill the entire background with white color

CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);

CGContextFillRect(context, CGRectMake(0.0, 0.0, cellWidth, cellHeight));

 

CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);

//Fill the top left quarter of the cell with black

CGContextFillRect(context, CGRectMake(0.0, 0.0, cellWidth/2.0, cellHeight/2.0));

 

//Fill the bottom right quarter of the cell with black

CGContextFillRect(context, CGRectMake(cellWidth/2.0, cellHeight/2.0, cellWidth/2.0, cellHeight/2.0));

 

Pattern 2

pattern_2

//http://www.kitchenbeforeandafter.com/wp-content/uploads/2009/05/kitchen-backsplash-tile-patterns2-300×216.gif

//\       /

// \     /

//  \ _ /

//   |_|

//  /   \

// /     \

///       \

 

 

//stroke middle square

CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);

CGContextFillRect(context, CGRectMake(0.0, 0.0, cellWidth, cellHeight));

 

 

//stroke diagonal

CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);

CGPoint points [] = {{0.0,0.0}, {cellWidth,cellHeight }, {cellWidth,0.0}, {0.0,cellHeight}};

CGContextStrokeLineSegments(context, points, 4);

 

CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);

int num_of_parts = 8;

float partWitdth = cellWidth / num_of_parts;

CGRect middleSpot = CGRectMake(partWitdth * 3, partWitdth*3, 2* partWitdth, 2*partWitdth);

 

CGContextFillRect(context, middleSpot);


Pattern 3

Circular_pattern

The Elements involve in this pattern are a circle drawn with various transformations

  • Circle
  • Semi-Circle
    • Circle shifted towards left by half the width of the cell
    • Circle shifted towards right by half the width of the cell
    • Circle shifted towards top by half the height of the cell
    • Circle shifted towards bottom by half the height of the cell
  • Arc
    • Circle shifted towards left & top by half the width and half the height of the cell respectively
    • Circle shifted towards left & bottom by half the width and half the height of the cell respectively
    • Circle shifted towards right & top by half the width and half the height of the cell respectively
    • Circle shifted towards right & bottom by half the width and half the height of the cell respectively

You can clone a copy of this Sample project from GitHub

STEP 3: Applying the Pattern.

Finally we would be applying the pattern in drawRect method of BBQuartzView in this sample.

// Drawing code

float alpha = 1;

 

//choose the pattern to be filled based on the currentPattern selected

CGContextRef context = UIGraphicsGetCurrentContext();

CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern (NULL);// 6

CGContextSetFillColorSpace (context, patternSpace);// 7

CGColorSpaceRelease (patternSpace);

 

//set the pattern as the Current Context’s fill pattern

 

//we dont need to set any color, as the pattern cell itself has chosen its own color

CGContextSetFillPattern(context, _patterns[_currentPattern],   &alpha);


//We would be filling the entire portion of this view

CGContextFillRect(context, [self bounds]);

  • Choose the pattern that needs to be applied. In this sample, the pattern is chosen based on the _currentPattern variable¬†value (0- Chequered pattern, 1- Pattern2, 3- Pattern3)
  • Patterns are created at the time of initializing the view. In sample, it is in initWithCoder method of BBQuartzView
  • The drawPattern callback is invoked only when the pattern is all set to be drawn. In my case, it is invoked when CGContextFillRect in the above drawing code snippet. You can use this pattern to fill any shape. The selected pattern would also be reflected while using CGContext drawing API like, CGContextFill variants, CGContextFillPath variants
  • The drawPattern Callback is called only once in its lifetime and for subsequent drawing, the pattern cell buffer would be re-used. So resize the single pattern cell, the patterns are re-created

Here is are the pics how the patterns would look like(captured from sample code).

patterns.png

 

You can clone a copy of this Sample project from GitHub

Hope, you find this piece of info useful. Fill in your comments or queries in below comment’s section. Waiting for you comments.

Happy Coding ūüôā

AGE Meter LIVE as iChat Status via Apple Script

Necessity is the Mother of Invention” – I just experienced the truth of it. Wait, I haven’t invented anything here. Since, I had the appetite do something new and noticeable on my Birthday, I came with AGE Meter, which displays your AGE as iChat status message, and its LIVE, updated every second

 

iChatStatus

 

I had written an Apple Script to set the Chat Message, and since many people follow my iChat status message, I thought let me update my AGE every second, which is something new in a status message, Right?. It received awesome response and I would like to share this script and let you experience the awesomeness of it.

 

 

NOTE: This script requires Mac OS X 10.4 and above, AppleScript Editor, iChat Messager for Mac OS X , PHP Installed

 

The Script is divided in to two parts

 

1. Apple Script – to update the iChat Message status

 

2. PHP script – to calculate the difference between current date and your Birthdate. This script is invoked by AppleScript and its result (the Age in Years, Months, Days, Hours, Minutes, Seconds ) is piped to AppleScript for final display

 

You can find the script here.

 

Installation

 

1. Unzip the BirthdayCounter.zip, which you have downloaded. Once unzipped, you ¬†should find a “BirthdayCounter” Folder. This folder has two files “BirthdayCounter_AppleScript” and “DateDifference.php”

 

2. Update your Birthdate here in this line in DateDifference.php file, located at the end of the script. Please note that the time should be in GMT.

 

echo dateDiff(“1976-06-23 02:00:00”, “now”) . “\n”;

 

3. Open “BirthdayCounter_AppleScript” in Apple Script Editor and Tap Run. There you go, the AGE meter has started.

 

 

Let me know if it¬†looks¬†awesomely for you ūüôā

 

 


 

10000 HITS!!

Hey Folks,

This blog just got its 10,000 hit and thank you each one you who have shown good support towards this blog. I think this is just the beginning. Just to give some stat on this short journey, the most liked posts in this blog are

Efficient Memory Handling in UIViewController-Part 1

iOS Open Folder Animation

And Apologize for not updating this blog for past 5 months, I have bee caught up in too many things viz ICC Cricket World Cup 2011(hey India Won it ūüôā ), IPL (RCB made it to Finals) and shifting focus to Android OS.

And lately, burnt my fingers by updating iOS 5 Beta onto my iPad ( unofficially the iPAd 1), and after experiencing its flaws (I don’t like it being tagged as BETA) tried to restore it to 4.3.3 successfully( in an ugly way ) but none of the third party apps are working anymore.

If you are planning to upgrade to iOS 5 BETA, then I would say spend your valuable time onto something else, and if you are still want to do, Make sure you BACKUP YOUR DEVICE before attempting it.

Will get back to you sooner.

All the Best!!

Happy Coding ūüôā

Things I Learnt Today

Mac Ports:

An awesome initiation by the Open-source community to provide a single application, called as Ports, which keeps track of most of the open-source projects thus reducing

  • the hassle of manual compilation of your favorite open source project
  • manual tracking of the latest version of your favorite open source project

All you have to say is the open source project name / software title , a.k.a port, you are interested, and Port utility will take care of

  • Finding the Latest stable version for the latest OS Version
  • Downloading the appropriate source
  • compiling and creating an executable

With Mac Ports available it is very easy to compile your JPEG library, or for that matter installing python, which is as easy as saying

sudo ports – v python +universal

This is the tool which help the Novice developers / or the ones who are very much interested in getting their Favorite open source project up and running rather than indulging in dirt of compilation

For more information on Mac Ports Visit the community site here

 

Python Imaging Library(PIL)

Did a Hands On on setting up Python Imaging Library and there came the use of ports where I had to Install JPEG, XML, FreeType libraries. This is wonderful library which supports a various Image Processing Options, with Image Comparison is the one which I was interested upon.

Installation of PIL is explained step by step here, I was installing this on Snow Leopard and was with this issue

“_imaging.so module not installed”

OR

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dlopen(/Library/Python/2.6/site-packages/PIL/_imaging.so, 2): \
Symbol not found: _jpeg_resync_to_restart
  Referenced from: /Library/Python/2.6/site-packages/PIL/_imaging.so
  Expected in: flat namespace
 in /Library/Python/2.6/site-packages/PIL/_imaging.so

If Ypur not so lucky enough to get the PIL installed due to this Error, then you have come to the right place. This issue is because the Python in Snow Leapard is looking for 64 bit JPEG library by default.

I have followed the steps nailed here and it worked for me

Hope this helps.

iOS Open Folder Animation

As I was fiddling with my iPad,  Open Folder Animation in iOS caught my attention. After giving it a serious though on how to achieve it, It looked Trivial.

iOS Folder View

 

Let us get together to write a piece of code which does this cool animation.

 

1. Plan

iOS_Folder_View_Plan.png

We can achieve this using 3 Main Layers

1. Layer -1 (Main View) : The Lowest layer contains the main screen which stores the main content

2. Layer -2  (Folder View): The Folder View, which hosts the Folder Icons. Once the Folder Opens, This is the only view which is active accepting the Touch Event. This layer resides above Layer-1

3. Layer-2.1 (Arrow ) : The Arrow, which points to the selected folder. This is movable on x-Axis.

4. Layer-3 (Layer to host Bottom part of Main Content View) : This layer hosts the bottom part of the Main Content View (Layer -1) i.e from point where Folder View ( Layer-2) occupies to the end of the Main Content View. This Layer is place above the Folder View (Layer-2 ) in terms of Level. In Terms of position on screen, this layer is placed just below the Folder View(Layer-2)

 

2. Execution

We can achieve Open Folder Animation effect in 3 Simple Steps

STEP 1: Capture the Main View Content into an image

  • Capturing Main View Content Image can be achieve using renderInContext: API. as shown in code snippet below
  • Clip the Main View into two parts, One part is the visible portion above the Folder view and rest of the image would be hosted in Layer -3. The Trick used in sample code below to avoid the cutting of the image into two parts, is by setting the Layer-3 bounds, such that it should hide the top portion (Part-1) of the Main Content view.

-(void)captureImageFromPointAndSetupMaskView:(CGPoint)selectedFolderPoint

{

UIGraphicsBeginImageContext(mMainBackgroundView.frame.size);

//capture the main content view

[mMainBackgroundView.layer renderInContext:UIGraphicsGetCurrentContext()];

UIImage *backgroundImage = UIGraphicsGetImageFromCurrentImageContext();

[mBottomPartOfMainBackgroundView setImage:backgroundImage];

//set the bounds such that the we hide the part of the main content image, which is visible just above the Folder View.

//This gets the continuation effect on the image once the folder view appears on screen

[mBottomPartOfMainBackgroundView.superview setBounds:CGRectMake(0.0, selectedFolderPoint.y + mSelectedArrowTipView.frame.size.height, mMainBackgroundView.frame.size.width, mMainBackgroundView.frame.size.height)];


}

 

STEP 2: Layout the Folder View(Layer 2 & 2.1) and Bottom Part Of Main Content View (Layer -3)

  • Folder View and Arrow View are grouped in Single View.
  • Place The Arrow View such that it is right below and to the Center of the Tapped Folder Icon Tapped
  • Place the Folder View Just below Arrow View

-(void)layoutBottomPartOfMainViewRelativeToPointInMainView:(CGPoint)selectedFolderPoint

{

//Place the Folder View Just below Arrow View

CGRect folderViewFrame = [mFolderView frame];

folderViewFrame.origin.y = floorf(selectedFolderPoint.y);

[mFolderView setFrame:folderViewFrame];

//making sure the View which displays bottom part of Main Backgorund View is just below  the Folder View

CGRect maskFrame = mBottomPartOfMainBackgroundView.superview.frame;

maskFrame.origin.y = folderViewFrame.origin.y + mSelectedArrowTipView.frame.size.height;

mBottomPartOfMainBackgroundView.superview.frame = maskFrame;

//Place The Arrow View such that it is right below and to the Center of the Tapped Folder Icon Tapped

[UIView setAnimationsEnabled:NO];

mSelectedArrowTipView.center = CGPointMake(selectedFolderPoint.x, 0.0);

CGRect arrowFrame = mSelectedArrowTipView.frame;

arrowFrame.origin.y = 0.0;

mSelectedArrowTipView.frame = arrowFrame;

 

[UIView setAnimationsEnabled:YES];

}


 

STEP 3- Push The Layer-3 which hosts the other part of the Main Content View

-(void)layoutFinalFrameOfBottomPartOfMainContentView

{

//Push The Layer-3 which hosts the other part of the Main Content View

CGRect maskFrame = mBottomPartOfMainBackgroundView.superview.frame;

maskFrame.origin.y = mFolderView.frame.origin.y + mFolderView.frame.size.height;

mBottomPartOfMainBackgroundView.superview.frame = maskFrame;

}

 

Thats it !! The above 3 steps would be called upon tapping a Folder  Icon as show in below code snippet

-(IBAction)openFolder:(id)sender

{

//get the center point of the tapped folder

CGPoint selectedFolderPoint = CGPointMake([sender center].x, [sender frame].origin.y + [sender frame].size.height);

if( mFolderView.hidden )//if folder is not opened

{

//open folder animation

//STEP 1: Capture the Main View Content into an image

[self captureImageFromPointAndSetupMaskView:selectedFolderPoint];

//STEP 2: Layout the Folder View(Layer 2 & 2.1) and Bottom Part Of Main Content View (Layer -3)

[self layoutBottomPartOfMainViewRelativeToPointInMainView:selectedFolderPoint];

[UIView beginAnimations:@”FolderOpen” context:NULL];

[UIView setAnimationDuration:0.5];

[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

//captures the main background view’s image

mFolderView.hidden=NO;

mBottomPartOfMainBackgroundView.superview.hidden=NO;

//STEP 3- Push The Layer-3 which hosts the other part of the Main Content View

[self layoutFinalFrameOfBottomPartOfMainContentView];

[UIView commitAnimations];

}

else {

//close folder animation

[UIView beginAnimations:@”FolderClose” context:NULL];

[UIView setAnimationDuration:0.5];

[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

[UIView setAnimationDidStopSelector:@selector(animation:didFinish:context:)];

[UIView setAnimationDelegate:self];

//restore the layout and hide the folder view after animation

[self closeFolder:selectedFolderPoint];

[UIView commitAnimations];

}

}

 

3. Result

Download the Full Source Code Here : iOS Open Folder Animation.zip

A Video of the Sample Code can be found here: iOS Open Folder Animation Video

If you like this post, Please leave your feedback / comment and Share this (See below for sharing options) to spread to all others who might be interested ūüôā

Happy Coding ūüôā

How to compare objects of your custom classes?

[This post is intended only for audiences with Basic knowledge in Objective-C]

With Cocoa / UIKit framework has built-in support for comparing objects like NSDate, NSString, NSData, NSNumber and few others which would help us to identify whether two objects are EQUAL, GREATER THAN or LESSER THAN the other object. This in-turn is used in cases like sorting, searching.

 

We would like to see how the same can be achieved for the custom classes we write, where we can specify the Equality condition by our own.

By default, NSObject class allows us to determine equality between two objects whose class is derived from NSObject through

isEqual: method,

where Apple documentation defines it as

This method defines what it means for instances to be equal. For example, a container object might define two containers as equal if their corresponding objects all respond YES to an isEqual: request. See the NSArray, NSDictionary, NSString and NSData class specifications for examples of the use of this method.

If two objects are equal, they must have the same hash value. This last point is particularly important if you define isEqual: in a subclass and intend to put instances of that subclass into a collection. Make sure you also define hash in your subclass.

 

 

In short, At NSObject (root class) level, two objects are said be equal

  • if their hash value are same
  • two objects have same address.

Well this may not be the case when we write our custom class,  for example,  two NSString objects might have different  pointer addresses, but have same string value. Hence, one must override hash method and isEqual: method of NSObject. NSString class would have hash and isEqual defined as below

– (NSUInteger)hash

{

//return the hash value generated from the string.

}

-(BOOL)isEqual:(id)otherObject

{

// return strcmp ( [self’s cString] , [otherObject’s cString] )

}

 

Where do I apply this?

Well, if you encounter a situation where you have an array (or in general collection) of Employees for eg, and you would want to remove an employee of particular ID, then you can do it with a single call like this. This would save you from writing an search algorithm.

Employee *employeeToRemove;

[myEmployees removeObject: employeeToRemove]; // assuming myEmployees is of type NSMutableArray

As Apple document says, removeObject and its variants (see below list for variants) would pick the object to remove for which isEqual: would return TRUE

  • ‚ÄstremoveObject:
  • ‚ÄstremoveObjectIdenticalTo:
  • ‚ÄstremoveObjectIdenticalTo:inRange:
  • ‚ÄstremoveObjectsInArray:
  • ‚ÄstindexOfObject:
  • ‚ÄstindexOfObject:inRange:
  • ‚ÄstindexOfObjectIdenticalTo:
  • ‚ÄstindexOfObjectIdenticalTo:inRange:

 

Another method that does fall in this category, is compare: method (actually you can give a custom name to this method ) whose signature is

-(NSComparisonResult)compare:(id)otherObject

NSComparisonResult is an enum with values  as below

enum {

NSOrderedAscending = -1,

NSOrderedSame,

NSOrderedDescending

};

 

With this method implemented in your Custom class (for example, Employee class), you can sort your objects in a collection (NSMutableArray , NSArray) with a single statement

[ myEmployee sortArrayUsingSelector(compare:)];

Other variants where this strategy can be used are

‚ÄstsortedArrayUsingSelector:

‚ÄstsortUsingSelector:

 

Hope this tutorial find useful for you.

Happy Coding ūüôā

 

%d bloggers like this: