Sunday, November 23, 2014

iOS Tutorial - Part 25 - Xcode - debugging - tools

Xcode debugging tools


Video Description 
Sometimes when you run the app and do some actions, application stops and it goes to a class name "main.m". This is happen when an exception raises that is not handled. In order to get more information about the crash and the exception we have different tools. In the following we will get familiar with some of these tools.

Console:

When exception raises or app crashes, at the bottom of the Xcode, you can see console that has some useful information. It can tells what kind of exception happened and what method causes this problem.

All Exception Breakpoint:

From console we can see the method name that causes the error but it's very inefficient to search all over the code to find the method. In order to find the line of code that causes the crash we need to add "All Exception Breakpoint". Open Breakpoint navigator tab on the top left side of Xcode. At the very bottom of the page click on "+" button. Select "Add Exception Breakpoint". Now if you run the program and it crashes, it brings up the line of code that causes the crash.

Custom Breakpoint

You can add custom breakpoint anywhere in your app. It stops the app and shows the line of code you add the breakpoint. In order to add custom breakpoint, just click on the left side border of the line you want. Blue arrow will show up. If you run the application and it reaches the breakpoint you have multiple buttons that you can use to get more detail information. These buttons are as follow:


Continue:

It will continue running the application (Executing rest of the code).

Step Over:

It will go one step ahead, for example if there is a line after your breakpoint it will go to the next line.

Step into:

It will go deep inside of that line of code. For example if you call other methods in this line if you step into, it will go to that method. If you have property in that line it will show setter and getter. If there is nothing to go in, it will go to the next line.

Step out:

If you step into via the "Step into" button, you can go out by pressing "Step out".

Conditional Breakpoint:

If you add a breakpoint, whenever app reaches that line of code, it will pause and show the line you specified. If you want to pause only in certain condition, just right click on the breakpoint and from the opening menu select "Edit Breakpoint". From the opening window add your condition in the blank field. Your condition should be written in objective c language.

Debug View Hierarchy:

If you want to have a 3D view of your application, run the application then press "Debug View Hierarchy"

Sunday, November 16, 2014

iOS Tutorial - Part 24 - UIScrollView

UIScrollView


Video Description 
When the contents of a view is not fit inside of the device size we need to use scroll view. We can easily drag and drop it inside of our view controller. Then setting the content size of the scroll view with setContentSize method.

contentSize

If you are setting the content size of the scroll view equal to a view element, make sure that the view element size is set by that time. For example for imageView, we should set the scroll view size after imageView gets its image, like bellow.
    UIImage *img = [[UIImage alloc] initWithData:dataImage];
    [self.imageView setImage:img];
    self.scrollView.contentSize = self.imageView.image.size;

minimumZoomScale and maximumZoomScale

In order to add zooming feature to the scrollView we need to set the min and max zoom scale. minimumZoomScale indicates the least scale that user can zoom out (0 to 1). maximumZoomScale indicates maximum scale that user can zoom in to the picture.
   self.scrollView.minimumZoomScale = 0.2;
   self.scrollView.maximumZoomScale = 3.0;
A good place for setting these properties are in the scrollView setter, like bellow:
- (void)setScrollView:(UIScrollView *)scrollView
{
    _scrollView = scrollView;
    _scrollView.minimumZoomScale = 0.2;
    _scrollView.maximumZoomScale = 3.0;
}
If you run the program it will not work because we have to define "Which view we want to zoom in scrollView". We indicate this view by implementing one of UIScrollViewDelegate method (viewForZoomingInScrollView). Before implementing this delegate method don't forget to add the name of the delegate method in front of interface like <UIScrollViewDelegate> and setting delegate equal to self. We can add it in scrollView setter like bellow:
- (void)setScrollView:(UIScrollView *)scrollView
{
    _scrollView = scrollView;
    _scrollView.minimumZoomScale = 0.2;
    _scrollView.maximumZoomScale = 3.0;
    _scrollView.delegate = self;
}

viewForZoomingInScrollView

Inside of this delegate method we just return the view that we want to be able to zoom. In our example it's imageView, so the implementation would look like:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return self.imageView;
}

zoomScale

In order to set the scale of zoom programmatically we can use this property. For example if we want to have the zoom scale of 1 (Actual size) we have:
self.scrollView.zoomScale = 1.0;

flashScrollIndicators

We don't have scroll bars on the screen all the times. We can show them for a moment. In order to flash the scroll bars for the user you can use flashScrollIndicators method like bellow:
[self.scrollView flashScrollIndicators];

Download

Download this App from here

Sunday, November 2, 2014

iOS Tutorial - Part 23 - UIAlertController, UIImagePickerController

UIAlertController, UIImagePickerController


Video Description 

UIAlertController

Displays an alert message to the user. This class replaces the UIActionSheet and UIAlertView classes for displaying alerts.

Steps to create UIAlertController

1- Initialize allertController with the specified title, message and the style you want.
    UIAlertController *alertCtrl = [UIAlertController alertControllerWithTitle:@"Alert Title" message:@"Alert Message" preferredStyle:UIAlertControllerStyleActionSheet];
2- Create actionAllert with specified title, style and handle the event when user taps on it
    UIAlertAction *buttonOnAlertCtrl = [UIAlertAction actionWithTitle:@"Button Title" style:UIAlertActionStyleDefault
                                                   handler:^(UIAlertAction *action)
                                                    {
                                                        //Handle Event
                                                    }];
3- Add the button to the allertController
[alertCtrl addAction:buttonOnAlertCtrl];
4- Show it to the screen
[self presentViewController:self.alertCtrl animated:YES completion:nil];

UIImagePickerController

You can use UIImagePickerController to get image from PhotoLibrary or Camera

Steps to get image from Camera

1- Create a property like bellow to access UIImagePickerController anywhere inside of your class @property (strong, nonatomic) UIImagePickerController *imagePicker; 2- Initialize and allocate memory
self.imagePicker = [[UIImagePickerController alloc] init];
//Set delegate method equal to self
self.imagePicker.delegate = self;
//Set source type (Here we choose camera)
self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
//Present the camera to the screen
[self presentViewController:self.imagePicker animated:YES completion:nil];
2- Add delegate names (UIImagePickerControllerDelegate, UINavigationControllerDelegate) in front of the interface
@interface ViewController () 
3- Implement UIImagePickerControllerDelegate method
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSData *dataImage = UIImageJPEGRepresentation([info objectForKey:@"UIImagePickerControllerOriginalImage"],1);
    UIImage *img = [[UIImage alloc] initWithData:dataImage];
    //img is the picture that user captured with the camera, you can do whatever you want with this picture
    //Add your own implementation here
}

Get get image from Photo Library

The steps are exactly like the steps for getting image from camera, except the source type. You should use the following line instead of line 4 of step 2:
    self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

Write Macro to compile different block of code for simulator vs. actual device

If we want to tell the compiler to run a block of code if its simulator and other block of code if it's on actual device, we can use the following if else statement: #if TARGET_IPHONE_SIMULATOR //Put the block of code that you want to be executed if it's running on the simulator #elif TARGET_OS_IPHONE //Put the block of code that you want to be executed if it's running on the actual device #endif

All of the code for this tutorial

#import "ViewController.h"

@interface ViewController () <UIImagePickerControllerDelegate, UINavigationControllerDelegate>

@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (strong, nonatomic) UIAlertController *alertCtrl;
@property (strong, nonatomic) UIImagePickerController *imagePicker;
@end

@implementation ViewController

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

- (void) setupAlertCtrl
{
    self.alertCtrl = [UIAlertController alertControllerWithTitle:@"Select Image"
                                                         message:nil
                                                  preferredStyle:UIAlertControllerStyleActionSheet];
    //Create an action
    UIAlertAction *camera = [UIAlertAction actionWithTitle:@"Camera"
                                                     style:UIAlertActionStyleDefault
                                                   handler:^(UIAlertAction *action)
                                                    {
                                                        [self handleCamera];
                                                    }];
    UIAlertAction *imageGallery = [UIAlertAction actionWithTitle:@"Image Gallery"
                                                     style:UIAlertActionStyleDefault
                                                   handler:^(UIAlertAction *action)
                                                    {
                                                        [self handleImageGallery];
                                                    }];
    UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel"
                                                           style:UIAlertActionStyleCancel
                                                         handler:^(UIAlertAction *action)
                                   {
                                       [self dismissViewControllerAnimated:YES completion:nil];
                                   }];

    
    //Add action to alertCtrl
    [self.alertCtrl addAction:camera];
    [self.alertCtrl addAction:imageGallery];
    [self.alertCtrl addAction:cancel];
    
    
}

- (IBAction)selectImagePressed:(UIButton *)sender
{
    [self presentViewController:self.alertCtrl animated:YES completion:nil];
}

- (void)handleCamera
{
#if TARGET_IPHONE_SIMULATOR
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Error"
                                                                   message:@"Camera is not available on simulator"
                                                            preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK"
                                                 style:UIAlertActionStyleDefault
                                               handler:^(UIAlertAction *action)
                                                {
                                                    [self dismissViewControllerAnimated:YES completion:nil];
                                                }];
    
    [alert addAction:ok];
    [self presentViewController:alert animated:YES completion:nil];
#elif TARGET_OS_IPHONE
    //Some code for iPhone
    self.imagePicker = [[UIImagePickerController alloc] init];
    self.imagePicker.delegate = self;
    self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    [self presentViewController:self.imagePicker animated:YES completion:nil];

#endif
}

- (void)handleImageGallery
{
    self.imagePicker = [[UIImagePickerController alloc] init];
    self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    self.imagePicker.delegate = self;
    [self presentViewController:self.imagePicker animated:YES completion:nil];
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSData *dataImage = UIImageJPEGRepresentation([info objectForKey:@"UIImagePickerControllerOriginalImage"],1);
    UIImage *img = [[UIImage alloc] initWithData:dataImage];
    [self.imageView setImage:img];
    [self.imagePicker dismissViewControllerAnimated:YES completion:nil];
    
}

Download

Download this App from here