Getting started with iOS development : Xcode an...

Introduction

In this tutorial, you will discover the main tools used for the developement of iOS native applications. Starting off with Objective-C, the programming language, and Xcode, the IDE.

At the end of this tutorial, you will be able to :

  • Understand the basics of Objective-C (syntax, memory management, ...)
  • Create a project in Xcode
  • Create a Hello World iPhone app
  • Explore the iOS developer documentation
The purpose of this tutorial is to give you the basic knowledge to start developping iOS applications.
The whole documentation can be found here :


You can find a table of special characters shortcuts on Apple keyboard  here.

If you need to login to apple developer site, the credentials are :

 User  epfl.sdp2011@gmail.com  Password     <ask the staff>

Objective-C

Class structure
An example of a "Car" class, with :
  • 4 instance variables
  • 2 instance and 1 class methods

It is normal if you don't understand everything after reading this example ! Things are explained one after the other in the next sections. 



Car.h - class declaration

#import <Foundation/Foundation.h>

#import <UIKit/UIKit.h>


#import "Person.h"


@interface  Car : NSObject {

    

    /* Instance variables */

    

    //won't be accessible outside class, applies to all following variables

    @private

    long serialNumber;

    NSString* modelName;

    UIColor* paintColor;

    Person* owner;

}


/* Properties */


//non thread-safe getters will be generated

@property (nonatomicreadonlylong serialNumber;

@property (nonatomicreadonlyNSString* modelName;


//non thread-safe getter and setter and will be generated. Setter will copy received color

@property (nonatomiccopyUIColor* paintColor;


//non thread-safe getter and setter and will be generated. Setter will make a strong reference on received owner

@property (nonatomicstrongPerson* owner;



/* Public methods */


//Instance (-) custom constructor method

- (id)initWithSerialNumber:(long)serial modelName:(NSString*)model color:(UIColor*)color;


//Class (+) custom "convenient" constructor

+ (Car*)carWithSerialNumber:(long)serial modelName:(NSString*)model color:(UIColor*)color;


//Instance (-) method

- (void)printHelloWorld;


@end



Car.m - class implementation

#import "Car.h"


@implementation Car


@synthesize serialNumber, paintColor, modelName, owner;


/* Instance (-) custom constructor method */

- (id)initWithSerialNumber:(long)serial modelName:(NSString*)model color:(UIColor*)color {

    self = [super init]; //call to default super constructor

    

    if (self) { //check that that construction did not return a nil object. 

                    Equivalent to if (self != nil) { ... }

        

        serialNumber = serial;

        modelName = model;

        self.paintColor = color; //Because of the "self." we are using here the setter that will copy the value

        //we could also have done : paintColor = [color copy];

        

    }

    return self;

}


/* Class (+) custom "convenient" constructor */

+ (Car*)carWithSerialNumber:(long)serial modelName:(NSString*)model color:(UIColor*)color {

    return [[self allocinitWithSerialNumber:serial modelName:model color:color];

}


/* Instance method */

- (void)printHelloWorld {

    NSLog(@"Hello, world !"); //NSlog(@"<string format>", arguments) is the equivalent to System.out.println(...) 

}


/* Overriding description (equivalent to toString in JAVA) */

- (NSString*)description {

    return [NSString stringWithFormat:@"<Car> serial number : %ld, model : %@, color : %@, owner : %@"serialNumbermodelNamepaintColorowner];

}


@end



Use of Car class - example

UIColor* red = [UIColor redColor];

    

Car* car0 = [[Car allocinitWithSerialNumber:12344 modelName:@"Clio" color:red];

    

    

/* OR SIMPLER : use convenient constructur we have defined : */

    

Car* car = [Car carWithSerialNumber:12345 modelName:@"Clio" color:red];

    

[car printHelloWorld]; //prints "Hello, world !"

    

NSLog(@"%@", car); //prints "<Car> serial number : 12345, model : Clio, color : UIDeviceRGBColorSpace 1 0 0 1, owner : (null)"

    

    

/* change car attributes */

    

UIColor* blue = [UIColor blueColor];

    

car.paintColor = blue; //Important : this line uses the setter ! This is completely equivalent to [car setPaintColor:blue]. Both are correct.


car.serialNumber = 234234; //ERROR : serial number is readonly


car->serialNumber = 234234; //ERROR : serial number is @private


What we can learn from this example :

  • Objective-C standard structure uses .h and .m files
  • Instance variables are protected (@protected) by default, but one should always use private (@private)
    @public is also possible but strongly discouraged. Using a property to generate a getter is the proper way.
  • @properties are the way to generate getters and setters
  • (id) is a simplification for NSObject*. It represents a pointer to any object and disables compiler warning when casting.
  • Public methods need to be prototyped in .h file
  • - and + represent instance and class (static) methods respectively
  • All standard C types can be used, side-by-side with Objective-C/Cocoa types (NSString, UIColor, NSNumber, NSArray, ...)
  • Method calls use the following syntax : [instance nameOfTheInstanceMethod] or [Class nameOfTheClassMethod]
  • Strings (type NSString*) are preceded by an @. For example : NSString* myString = @"Toto";
  • NSLog() is the equivalent of System.out.println() in Java 

Collections

Before diving into more details, here is a short overview of the 2 most useful collection types.

NSArray : represents an immutable array, on which objects pointers can be retrieved using an index integer.

NSMutableArray : mutable version of NSArray. NSMutableArray subclasses NSArray.

NSDictionary : represent an immutable key-value/object pointer dictionary (hash table).

NSMutableDictionary : mutable version of NSDictionary. NSMutableDictionary subclasses NSDictionary.

Neither arrays or dictionary are typed. Meaning that they can contain multiple types for their values ("id" pointers).
Note : immutable = cannot be modified. New objects cannot be inserted into an NSArray, while they can in an NSMutableArray for example.
A complete guide to all available collections can be found here.

Methods
We have seen in the Car class example how methods are declared and used. But as their definition is quite atypical, here some precisions.
Imagine we have an initialized array of type NSMutableArray and we want to insert element myCar at index 3.
We use the following method defined by NSMutableArray class :

- (void)insertObject:(id)anObject atIndex:(NSUInteger)index


In practice, it makes :

[array insertObject:myCar  atIndex:3]


insertObject and atIndex are called labels. 


Labels added to method type (instance (-) or class (+)) define the method. Two methods with the same labels cannot be declared together, even if their type differ.


The previous method minimal, exact and sufficient definition is actually :    insertObject:atIndex:


For example, these three methods are the same for the compiler and fail to compile when declared together :


- (void)insertObject:(id)anObject atIndex:(NSUInteger)index

- (void)insertObject:(Car*)anObject atIndex:(NSUInteger)index

- (void)insertObject:(Car*)aCar atIndex:(NSUInteger)index



But :

- (void)insertCar:(Car*)aCar atIndex:(NSUInteger)index

is OK.

What are anObject and index then (opposed to the labels) ? They are the name of the variables you will use inside the method.

Finally, if this definition schema is quite "heavy", it has the advantage that it can be read like a whole sentence and thus easily understandable.
Selectors (type "SEL")

The selector type is very important in Objective-C. It is a kind of pointer on a method. You'll see them very often in the documentation.

Imagine for example that you want to call the printHelloWorld method on a car instance with a delay and every 1 second. We use the class NSTimer class for that :

[NSTimer scheduledTimerWithTimeInterval:1.0 target:car selector:@selector(printHelloWorld)userInfo:nil repeats:YES];


We have created a selector by using @selector(<method_signature>).


Memory management

Until last year memory management is Objective-C was manual, using a system called reference counting.

But this management is now automatic since Xcode 4.2 that introduces automatic reference counting (ARC).

Basically, you can see ARC as a mechanism provided by the compiler that will automatically add in the code calls to methodrelease (free memory) on an object A whenever no more pointer are pointing to it.

Nonetheless, it does not prevent retain cycles.

A retain cycle is when to objects A and B have a reference to each other. Meaning A->B and B->A.

Imagine the following case:

30163302_S7tG.png

Now, if A is freed from memory, it is no longer pointing to B. But as C is pointing to B and vice-versa, they will be both kept in memory.

problem typically appears when implementing a tree : chilldren nodes should not have a strong reference to their parents, so that releasing the root node releases the whole tree.

To prevent this problem, pointers can be strong (default) or weak.

  • strong (default)
    A strong pointer will make pointed object be kept in memory. This is default for instance variables and properties.

  • weak
    A weak pointer will not be considered as a real pointer in terms of memory management. If A weakly points to B and there is no other (strong )pointer to B, B will be freed from memory.
    Specifying a pointer as weak is not the following way :

    Node__weak parent;


Note: other pointers types are available, but less used in practice. The complete list is available here.
@property

In the previous Car class example, we have seen that @property is the clean way to generate getters and setters for instance variable.

Now that we have seen how the memory is managed, we can understand how they are defined :

@property(attributestype  name;

The attributes are divided into four groups and can take the following values :

1) Access type

  • readwrite (default) : will generate getter and setter
  • readonly : will only generate getter
2) Memory management
  • strong (default) : setter will make a strong reference to received object
  • weak : setter will make a weak reference to received object
  • copy : setter will copy received object and make a strong reference to it
3) Customization
  • getter=... : can rename getter method (default is <nameOfTheProperty>)
  • setter=... : can rename setter method (default is set<NameOfTheProperty>)
4) Thread management
  • nonatomic : the generated setter will not be thread-safe
  • not specified (default) : the generated setter will be thread-safe (synchronized in java) 


Important note : w hen setting values to instance variables inside a class, there is an important destination to make between :

name  @"A name";


/* The instance variable is accessed directly, without using the setter => ignores attributes mentioned above */


and

self.name = @"A name";

[self setName:@"A name"];


/* These two lines are completely equivalent. The setter is called. */


Property without instance variable : it is totally possible to have a property without a corresponding instance variable. In that case, it is necessary to access the variable using the self. notation.


Protocols
In Objective-C, the protocols are the  equivalent of the interfaces in Java and are defined using @protocol keyword. More  here.
Categories
Obective-C provides are very easy way to add functionality to an existing class without subclass :  categories.


Xcode

Xcode is the main tool you will use to develop your app. It is the Eclipse for iOS development.


We will use Xcode 4 and iOS 5 SDK, which are installed on INF2 machines.

To use Xcode on your own machine

If you have a Mac on Mac OS X 10.7.4 or later ( -> About this Mac) you can download Xcode 4.5 with iOS 6 SDK for free from the Mac App Store.


Create a project in Xcode

0. Workspace preparation (skip this step if you use your own machine)
  • Mount your personal folder, using the shortcut on the desktop
  • Go to Finder preferences
30163303_1zxj.png

  • Go to Sidebar tab and check the first line "icin2pcXX.epfl.ch" and close the window.
30163303_NFwW.png


1. Start Xcode
Type Xcode in the Spotlight search field at the top right of the screen, then press return.

30163304_mHBm.png

2. Select "Create a new Xcode project".
30163304_m4xs.png

3. Select "Single View Application" and click next. (If this options does not appear, select "View-based Application").
30163305_3r1C.png


4. Enter the following informations :
30163306_ixLr.png


5. Click next and save the project to your personal folder, in a new folder named "SDP" :
30163307_1vlK.png


6. The project creation is done and should have a window like this :
30163308_ShsU.png



Create a Hello World iPhone App

The project created in step one is empty.  Try running it by clicking the "Run" button. It will open the iOS simulator and you should see a boring gray window.

So let's add some things to this window.

1) To do so,  select (single-click) the file "ViewController.xib" in the file explorer column (a single-click changes to current view to new file, double-click open a new tap/window, depending of your Xcode preferences). Now click on the buttons shown in red below :

30163308_s0I1.png
Xcode 4.2


2) Now select the objects tab in the bottom right and drag a Label and a Button into the iPhone view.

30163309_lvSa.png


3) Change the button text by double clicking on it.

30163310_4SAT.png

4) We are now going to link these items to instance variables of  ViewController class.
To do so, open (single-click) ViewController.h file in file explorer and insert the following properties in class declaration

Properties to add to ViewControll.h

@property (nonatomicIBOutlet UILabel* label; // IBOutlet attribute makes this property visible from the interface builder tool

@property (nonatomicIBOutlet UIButton* tapMeButton;


5) Now go to  ViewController.m and implement the  buttonAction method, which determinates what will happen when we touch the button we added before. In our case, setting the text of the label to "Hello!". Add the following method :

Method to add in ViewController.m

- (IBAction)buttonAction { //return type IBAction makes this method visible as action from the interface builder tool

    self.label.text = [NSString stringWithFormat:@"Hello World ! Time : %ld"time(NULL)];

}


6) Return to the user interface file  ViewController.xib. Since we added the IBOutlet and IBAction to the ViewController class, we can now link the visual elements to these instance variables. To do so, right-click (ctrl-click) on "File owner" and draw a line from "tapMeButton" to the button. Do the same for the "label".

30163311_meEe.png

30163311_Vrf4.png

7) Finally, link the "buttonAction" method to the button "Touch Up Inside" action (which represents the standard touch).

30163311_vVCP.png

8) We are done ! Run your application in the iOS 5 or iOS 6 simulator
30163313_eC9U.png



30163313_oXrj.png


Explore the iOS developer documentation

To develop your knowledge on iOS development, you will have to browse the documentation. You can find it online here :


When using a class in Xcode, you can find its related documentation with cmd+click.

30163313_JJt8.png

You can also search for a function of an Xcode menu by typing it in the search field :

30163314_ODfc.png


转载于:https://my.oschina.net/u/557242/blog/106449

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值