Redwan's Blog

About Me

My photo
Dhaka, Bangladesh
I am B.S.C Engineer,CSE,SUST and Ex-Cadet of Mirzapur Cadet College.

Friday, June 8, 2012

iPhone Lecture: Day1

I followed stanford lecture guideline and more than 90% contents are collected from them.
Lecture1
View more PowerPoint from redwan1795

Tuesday, May 29, 2012

How to move up the UIView while writing in UITextField


Inside .h File of your ViewController



Declare UIText field delegate(
) in .h file




- (void)setViewMovedUp:(BOOL)movedUp;



Inside .m file of your ViewController

-(void)textFieldDidBeginEditing:(UITextField *)sender
{
NSLog(@"Inside textFieldDidBeginEditing");
    if ([sender isEqual:leftTextField] || [sender isEqual:rightTextField])
    {
NSLog(@"Inside textFieldDidBeginEditing (INSIDE IF)");
        //move the main view, so that the keyboard does not hide it.
        if  (self.view.frame.origin.y >= 0)
        {
NSLog(@"Inside textFieldDidBeginEditing (INSIDE y>0)");
            [self setViewMovedUp:YES];
        }
    }
}


- (void)keyboardWillShow:(NSNotification *)notif
{
    //keyboard will be shown now. depending for which textfield is active, move up or move down the view appropriately
    if (self.view.frame.origin.y >= 0)
    {
        [self setViewMovedUp:YES];
    }
    else if (self.view.frame.origin.y < 0)
    {
        [self setViewMovedUp:NO];
    }
}



//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMovedUp:(BOOL)movedUp
{
//NSLog(@"Inside setViewMovedUp");
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5]; // if you want to slide up the view
    CGRect rect = self.view.frame;
    if (movedUp)
    {
NSLog(@"Inside else movedUP YES");
        // 1. move the view's origin up so that the text field that will be hidden come above the keyboard 
        // 2. increase the size of the view so that the area behind the keyboard is covered up.
        rect.origin.y -= kOFFSET_FOR_KEYBOARD;
        rect.size.height += kOFFSET_FOR_KEYBOARD;
    }
    else
    {
NSLog(@"Inside else movedUP NO");
        // revert back to the normal state.
        rect.origin.y += kOFFSET_FOR_KEYBOARD;
        rect.size.height -= kOFFSET_FOR_KEYBOARD;
    }
    self.view.frame = rect;
    [UIView commitAnimations];
}

Monday, May 14, 2012

Deploy an application to your iphone

After doing a few small projects, I am in need to deploy the application to iphone as many features doesn't work in simulator
- Calling to a phone number
- Sending an SMS
- GPS / Location
- Accelerometer

So, we need to learn how to deploy a project to iphone so that we can be able to see what those features really looks like. I have found a good tutorial that shows how...
http://mobiforge.com/developing/story/deploying-iphone-apps-real-devices

We need to create certificates. We need two types of files
- .p12 files
- .mobileprovision files (adhoc and appstore distribution)

From the link blog, following step by step we shall be able to create them. After that we need to open Application->Utilities-> Keychain Access and double click on it. We have to make sure that the certificate files are showing on the list like the image below.



Now, we need to open Xcode->Window->Organizer and select "provisioning profiles" Tab include/import/drag and drop the .mobileprovision files. It should look the the screen shot below.



Now, need open the project in Xcode and double click on the "Project Name" on the left nav bar named "Groups & Files" and on the "Build" tab on "code signing" section-> "Code Signing Identity"-> "Any iOS Device"-> We should select the development profile like the screen shot below.


Now, we shall select Target->"Project Name"-> and double click on it. On "Build" tab, we have to make sure it looks like below.



And on "Properties" tab, we have to make sure that "your company name" is changed to the appropriate company name the one that you have registered with in Apple site.


Thats it. Now, select "Device" instead of simulator for build properties like the screen shot followed and attach you iphone device with designated cable and hit "build and run".  Your application should appear on iphone by this time.



Adios Amigos for now!  






Friday, May 4, 2012

Launching Native Apps: Phone Call, SMS, Email, Map and Browser

Every iphone application uses the native apps frequently. So, we shall deal with them sooner than later. I am implementing the openURL project from http://appsamuck.com/day3.html in my own way.

We shall deal with phone call, SMS, Email, Map and Browser.  I must say that we can not test phone call and SMS in simulator(Later we shall learn to port an app in iphone).

Let get on to it straight on.

Step1: We shall open up a project in Xcode named "openURL" as a "View-based Application"
Step2: Lets plan how we are going to do it.

We are going to need five buttons "UIButton" and five methods(??) that will implement the button action. As declaring a method with (IBAction) return type we can tell the compiler that it is associated with a button. At the same time, we can send the "sender" as an id so that we can determine from which button the method is been called. This id type object "sender" is sent as a perimeter of the method.  And interface builder shall not recognize it or let us associate a method with a button as long as its return type is NOT IBAction.

We are gonna use the interface builder to place the button. So, we shall let the compiler understand it by declaring the buttons as IBOutlet.

Without using the interface builder, we could declare a UIButton as followed[We are not gonna do it this way in this example project]

//Declared button type as Round Rect Button
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//Button position and size defined(x, y, height, width)
myButton.frame = CGRectMake(80, 50, 150, 40);
// We are telling compiler what method should be invoked when the button is Touched up inside.
[myButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
//The following buttonClicked method shall be called in this case

- (IBAction)buttonClicked:(id)sender
{
    NSLog(@"Hi!");

}

Step3: We are going to add five buttons using interface builder and associate a tag with each one. A tag is an integer value and it will help us to detect from what button the method is being called and do something accordingly. We will also add the titles of the buttons using interface builder.




Step4: We shall open up the Xcode and start writing code on openURLViewContorller files as followed.

openURLViewContorller.h 



@interface openURLViewController : UIViewController
{
IBOutlet UIButton *btnActivatePhoneCall;
IBOutlet UIButton *btnActivateSMS;
IBOutlet UIButton *btnActivateEmail;
IBOutlet UIButton *btnActivateMap;
IBOutlet UIButton *btnActivateBrowser;

}

- (IBAction) activateAction: (id) sender;
@end



openURLViewContorller.m



(IBAction) activateAction: (id) sender
{
if ([sender tag] == 0
{
NSLog(@"Phone Call Button");
}
else if([sender tag] == 1)
{
NSLog(@"SMS Button");
}
else if ([sender tag] == 2)
{
NSLog(@"Email Button");
}
else if([sender tag] == 3)
{
NSLog(@"Map Button");
}
else 
{
//sender== btnActivateBrowser
NSLog(@"Browser Button");
}

}

Remember, we associated tags with those buttons and we are reading them by using [sender tag]. 

We are using NSLog just to verify whether our plan is working or not.

N.B. We are not doing getter/setter or property declaration and synthesizing for the buttons. We must remember that only to those UI Elements must be performed property declaration and synthesizing, who are gonna change its property(i.e. title, font color, text) in run time or by another action(a button action or a method action or something).

Step5: We are going to open the Interface Builder again and associating the buttons with the method activateAction







Step6: SMS and Email needs to implement two delegates MFMessageComposeViewControllerDelegate, MFMailComposeViewControllerDelegate, we need to add a frame work named"MessageUI.framework" as well for Email as well. We need to implement following methods as well in .m file and need add headers (MessageUI/MessageUI.h  and MessageUI/MFMailComposeViewController.h ) as well.

6.1. Declaring Delegates
openURLViewController.h

@interface openURLViewController : UIViewController
{
IBOutlet UIButton *btnActivatePhoneCall;
IBOutlet UIButton *btnActivateSMS;
IBOutlet UIButton *btnActivateEmail;
IBOutlet UIButton *btnActivateMap;
IBOutlet UIButton *btnActivateBrowser;

}

- (IBAction) activateAction: (id) sender;
@end 

6.2. Implement Delegate Methods

openURLViewController.m


- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result 
{
    [self dismissModalViewControllerAnimated:YES];
}

-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error 
{
[self dismissModalViewControllerAnimated:YES];
}

6.3. Include Framework







6.4. Declare Header Files

openURLViewController.h



#import
#import

#import


@interface openURLViewController : UIViewController 
{
IBOutlet UIButton *btnActivatePhoneCall;
IBOutlet UIButton *btnActivateSMS;
IBOutlet UIButton *btnActivateEmail;
IBOutlet UIButton *btnActivateMap;
IBOutlet UIButton *btnActivateBrowser;

}

- (IBAction) activateAction: (id) sender;
@end

Step7: Now, to make a phone call to cell number 12125551212 we shall add the following code inside the if statement ([sender tag] == 0)  of activateAction method. 

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel:12125551212"]];


We shall be able to test in iphone, but NOT IN SIMULATOR!!!


Step8: Now, to send SMS we shall add the following code inside the if statement ([sender tag] == 1)  of activateAction method. 

if ([NSClassFromString(@"MFMessageComposeViewController") canSendText]) 
{
      [self presentMessageComposeViewController];

[NSClassFromString(@"MFMessageComposeViewController"canSendTextreturns true if the current device is capable of operating SMS feature and returns false if it doesn't. 

And we need to name the presentMessageComposeViewController method in .h file of the viewController and implement it in .m file.

-(void) presentMessageComposeViewController 
{
     id smsViewController = [[NSClassFromString(@"MFMessageComposeViewController") alloc] init];
     [smsViewController setTitle:NSLocalizedString(@"Your Title",nil)];
     [smsViewController setBody:NSLocalizedString(@"Your Message. urls work too www.example.com",nil)];
     [smsViewController setMessageComposeDelegate: (id)self];
     [self presentModalViewController:smsViewController animated:YES];
     [smsViewController release];
}

We shall be able to test in iphone, but NOT IN SIMULATOR!!!

Step9: 
Now, to send Email we shall add the following code inside the if statement ([sender tag] == 2)  of activateAction method. 



if ([MFMailComposeViewController canSendMail])
{
[self sendEmail];
}
else 
{
        NSLog(@"Device is unable to send email in its current state.");
}


[MFMailComposeViewController canSendMail] returns true if the current device is capable of operating Email feature and returns false if it doesn't. 

And we need to name the sendEmail method in .h file of the viewController and implement it in .m file.

- (void) sendEmail
{
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
mailViewController.mailComposeDelegate = self;
[mailViewController setSubject:@"Subject Goes Here."];
[mailViewController setMessageBody:@"Your message goes here." isHTML:NO];
[self presentModalViewController:mailViewController animated:YES];
[mailViewController release];
}



If we wanted the app to quit the present app and open up the default Email app we could simply write

[[UIApplication sharedApplication] openURL: @"mailto:john.appleseed@apple.com"];



We shall be able to test in simulator and it should look as followed image.




Step10: Now, to open up the city of "London" in MAP we shall add the following code inside the if statement ([sender tag] == 3)  of activateAction method. 


[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://maps.google.com/maps?q=London"]];


We shall be able to test in SIMULATOR and it shall look like as followed image!!!




Step11: Now, to open up the URL "www.google.com" in Browser we shall add the following code inside the else statement of activateAction method. 


[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.google.com/"]];


We shall be able to test in SIMULATOR and it shall look like as followed image!!!

Adios Amigos!!!


Thursday, May 3, 2012

Dealing with Animation: Simple Sequential Image Animation

Today, I am creating a simple animation with an array of sequential images. Animation like this are sometimes very useful like displaying a person is walking rather than a static stalled image.

I am doing a Bonfire(http://appsamuck.com/day2.html) today. A fire is set with pile  of woods and it is burning. So, I am going to set images frame after frame within a short interval of time so that it seems alive. I picked 17 images.

Step1:  First, we create a project "Bonfire" which should be a view based application.


Step2: I wanted the app to be full screen and not to show the status bar. So, I double clicked on info.plist and added a row"Status bar is initially hidden" and checked it.



Step3: I have declared IBOutlet for an UIImage View and named it campFireView in .h file of viewController and in .m file I synthesized it.

BonfireViewController.h


#import

@interface BonfireViewController : UIViewController 
{
IBOutlet UIView *animationView;
IBOutlet UIImageView *campFireView;

}

@property (nonatomic,retain) UIImageView *campFireView;

@end



Step4: I declared a method .h of viewController named "startAnimation"with a void return type and in .m file implemented it like followed.

And called the method from viewDidLoad 


- (void)viewDidLoad 
{
    [super viewDidLoad];
[self startAnimation];
}


BonfireViewController.h


#import

@interface BonfireViewController : UIViewController 
{
IBOutlet UIView *animationView;
IBOutlet UIImageView *campFireView;

}

@property (nonatomic,retain) UIImageView *campFireView;
- (void) startAnimation;
@end

BonfireViewController.m

- (void) startAnimation
{
campFireView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
campFireView.animationImages = [NSArray arrayWithObjects:[UIImage imageNamed:@"campFire01.gif"],[UIImage imageNamed:@"campFire02.gif"],[UIImage imageNamed:@"campFire03.gif"],[UIImage imageNamed:@"campFire04.gif"],[UIImage imageNamed:@"campFire05.gif"],[UIImage imageNamed:@"campFire06.gif"],[UIImage imageNamed:@"campFire07.gif"],[UIImage imageNamed:@"campFire08.gif"],[UIImage imageNamed:@"campFire09.gif"],[UIImage imageNamed:@"campFire10.gif"],[UIImage imageNamed:@"campFire11.gif"],[UIImage imageNamed:@"campFire12.gif"],[UIImage imageNamed:@"campFire13.gif"],[UIImage imageNamed:@"campFire14.gif"],[UIImage imageNamed:@"campFire15.gif"],[UIImage imageNamed:@"campFire16.gif"],[UIImage imageNamed:@"campFire17.gif"],nil];
campFireView.animationDuration = 1.75;
campFireView.animationRepeatCount = 0;
[campFireView startAnimating];
[self.view addSubview:campFireView];
[campFireView release];
}


Step5: I have added a new group under resource folder and put the 17 imaged under it.















Step6: Build and Run. and the app shows as followed.

Wednesday, May 2, 2012

Dealing with date: A Countdown Clock

My intention is to build small code segments that I may need to us when I need to build bigger projects.

I am creating an application that shows a countdown a 24 hour from present time (I am following http://appsamuck.com/).

Step1:  I created a simple View Based Application "MinutesToMidnight" on Xcode



Step2: I double clicked on the Resource-> MinutesToMidnightViewController.xib

Step3: Added a UILabel where the countdown shall be displayed and also selected the view and changed its color property. Also, changed the font of the label.



Step4: Declared IBOutlet for the label in the MinutesToMidnightViewController and drag and made it recognized to the file's owner. Actually, as I want to control the label to change its value programmatically, I need to tell the Interface builder that it is the label I will be referring about.



MinutesToMidnightViewController.h

#import 

@interface MinutesToMidnightViewController : UIViewController 
{
IBOutlet UILabel *lblClock;

}
@property (nonatomic,retain) UILabel *lblClock;



-(void) updateLabel; 

@end

MinutesToMidnightViewController.m
@synthesize lblClock;






Step5: I need a timer. Well, I will declare a NSTimer on AppDelegate(??). But Why in app delegate and why NOT in the view controller?? I am not much sure. But, I assume that putting the timer available in app delegate will help the other view controllers(If we had more) reuse it as timer task is an expensive operation.

So, in app delegate.h I declared an NSTimer variable and in .m file I initialized it in application didFinishLaunching method.


timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];

Also, I declared a method (onTimer)in .h file and implemented it in .m file of the app delegate.

What I wrote in method named onTimer?

-(void)onTimer
{
[viewController updateLabel];
} 

What does it mean?? It means send a message to viewContoller(Look in .h file of app delegate and we shall find that it is a pointer reference to MinutesToMidnightViewController) to call a method named updateLabel. So, we in future shall write a method in view controller in that name. 

What is a selector?? Let me google it first.

In Objective-C, selector has two meanings. It can be used to refer simply to the name of a method when it’s used in a source-code message to an object. It also, though, refers to the unique identifier that replaces the name when the source code is compiled. Compiled selectors are of type SEL. All methods with the same name have the same selector. You can use a selector to invoke a method on an object—this provides the basis for the implementation of the target-action design pattern in Cocoa.

Step6: Now we need to declare updateLabel the method on .h file of viewcontroller implement the method on .m file



-(void)updateLabel
{
NSDate* now = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [gregorian components:(NSHourCalendarUnit  | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:now];
NSInteger hour = 23 - [dateComponents hour];
NSInteger minute = 59 - [dateComponents minute];
NSInteger second = 59 - [dateComponents second];
[gregorian release];

lblClock.text = [NSString stringWithFormat:@"%02d:%02d:%02d", hour, minute,second];
}

Lets explain the code. We have an NSDate and NSCalendar variable. NSCalendar instance is initialized as a gregorian calendar. 

NSDateComponent variable took the format(Hour, minute and second) from that NSCalendar instance and specific date is derived from NSDate instance. As we are calculating hour, minute and second from a fixed countdown point, 24 hours to present time, we deducted 23 from hour from date Component hour and 59 minute and 59 seconds from minute and date respectively.

Afterwards we associated it with the text of the label in which we are showing the time. 

Step7: Now Lets Build and run and it should look like this


N.B. We need to invalidate and release the timer in applicationWillTerminate and dealloc
respectively in the .m file of app delegate