Pages

Thursday, July 28, 2011

[Code Snippet] Add UIButton programatically

I have not so much time to update the blog, but I have to maintance the wednesday's code snippet so today's code snippet is about one of those things that are very easy to do, but difficult to remember: add a UIButton programatically to our view.

To add a basic UIButton programatically, just instance it, give it a frame and obviously a selector for the TouchInside (click) event, and that's all.

Code snippet is like that

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[myButton addTarget:self
           action:@selector(myButton_click:)
 forControlEvents:UIControlEventTouchDown];
[myButton setTitle:@"My title" forState:UIControlStateNormal];
myButton.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[view addSubview:myButton];

- (IBAction) myButton_click:(id)sender
{
    NSLog(@"Button clicked");
}

Good programming!!!!

Wednesday, July 20, 2011

[Code Snippet] Scheduling local notifications

Sometimes we want to create an app that notifies the user some information when a selected date/time is reached, for that reason Apple included local notifications since iOS 4.1

The use of local notifications is much easier than PUSH notifications, that needs to implement a server-side web app for sending PUSH notifications through Apple Push Notification (APN) service.

To use local notifications, you only have to instantiate NSLocalNotification class, set it's fire date and time, its message, sound and any other fields that you could need and schedule it in local notification scheduler, and iOS do the rest for you.

Here is a sample code

UILocalNotification *localNotif = [[UILocalNotification alloc] init];

if (localNotif == nil)
     
return;

localNotif.fireDate = itemDate;
localNotif.timeZone = [NSTimeZone defaultTimeZone];

// Set the action button
localNotif.alertAction = @”View”
//This sets the alert text to the current text in the textfield.

localNotif.alertBody = @"Charle's birthday";

//This sets the sound name of the notification.
localNotif.soundName = UILocalNotificationDefaultSoundName;

//You can also set the badge number of the application.
localNotif.applicationIconBadgeNumber = 1;

// Schedule the notification
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];

[localNotif release];

I hope this could be useful for you, enjoy it!!

[e-book] Mobile Developer's Guide 8th edition (Free)

A few weeks ago, I've downloaded two free ebooks in PDF Format about mobile development, and last week I had time to have a look at these.

First one is Mobile Developer's Guide 8th edition, that you can download here. It's a very useful guide for these people who wants to start in mobile development, but they're a bit lost. This guide provides a little approach for each mobile platform (introductio, pre-requisites, development, testing, publication) and talks about cross-platform frameworks or mobile web apps too.

As well as being a highly recommended reading for begginers, if you are a senior mobile developer, maybe you only know one, two or three platforms, but no more. With this reading you could know advantages and disadvantages for every platforms and development strategies and you can take a decission, and what is more important: Justify it to your customer/boss/...

At last, this book has a hardcopy version which, if you purchase it, you will be helping Africa through AppsWorld Africa.

So if you have any free time, download or purchase it and read it.

P.S. Thanks to @davidcontrerasm for talking me about this book via Twitter.

Wednesday, July 13, 2011

[Code Snippet] Store a NSArray of custom objects into NSUserDefaults

We're  back from holidays, it has been two weeks without updates, so now it's time for doing it.

Sometimes we have to cache some kind of information, or store it easily because we don't need to make searches on them, just we want to recover ir quickly. In this case using SQLite for local storage is a big solution for a little problem, and store the information as a XML based file lead us to write a serializer and a custom XMLParser, so the best option to accomplish that is store it in NSUserDefaults.

Maybe you have already stored basic information like NSString or NSNumber objects in user defaults, so you know that it is an easy way to store a NSObject into a NSDictionary.

But maybe you want to store a little array of information, for example a little shop list with identification number, and description, so you have created a object like this.

@interface ShopItem : NSObject
{
        int numberID;
        NSString *description;
}

@property (nonatomic, assign) int numberID;
@property (nonatomic, retain) NSString *description;

@end

So, how could we store a NSArray containing some of this objects into NSUserDefaults? Store the NSArray object into NSUserDefaults as usually cause our app to crash, so we have to serialize and deserialize the NSArray of custom objects implementing NSCoding protocol in our custom NSObject to encode key-value pairs for each property of our custom object.

@interface ShopItem : NSObject <NSCoding>
{
        int numberID;
        NSString *description;
}

@property (nonatomic, assign) int numberID;
@property (nonatomic, retain) NSString *description;

@end
@implementation ShopItem

@synthesize number, description, shoppingDate;

- (void)encodeWithCoder:(NSCoder *)coder;
{
    [coder encodeObject:description forKey:@"description"];
    [coder encodeInteger:numberID forKey:@"numberID"];
}

- (id)initWithCoder:(NSCoder *)coder;
{
    self = [[ShopItem alloc] init];
    if (self != nil)
    {
        description = [coder decodeObjectForKey:@"description"];
        numberID = [coder decodeIntegerForKey:@"numberID"];
    }  
    return self;
}

@end

Once we have implemented NSCoding protocol in the custom object, we are able to store our NSArray in NSUserDefaults like that

[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:objectArray] forKey:@"savedArray"];

To retrieve our NSArray again, we should recover the NSArrayObject from NSUserDefaults, check that it's not nil (be careful, if you try to decode a nil array, you'll get an EXC_BAD_ACCESS exception) and unarchive it.

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"savedArray"];
if (dataRepresentingSavedArray != nil)
{
        NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
        if (oldSavedArray != nil)
                objectArray = [[NSMutableArray alloc] initWithArray:oldSavedArray];
        else
                objectArray = [[NSMutableArray alloc] init];
}

With this pieces of code, you could store and retrieve little sets of information in your NSUserDefaults local storage.

I hope this helps you.

Wednesday, June 22, 2011

[Code Snippet] Playing video streaming in our iPhone App

Hi there. Today's code snippet is another easy one, just for playing video streaming embedded in our app using Media Player Framework.

First thing to do is to import the headers that we need

#import <MediaPlayer/MediaPlayer.h>

After that we'll have to instantiate the MPMoviePlayerController and add it as a subview to our actual view. We could set the MPMoviePlayer controller frame, to get a full screen player or not.


MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:
                                            [NSURL URLWithString:@"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"]];
   
    [player.view setFrame: self.view.bounds];  // player's frame must match parent's
    [self.view addSubview: player.view];
   
    [player prepareToPlay];
    [player play];

Two things to take care:

First one: Take care about the supported stream formats for iOS, if the video streaming is not played maybe because the streaming is not transmitted in the correct formats. Review the stream formats and the best practices for iOS streaming here

Second one: Video player is another control yet, so you can add controls onto it like UILabels, UIButtons and make your streaming a bit interactive for the user. Just add the control with addView method and you can use it.

I hope this code snippet could be useful for you. Now I'm inmersed into interoperability between Microsoft Azure cloud computing framework and iPhone so it's possible that in a few weeks there are some articles about that.

Wednesday, June 15, 2011

[Code Snippet] Implementing UIActionSheets

This week code snippet is about how to implement UIActionSheet in our UIViewController to present actions like a context menu. Like my previous post, this is so easy but have it previously implemented could save us some valious time.

To show the UIActionSheet, instance UIActionSheet and show it with this piece of code.

UIActionSheet *popupQuery = [[UIActionSheet alloc] initWithTitle:@"Share" delegate:self cancelButtonTitle:@"Cancelar" destructiveButtonTitle:nil otherButtonTitles:@"Facebook", @"Twiter", @"E-mail", nil];
        popupQuery.actionSheetStyle = UIActionSheetStyleBlackOpaque;
   
    [popupQuery showInView:self.view];
    [popupQuery release];

Cancel button will hide our action sheet when is pushed, destructive button will appear in red background and any other button will appears as normal. Both, destructive and the other buttons behaviour has to be declared implementing UIActionSheetDelegate clickedButtonAtIndex.


-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
     if (buttonIndex == 0) {
       
         NSLog(@"Button Facebook clicked");

    } else if (buttonIndex == 1) {
       
        NSLog(@"Button Twitter clicked");;

    } else if (buttonIndex == 2) {

        NSLog(@"Button Email clicked");
       
    }
}

With this piece of code you can implement a context menu like behaviour in your view. Take note that you have not to implement cancel button index click behaviour.





I hope this code snippet helps you, enjoy it!!!

Wednesday, June 8, 2011

[Code Snippet] Sending emails from our app with MessageUI framework

Hello everybody, I've been very busy last days, too much work, so this week I'll bring you an easy code snippet that everybody should know but could be useful to have it here for cut & past simply.

When we want to use the iOS' email composer from our app, first thing to do is to link MessageUI framework with our binaries, and obviously import it in our header file.

#import <MessageUI/MessageUI.h>

For using it, you have to implement in your class the MFMailComposeViewControllerDelegate

@interface MyViewController : UIViewController <MFMailComposeViewControllerDelegate>

After that, to invoke the MFMailComposer is so easy, just instance it and preload all the email fields that you want: To, cc, bcc, subject... and present it as a modal view controller. Don't forget setting the mailComposeDelegate property to the class which implements MFMailComposeViewControllerDelegate, usually the same class that invokes MFMailComposeViewController.:

    MFMailComposeViewController *mailView = [[MFMailComposeViewController alloc] init];
    mailView.mailComposeDelegate = self;
    mailView.navigationBar.tintColor = [UIColor colorWithRed:0.36078431 green:.015686275 blue:.0078431373 alpha:1];
    [mailView setToRecipients:[NSArray arrayWithObject:@"fiveflamesmobile.blogspot.com"]];
   
    [self presentModalViewController:mailView animated:YES];
   
    [mailView release];

After those steps we have to implement de MFMailComposrDelegateProtocol as this:

#pragma mark -
#pragma mark MFMailComposeViewControllerDelegate

- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    [self dismissModalViewControllerAnimated:YES];
   
    UIAlertView *alert = nil;
   
    if (result == MFMailComposeResultSent)
    {
        alert = [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"EmailEnviado", "") message:NSLocalizedString(@"EmailExito", "") delegate:self cancelButtonTitle:NSLocalizedString(@"Aceptar", "") otherButtonTitles:nil] autorelease];
       
    } else if (result == MFMailComposeResultSaved) {
       
        alert = [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"EmailGuardado", "") message:NSLocalizedString(@"EmailBorradores", "") delegate:self cancelButtonTitle:NSLocalizedString(@"Aceptar", "") otherButtonTitles:nil] autorelease];
       
    } else if (result == MFMailComposeResultFailed) {
       
        alert = [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"EmailNoEnviado", "") message:NSLocalizedString(@"EmailFallo", "") delegate:self cancelButtonTitle:NSLocalizedString(@"Aceptar", "") otherButtonTitles:nil] autorelease];
    }
   
    [alert show];
}

Be careful, I've user localizated string to show the message in the alert view, but maybe I'll write about that in next code snippets. And with this few lines of code you will be able to send emails with the iOS mail client.

So that's all for today. More and better (I'll try it) the next week.