Tuesday, April 19, 2011

NSDateComponents and a better way to handle dates

Handling dates in objective-c can be quite difficult if you don't use the right tools.
And the best tools are for sure the NSDateComponents class. This class is available to both Mac and iOS development, and it makes handling dates much more simple.
Suppose that you need to get the month number of a date. If you don't know NSDateComponents, a way to do that is create a NSDateFormatter and set the format only for the month and get a string that you could convert to a number. Simple  like that. Actually this is far from simple, and far from optimal and far from good programming practices.
Using NSDateComponents things get much easier.
Just create a NSCalendar, like in this statement
NSCalendar* calendar = [NSCalendar currentCalendar];
and set which components you want to retrieve, these are the options:
  • NSEraCalendarUnit,
  • NSYearCalendarUnit,
  • NSMonthCalendarUnit,
  • NSDayCalendarUnit,
  • NSHourCalendarUnit,
  • NSMinuteCalendarUnit,
  • NSSecondCalendarUnit,
  • NSWeekCalendarUnit,
  • NSWeekdayCalendarUnit,
  • NSWeekdayOrdinalCalendarUnit,
You can specify which components you want using a statement like this one
NSUInteger flags = NSMonthCalendarUnit | NSDayCalendarUnit;
And later you just need to call
NSDateComponents* components = [calendar components:flags fromDate:someDate];
and you will have (in this case) the day and the month of the someDate variable.
To get these values just call the day and month methods from the components object, and you will get an NSInteger.
Also if you want to add some time to a date, like an hour, or a day, or 65 days,4 hours and 3 minutes, if you dont use NSDateComponents, you would end up using something like this:
[someDate addTimeInterval:60*60] //add an hour to someDate
To and an hour this is the simplest way, but and if you need to add 65 days,4 hours and 3 minutes? things would get a lot harder, wouldn't it?
Using NSDateComponents this is done like a breeze :)
You will need the calendar again, and then you instantiate a NSDateComponents, like this:
NSDateComponents *components = [[NSDateComponents alloc] init];
and you set the time you want to add, like in our example:
[components setDay:65];
[components setHour:4];
[components setMinutes:3];
and you call:
NSDate *futureDate = [calendar dateByAddingComponents:components toDate:[NSDate date] options:0];
You can also find the distance between two dates using the NSDateComponents. It is as simple as the other functions:
You set the components you want to track, like this code:
NSUInteger flags = NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents *components = [calendar components:flags fromDate:startDate toDate:endDate options:0];
NSInteger months = [components month];
NSInteger days = [components day];
You see, the NSDateComponents can make you life dealing with dates a lot simpler :)

Tuesday, November 2, 2010

Prototype for November, 02


After a couple of weeks it's there on youtube the second version of the comic creator app.

This app will create all the comics that the Comic Reader app (for iPhone and iPad) will use.

To give a look at the reader app, just watch my old videos, as i didn't update the reader for this release, it isn't in the video.

Wednesday, September 1, 2010

iOS - Adding a stretchable UIImage as background


Often i need to use some image as a background for many visual components, like views, scrollviews, buttons, other images… and most of time i ended using a large enough image to cover the front image.
So, if my view was 1000x700 i needed to load an 1000x700 image for the background. But this image will eat a lot of memory just to be there as a background. There should be a better way to do this. And there is a better way to do this.
All you have to do is create your UIImage like this
UIImage* backgroundImage = [[UIImage imageNamed:@”stretchableImage.png”] stretchableImageWithLeftCapWidth:44 topCapHeight:45];
this stretchableImageWithLeftCapWidth specify how many pixel in the left must be kept. The same goes to the topCapHeight, and in this case it specifies the number of pixels in the top.
So in the example, the sdk will keep the first 44 pixels, copy the 45th along all the way of the image, and in the end keep again the last 44 pixels. It will do the same for the height.
So you wont need to keep a large image in memory. And you can also use this technique to create dynamic buttons, views and anything that you may even not know how length it is.

Here you can find an image as example (but keep in mind that as a designer, i’m a good programmer ^_^” )



Visit my tumblr for more iphone tips and tricks

Wednesday, August 25, 2010

iOS - Accessing web services easily, now with blocks!!


The iPhone SDK 4 brought to us some very neat features. One of the most awesome and powerful are blocks.  
Blocks are like small procedures, that you can use as parameters to methods.
These structures exists already in many scripting languages, as ruby and python, and now we can also use its powers in ours iphone applications.
When we need to communicate with web services, we know how painful this task may be. Asynchronous operations, delegates, parsing json and xml responses. There are a lot of libraries that handle these tasks. I’ve commented already about a JSON parsing library here. But this library just parses JSON. It does not handle accessing the webservice, or error responses.
For that, i’ve found a great project hosted on github, called Seriously, that handles all of the tasks, and it uses blocks to simplify our code.

Continue reading on my tumblr

iOS - Parsing JSON


Very often we need to access some kind of service available on the internet to gather some data to work with. Most of nowadays services prefer to send data using the JSON format (learn more about json here). It’s simple and compared to XML, smaller.
In iOS there is no native way to work with json text, but there are some great library avaliable out there that make the job really easy. One of the best I know is the TouchJSON (a wiki about it is avaliable here). This library makes really simple the task to parse a JSON string.

Tuesday, August 24, 2010

How to load your data correctly in the background - iOS


Almost all view controllers need to load some data from the internet and interact with them.
This kind of task may sound simple at first, but as you will find out, there are some kind of complications, like autoreleasing objects with no autorelease pool in place, how to get notified when your data has been loaded and how to handle this data. Also all the updates to the view should be done in the main thread, not the background thread, to avoid possibly app crash.
To solve all these problems I’ve created a subclass of UiViewController that controls all the steps required to load the data the right way, and updates the view the right way.
Continue reading about this in my tumblr blog here

Sunday, January 31, 2010

How to make a POST request with iPhone sdk

To make a web request with the iPhone is very simple. The following code is an example of how you can do it. If you need to pass some variables to the server, just use the lines that are in bold.

NSURL *url = [NSURL URLWithString:@"http://www.google.com.br"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
NSData *requestBody = [@"username:x&password:y" dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:requestBody];
NSURLResponse *response = NULL;
NSError *requestError = NULL;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&requestError];
NSString *responseString = [[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding] autorelease];

 Ready. The variable responseString will have all the text that the server has returned.