First application

In this tutorial we cover the following topics


Concepts, info etc.



The Model-View-Controller


Cocoa Touch – a UI framework for building software programs to run on iOS (for the iPhone, iPod Touch, and iPad) – heavily uses model-view-controller (MVC) pattern. MVC divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user.

Components

  • The model directly manages the application’s data.
  • The view can be any output representation of information, such as a chart or a diagram. Also other elements like windows, controls, and other that the user can see and interact with are considered to be a part of a view. Multiple views of the same information are possible, such as a bar chart for management and a tabular view for accountants.
  • The controller, accepts input and converts it to commands for the model or view. Controller binds together the model and view. It contains the application logic that decides how to handle the user’s inputs.

Interactions

In addition to dividing the application into three kinds of components, the model-view-controller design defines the interactions between them.

  • A model stores data that is retrieved according to commands from the controller and displayed in the view.
  • A view generates an output presentation to the user based on changes in the model.
  • A controller can send commands to the model to update the model’s state (e.g. editing a document). It can also send commands to its associated view to change the view’s presentation of the model (e.g. by scrolling through a document).

It is worth to note that MVC pattern was introduced into Smalltalk – the precedesor of Objective-C.




Actions


An interface objects in a storyboard or nib file can be set up to trigger special methods in our controller class: action methods. For example, we can decide that when the user press a button, a specific action method should be called. Actions are methods that are declared with a special return IBAction code. The declaration for an action method will one of the following forms:

- (IBAction)doSomething;
- (IBAction)doSomething:(id)sender;
- (IBAction)doSomething:(id)sender
               forEvent:(UIEvent *)event;



Outlets


A controller class can refer to objects in a storyboard or nib file by using a special kind of property called an outlet. We can think of an outlet as a pointer to an object within the user interface. For example we can created a button in Interface Builder. By declaring an outlet and connecting that outlet to the button object, we would then be able to use the outlet from within a code to change the text displayed on that button.

Outlets are special Objective-C class properties that are declared using the keyword IBOutlet. Declaring an outlet is done either in the controller’s class header file or in a special section, called the class extension, of the controller’s implementation file. Below there is an example of an outlet called myButton, which can be set to point to any button in the user interface.

@property (weak, nonatomic) IBOutlet UIButton *myButton;


Delegates


Delegates, in short, are objects that take responsibility for doing certain tasks on behalf of another object. In iOS the application delegate lets us do things on behalf of the UIApplication class. Every iOS application has exactly one instance of UIApplication, which is responsible for the application’s main loop and handles application-level functionality, such as routing input to the appropriate controller class. UIApplication is a standard part of the UIKit, and it does its job quite well without any programmers attention; generally we don’t need to touch this part of code.

During an application’s execution, at certain times, UIApplication will call specific methods on its delegate. For example, if we want to execute some code just before the program quits, we would implement the method applicationWillTerminate: in an application delegate and put our termination code there. This type of delegation allows the application to implement common behavior without need to subclassing UIApplication.

The standard application delegate look something like this (this code was taken from AppDelegate.m file autogenerated for the project which is the main goal of this part of the tutorial)

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state.
    // This can occur for certain types of temporary interruptions (such as
    // an incoming phone call or SMS message) or when the user quits the application
    // and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down
    // OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers,
    // and store enough application state information to restore your application
    // to its current state in case it is terminated later.
    // If your application supports background execution, this method is called
    // instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the inactive state;
    // here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application
    // was inactive. If the application was previously in the background,
    // optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate.
    // See also applicationDidEnterBackground:.
}

@end

li>Xcode file formats


Xcode file formats


Interface Builder – an Xcode part we use to design iOS application – supports a few different file types.

  • .nib The oldes one is a binary fomat that uses the extension .nib
    Each nib file can contain any number of objects, but when working on iOS projects, each one will usually contain a single view and controllers or other objects that it is connected to. Such a approach help us to divide an aplication into idependent parts which can be loaded ony when they are needed for display.
  • .xib This is a modern, XML-based, version of .nib files. Both of these formats contain exactly the same sort of document, but the .xib as text-based is more natual choice in term of human readability and source control management systems.
  • .storyboard This type of file can contain several view controllers, as well as information about how they are connected to each other when the application runs. A storyboard never loads all its contents at once which is opposite to the all at once load nib files.
  • It’s good to note that although .nib files are today not in use – they are replaced by modern formats – Interface Builder files are still called nib files in many documentation, regardless of whether the extension actually used for the file is .xib or .nib.


Good to read, good to know




First iOS application

  1. Step 1: setting up a project in Xcode
    Launch Xcode and select File | New | Project... In project window select iOS | Application | Single View Application template and then click the Next button.
    001
    You will see the project options sheet, which should look like below (image below shows the completed options sheet after specifying the fields)
    002
    Press Next button, and you will be prompted for a location for your project.
    003
    Press Create to save the project.
  2. Step 2: a closer look at the project files
    Let’s look at the files that were created for us by Xcode.
    004

    • The first folder, which is always named after our project, is iOS First Application. This is a place where most of the code that we will create go. In the Project Navigator expand the iOS First Application folder. This folder should contain four source code files (the ones that end in .h or .m), a storyboard file, a launch screen file, and an asset catalog for containing any images that the application needs.

      The source code files implement two classes that our application needs: the application delegate and the view controller for our application’s (only) view. The controller class called ViewController is responsible for managing our application’s view.

      Main.storyboard contains the user interface elements specific to our project’s main view controller.

      The Supporting Files folder contains source code files and resources that aren’t Objective-C classes, but that are necessary to our project. Typically this folder can contains two files:

      • main.m contains the application’s main main() method. In most cases there is no need to touch this file.
      • Info.plist is a property list that contains information about the application, such as its name, whether it requires any specific features to be present on the devices on which it is run, and so on.
    • The iOS First Application(UI)Test folders contains the initial files needed to write some unit tests for the application.
    • The Products folder contains the application that this project produces when it is built.

    It is worth to note that the folders in the navigator area do not have to correspond to real folders in a file system. These are logical groupings within Xcode to help us to mantain the source code. The hierarchy inside Xcode is completely independent of the file system hierarchy, so moving a file in Xcode will not change the file’s location on the file system.

    When we take a closer look at ViewController.m file we can find there an empty class extension (@interface ViewController ()) as well as some boilerplate code in the form of viewDidLoad and didReceiveMemoryWarning methods. We can keep them all or delete (or simply comment) if we have no intention to use it.

  3. Step 3: designing the user interface (add first button)
    Single click Main.storyboard file to open the application’s view in Xcode’s Interface Builder.
    005_03
    Now we are going to add some simple components: two buttons and one label. Select View | Utilities | Object Library (or select a correct icon in Xcode) and find in Object Library Button object (you can complete this faster with a help of serach field at the bottom).
    006
    Drag the Button from the library and drop it on the white window inside the editing area. This will add a button to your application’s view. Place the button along the left side of the view the appropriate distance from the left edge by using the blue guidelines that appear to place it. For vertical placement, use the blue guidelines to place the button halfway down in the view.
    007
    008
    Double-click this button – this will allow you to edit the button’s title. Give this button a title Previous.
    009
    Select View | Assistant Editor | Show Assistant Editor to open the Assistant Editor.
    010
    Alternatively we can show and hide the Assistant Editor by clicking the middle editor button in the collection of buttons on the upper-right side of the project window.
    011
    You should see ViewController.m or ViewController.h file. It is possible to switch between them with ,,arrows” (< or >). If, for some reason, it is not displaying the file that we want to see, we can use the jump bar (depicted as to overlapping rings) at the top of the Assistant Editor to fix that.

    To add action method to the view controller’s class extension click the button that was added to the storyboard, hold down the Control key, and then drag from the button over to the source code in the Assistant Editor (we should see a blue line). Move the cursor so it’s in the class implementation and when you will see a gray pop-up you can release the mouse button.
    012
    Now we have to fill a floating pop-up.
    013
    014
    Press Connect button or simply press Enter key to finish this process which should result the action method code insertion.
    015

  4. Step 4: designing the user interface (add second button)
    In the first half this step is very similar to the previous step: add second button named Next, located on the right.
    016
    017
    The reason why separated this step from the previous is that this time, we don’t want to create a new action method. Instead, we want to connect this button to the existing one that Xcode created a moment ago. We do it the same way as we did for the first button.

    Control-click the button and drag toward the code in the Assistant Editor (remember to open it before). Drag toward the declaration of the reviousl created buttonPress: method. This time, as the cursor gets near method source code, that method should highlight, and we will see a gray pop-up Connect Action. Release the mouse button. Xcode will connect the button to the action method. That will cause the button, when tapped, to trigger the same action method as the previous button.
    018
    You can verify that the trigger was creaded by pressing right mouse button on the button where in Sent Events section you shoud be able to find Touch Up Inside – View Controller buttonPress
    019

  5. Step 5: add the label and outlet
    Now you can use you knowledge and add a label object as we did it for buttons.

    Now select View | Utilities | Show Attributes Inspector or press the Attributes inspector icon
    020
    and change some of the label’s properties, for example alignment
    021
    022
    023
    024
    or remove default Label text
    025
    To add an outlet for this label, select the label in Interface Builder and Control-drag from the label to the header file (as we did it before). Drag until your cursor is in the extension part (between @interface and @end in ViewController.m file). After reeasing mous button we will see a pop-up window that offers to create an Outlet or an Outlet Collection.
    026
    027
    028
    As for buttons we can verify if outles has been created.
    029

  6. Step 6: add an action method
    Add the following code to the buttonPress method:

    NSString *title = [sender titleForState:UIControlStateNormal];
    NSString *textForLabel = [NSString stringWithFormat:@"%@ button pressed.", title];
    _infoLabel.text = textForLabel;
    

    Select Product | Run
    030
    The Previous button is accessible and works correctly but where is Next button? To fix this we have to work a little bit with a layout.

  7. Step 7: fix the layout
    To arrange correctly our components we will use Auto Layout. The idea behind Auto Layout is that we use some constraints to specify how we want the controls to be placed. Let’s say that we want

    • The Previous button to be vertically centered and close to the left margin.
    • The Next button to be vertically centered and close to the right margin.
    • The label should be close to the left margin, some way down from the top of the screen.

    We’ll start fixing with positioning the label. Select Main.storyboard in the Project Navigator and open the Document Outline to see the view hierarchy. Find the icon labeled View and click on it to open the View icon (if it’s not already open). Hold down the Control key and drag the mouse from the label to its parent view. This is how we set an Auto Layout constraint between components (simply by dragging from one view to another).
    031
    Release the mouse and a gray pop-up with various options (each is a single constraint) will appear.
    032
    Clicking any of them will apply that constraint. To apply more than one constraint at a time, we need to hold down the Shift key while selecting them. So hold down the Shift key and click Vertical Spacing to Top Layout Guide. To actually apply the constraints, click the mouse anywhere outside the pop-up. When you do this, the constraints that you have created appear under the heading Constraints in the Document Outline and are also represented visually in the storyboard.
    033
    Unfortunately we can see red outline around the label which means that there are some problems with Auto Layout. There are three typical problems that Interface Builder highlights in this way:

    • We don’t have enough constraints to fully specify a view’s position or size.
    • The view has constraints that are ambiguous.
    • The constraints are correct, but the position and/or size of the view at runtime will not be the same as it is in Interface Builder.

    .
    Every time we can find out more about the problem by clicking the yellow warning triangle in the Activity View to see an explanation in the Issue Navigator.
    034
    In our case this is Horizontal position is ambiguous for “Info Label”.

    Select the label on the storyboard and click the Pin button at the bottom right of the storyboard editor to open Pin pop-up.
    035
    036
    At the top of the pop-up, we will find four input fields connected to a small square by orange dashed lines. Set the constraint by entering 64 into left field.
    037
    Press Add 1 Constraint or if it is inactive you can press Enter to apply the constraint to the button.
    038
    We have now applied all of the constraints that we need, but there may still be warnings in the Activity View. To fix that, use the Resolve Auto Layout Issues button.
    039
    Click the button to open its pop-up and then click Update Frames from the top group of options. We use the option from the top group because we want only the frame of the label views in the view controller to be adjusted.
    040
    Great, label is done so let’s fix the buttons’ positions.

    Select the Previous button on the storyboard and click the Align button at the bottom right of the storyboard editor.
    041
    We want the button to be vertically centered, so select Vertically in Container in the pop-up and then click Add 1 Constraint.
    042

    043
    Now we have to add left margin constraint as we did it for the label.
    044

    045

    046

    047

    048
    If the value we have just entered is bad we can correct it selecting constraint in the storyboard or the Document Outline and open the Attributes Inspector.
    049

    050

    051

    052
    Great, the Previous button is done so let’s fix the Next.

    Select the Next button and repet steps we did for Previous button (but remember to set right not left margin constraint; I have also used -32 as a right constraints).
    053

  8. Step 8:
    Now we can again select Product | Run
    054

    055

    056
    The result maybe is not perfect but much better than last time.



Excercise 5.0


Write an iOS application according to the following rules

    Assumptions

  • Application should read data from a text file. Because at this moment we don’t know how to store data in a file, we have to mimic file operation and hide them in a class. So, we can create for example FileStorage class with methods like getFileContentsAsStringArray or append which internaly operates on string array but from user perspective behaves as it would use real file.
  • Each line describes one training.
  • Training data are expressed in the form
  • One training data should be represented in application as an object.
  • All training data (object) should be collected in an array.
  • Details of one training data are presented on the screen.
  • There should be Previous and Next buttons which we can use to switch to previous or next training data.
  • There should be also three more buttons to calculate some statistics, for example total time, total distance, average distance per week.
  • You can use the code presented in Hint 2 for the exercises from Data types part of this tutorial.

Leave a Reply

Your email address will not be published. Required fields are marked *