SlideShare uma empresa Scribd logo
1 de 112
Baixar para ler offline
IOS DEVELOPMENT
INTRODUCTION
Lou Loizides, PE
MS Computing Student @ Marquette


31 Mar 2013
http://boozall.com
Presentations
•  Class 1 – Objective C
   •  Background
   •  Requirements
   •  Concepts
   •  Syntax
•  Class 2 – iPhone Programming
  •  XCode
  •  Cocoa Classes
  •  Programming With/Without IB
  •  Sample App


•  If you need a book, the “Big Nerd Ranch” guides to iPhone
 Programming and Objective C are highly recommended
BACKGROUND AND
CONCEPTS
Objective C
•  Became popular on NextStep systems in the early 1980s
   •  Many objective C classes start with “NS”
•  Superset of C
   •  “Thin layer” on top of C compiler
   •  C code can be used anywhere within objective c source
   •  Compiler (LLVM) Capable of compiling C++
    •  Handy for open source libraries eg. (Tesseract, OpenCV)

•  Not managed
   •  Apps are native code, not byte code
   •  Understanding of memory management is important
   •  Apps will crash on errors – no try/catch
•  Objective C is the language, Cocoa is the framework
Requirements
•  Mac!
   •  Required an Intel processor
   •  Provisioning profiles need to be signed on Mac to distribute or test
      on a device
•  XCode
   •  Download from Mac App Store
•  If you need to test on an iOS device:
    •  Developer’s account: $100/yr
    •  Can distribute beta apps using ad-hoc methods
     •  Need phone UUIDs
  •  iPhone 4 or higher (3G/3GS won’t connect to XCode anymore)
  •  Note: Possible to run programs in the simulator without a
    developers’ account
Alternatives to XCode
•  Some alternatives to using XCode and Macs exist:
   •  Mono Touch
   •  App Titanium
   •  Unity 3D
   •  Flash CS5
   •  Phone Gap
•  The idea of Objective C is to create fast, efficient native
 code so these solutions aren’t the best
  •  Writing an iPhone app in Flash just seems like a bad idea
Quirks
•  Use “nil” instead of null
•  Usually you chose a 2 char prefix for all classes in an app
   •  Example: “WB” for an app called “Workbench”
•  @ symbol before a string is short hand for creating an
   NSString from a const char* (e.g. @"test")
•  Instead of true/false it’s yes/no (true/false can be used but
   it’s not common)
•  Almost all framework objects and functions use floats –
   integers are really only used in indices
  •  Eg. All graphics functions use floats for points
  •  Using floats mean you don’t have to cast as much
•  NSInteger and CGFloat more common than int and float –
 set to compile to 32 bit or 64 bit depending on target
Cocoa
•  Objective C is just the language – syntax, etc.
•  Cocoa provides the frameworks
•  Consists of:
   •  Foundation Framework:
    •    Root class is NSObject
    •    The majority of objects
    •    Objective C
    •    Prefixed with NS, UI, others
    •    Compatible with ARC, autorelease
  •  Core Foundation Framework:
      •  No root class
      •  C, not Obj C
      •  All prefixed with CF
      •  Must release manually using CFRelease
The Stack and Heap In Obj-C
•  Understanding memory management is critical in Obj-C
•  Stack:
   •  Transient storage of local primitives
   •  Last in, first out during functions
   •  Memory is released when function exits
   •  *Most* primitives (including pointers) will be on the stack
     •  Primitives allocated with classes end up on the heap
     •  If it’s declared within a function will be on the stack
•  Heap:
   •  Memory allocated for objects
   •  Doesn’t automatically release
   •  Rule of thumb (few exceptions): if “alloc” is need it’s on the heap
   •  Requires a pointer somewhere (either to variable or class) to find
Example
                            static allocation in heap
static int testA = 1.0f;	   Note: “.0f” means cast as
int testB = 1;	             float (usually not
                            necessary)
	
@implementation foo	
                            heap in object
{	
   -(void)bar	
   {	
      float testC=1;	       Stack – will
   }	                       disappear when
}	                          function is done
Pointers
                            0xABC111
         stack                                 heap
       0xABC111                             Allocated Object
       0xABC119
       0xABC11F




•  Pointers are int32 memory addresses (eg. ABC111)
•  Mostly used for addressing classes in objective-C, but can
 also be used for anything else allocated:
  •  Arrays in C (allocated using malloc)
  •  Pointers to other primitives – use to pass values “by reference”
Using Pointers
Address of a variable, class, etc:
      	int var = 16;	
      	int &varAddress = *int;	

Accessing data at pointer address:
      	*varAddress = 17	

Allocating memory and returning a pointer:
      	//allocate 10 ints	
      	//Note: because this is C you will need release()	
      	int *varAddress = (*int)malloc(10*sizeof(int));	
      	
Two different ways to declare:
      	myClass *pointer1, *pointer2; //preferred	
      	myClass* pointer1, pointer2;
Key Pointer Concepts for Obj C
•  Understand what’s on the stack
   •  Keep track of objects on the heap
•  Recognize null references
   •  Pointers should point to objects or nil to avoid errors
   •  Un-initialized primitives won’t crash program but null references will
•  All objects in Obj C are allocated dynamically using
   pointers
•  “id” can be used in place of object pointer
  •  Sort of like generic “object” class in VB
  •  Example:
       	NSString* myString = [[NSString alloc] init]	
       	id sameString = myString;
Quirks & Pointers Code Example
NSString *str = nil;!
CGFloat gV = 5.0f;!
BOOL testC = NO;!
!
for (NSInteger i=0; i<10; i++)!
{!
   testC = i>gV;!
   if (testC) str = @"test”;!
   //pointer will be 0x0 (nil) until it's past 5!
   NSLog(@"%d against %f and the pointer is %p”,!
      i,gV,str);!
   //a string is static so it’s always at the same ptr!
   //use NSMutableString if you want a copy!
   NSLog(@”text %@ still at %p",!
     "str,[str copy]);
}
Classes
•  Classes consist of Interface (class declarations) and
   Implementation (methods)
•  Usually two files are created for each class – one with
   each
  •  It is technically ok to put both in the same file, but this can slow
     down compiling
  •  It is technically ok to put multiple classes in the same file but most
     people don’t (I do it every now and then)
•  Most classes will inherit from another class
Class Inheritance in Objective C
•  Any class in objective C can derive from any class
•  Any function can be overridden
   •  Overriding a function requires no special syntax or keyword
   •  Program will first look for a function in the child class, then traverse up
      the class hierarchy until it finds a match
   •  Don’t forget to call [super methodName] if you need to keep traversing
   •  Access: “super” = parent class, “self” = current class
                                                                         Runs this
                                                                         one

        NSObject        -(void)test              NSObject         -(void)test


                            -(void)test                               No test
             MyObj                                     MyObj
                                                                      method
                               Runs this
                               one
Headers And Interfaces
•  Same concept as C, C++
•  Provides forward declaration (for compiler & IDE) of:
   •  Classes
   •  Variables
   •  Selectors
•  Memory for items declared in the class interface in the header
 (including structs and primitives) is allocated on the heap when
 the class is created
  •  At a minimum your class needs enough space for what’s in the interface
  •  Everything else is allocated dynamically as needed
•  Selectors don’t have to be declared in the header, but won’t be
   visible to other classes unless they are
•  Variables are never visible to other classes
  •  Headers are just for declaring “global” variables
  •  Getters and setters are required to access variables from other classes
Interface/Implementation Example
       Header (XY.h)                    Implementation (XY.m)
                       superclass

@interface MyClass:NSObject	        static BOOL saveMe=YES;	
                                    	
{	
                                    @implementation MyClass	
   NSInteger myInt;	                	
}	                                    -(void)myFunction	
	                                     {	
                                      }	
//forward declare func	             	
-(void)myFunction;	                   +(CGFloat)classFunction	
	                                     {	
                                          return 1.0f;	
//static class func	
                                      }	
+(CGFloat)classFunction;	           	
@end	                               @end
Import and @class Directive
•  Headers must be imported when needed
•  Because every header imports it’s own headers, importing headers
   within headers leads to memory problems and long compilation times
•  Frameworks are imported with <> instead of quotes
•  Use @class directive when possible to tell a header you’ll import the
   other header in the implementation

#import <CoreData/CoreData.h> //Framework	
#import “myHeader.h”	
@class someClass; //“I’ll import someClass later”	
@interface myViewController:UIViewController	
{	
      someClass *test;	
}	
@end
Class Extensions
•  In addition to creating a class derived from another class, you can
   modify existing classes with class extensions
•  Specify class you’re extending in the interface:
•  Syntax for a class extender for UIImage called “Pixels”
        "@interface UIImage (Pixels)!
        "@end!
!
        "@implementation UIImage (Pixels)!
        "@end!
•  If you create a class using the File menu, the template will crate a
   class extension at the top of the .m file – comes in handy but not
   necessary
        "@implementation myClass ()
•  Common convention for class extender file name:
    •  UIImage+Pixels.m
    •  UIImage+Pixels.h
!
Class vs. Object Methods
•  “-” before a method means it’s an object method
•  “+” before a method means it’s a class method
    •  Class messages are statically allocated when class is created
    •  Commonly used for a custom alloc and init
•  Same concept as local/global functions in C++


•  Example, for class “myClass” (methodàmessage):
+(void)test{} à [myClass test]	
-(void)test{} à myClass *obj; [obj test]
Objective C “Messages”
•  In Obj C you “send messages” to objects to run methods
•  Comparison syntax:
   •  Send message “method” to myclass in Obj C:
        	[myClass method]	
   •  C++ and Java equivalents:
        	mClass->method()                myClass.method()	
   •  Objective C 2.0 (introduced in 2007) allows use of dot notation
     •  Examples in stack overflow will be mixed
     •  In my experience developers tend to use dot notation for getters,
        standard syntax for everything else
     •  I don’t recommend too much dot notation as it hides what’s happening

•  “Selector” = signature of a method
    •  Eg: Selector for [view initWithFrame:frame] is “initWithFrame:”
Passing Objects in Messages
•  Only primitives can be passed
                                          Would be referred to as selector
   •  Objects are passed using pointers
                                          “selectorWith:andAlso:”
•  Example Message:
   oClass *obj1;	
   oClass *obj2;	
   [myClass selectorWith:obj1 andAlso:obj2]
•  Example Function:
    (void)selectorWith(oClass*)o1	          Functions in objC are
       	andAlso:(oClass*)o2	                usually very descriptive,
                                            but the words before the
       	{

                                            parameter is not
       	}	                                  necessary (only need
   	                                        spaces)
Cool Thing About Nil References
•  Sending a message to an object with a nil reference just returns nil
•  This can cause some headaches, though, because code will run if object
   not allocated
•  If a class might be nil it’s safer to send a message to that class if the
   alternative is to pass a nil object to another class in a message to it
   (which crashes a lot of methods)
  •  Example:
        safe: [view2 removeFromSuperview] //just returns nil if view2=nil	
        not safe: [view removeSubView:view2] //could crash if view2=nil

        (note: there is no removeSubView method for this reason)
	
if ([myClass skyIsBlue]) {	
   /*	
    true if sky is blue	
    false if sky is not blue or myClass = nil	
   */	
}
Common Nil Reference Mistake
UIButton *tBut; //just a pointer; nothing created	
//this will not generate errors	
[tBut setTitle:@"test”	
     	forState:UIControlStateNormal];	
	
	
//what’s missing – need to point to something:	
UIButton *tBut =	
     	[[UIButton alloc] init];	
[tBut setTitle:@"test”	
     	forState:UIControlStateNormal];
Objective C Object Declaration
•  Standard steps are:
   •  Allocate Memory
   •  Initialize object
•  Syntax:
       	myObj *pointer = [[myObj alloc] init];	
•  Many standard classes have a class method that does both
 steps, ex:
      	UIButton *t = [UIButton	
      	     	buttonWithType:UIButtonTypeCustom]	
      	UIColor *color = [UIColor redColor];
Standard Init Methods
•  Unlike in managed code, objective c objects always have to be
   initialized (memory starts out as random bits)
•  NSObject uses the selector “init” for this, which can be
   overridden as necessary. Always follow this form:

-(id)init	
{	
   self = [super init];	
      if (self) {	
     	 //your stuff here	
     	 //only run if super initialized ok	
      }	
   return self;	
}
Creating Custom Init Methods
•  You don’t have to use provided init selector:

-(id)createClassWithHelloString:	
        	(NSString*)helloS	
{	
    self = [super init];	
        if (self) {	
        	 NSLog(@”Hello String: %@”,helloS);	
        }	
    return self;	
}	
	
•  Views have initWithFrame:
•  Controllers have initWithNibName:bundle:
Objective C Heap Memory Management
•  Objects on heap need to be accounted for and
   deallocated as necessary
•  3 Options for Cocoa Touch:
 •  Allocate and release memory manually
      	[myObj release];
 •  Add objects to autorelease pool
    •  Autorelease pool retains objects until program exits or when it’s
     manually drained
     	[myObj autorelease];	
 •  Use Automatic Reference Counting


Note: Cocoa for OSX does have a GC, but we won’t be
discussing it here
ARC (Automatic Reference Counting)
•  Introduced in 2011
•  Supercedes manual reference counting
•  Retains objects that have “owners” (strong pointers to
   object)
•  Only works with classes derived from NSObject (not
   foundation classes or anything based on C)
  •  Release other classes manually using release() and CFRelease()
•  Automatically deallocates objects with no owners
•  Can still compile individual classes without ARC:
        -fno-objc-arc flag (not common)
More Notes Regarding ARC
•  Reasons not to use it:
   •  Releasing yourself can help eliminate memory problems
    •  ARC does not allow use of release and autorelease in code
  •  Easy to create memory leaks
  •  ARC can take a few ms to a second to release objects
    •  Program can run ok during one test and crash during the next
    •  Easy to miss problems and have them show up later




•  I will only be using ARC in my examples
Releasing an Object in ARC
•  Set all owners of an object (strong pointers) to nil. Once
 the object is floating and has zero owners ARC will grab it.

  //allocate the view
  UITableView *myTable = [[UITableView alloc] init];

        *myTable
                              UITableView Object
         pointer

  myTable = nil;

        *myTable                                       Object has zero
                              UITableView Object       owners now, so
         pointer
                                                       ARC will reclaim
ARC vs. Garbage Collection
               ARC                          Garbage Collection
Managed        Not managed. ARC is          Managed. Part of OS that
               code added at compile        watches objects on the heap.
               time, so very little         Can lead to performance
               overhead required            problems if too many objects
                                            are allocated.
Persistence    Objects are released as      Objects are released as
               soon as there’s no           required to free up memory
               pointer to them. Need to
               be very careful about
               keeping track of
               pointers.
Memory Leaks   Prone to memory leaks        Less prone to memory leaks as
               if there are pointers that   objects that are no longer
               are unreachable in code      being used will be released
                                            eventually
Memory Leaks in ARC
•  Most common cause of a leak is through a retain cycle
•  With ARC you might not have to release but setting pointers to nil is important

     Obj 1                        Obj 2                     Obj 3          All objects have
                                                                           owners and are
 *obj2 = 0x1                   *obj3 = 0x2               *obj2 = 0x3       retained


                                                                           Obj 2 will be
     Obj 1                        Obj 2                     Obj 3          released (no
                                                                           owner), then
  *obj2 = nil                  *obj3 = 0x2               *obj2 = 0x3       Obj 3 (no
                                                                           owner once Obj
                                                                           2 is gone)
Retain Cycle

     Obj 1                        Obj 2                     Obj 3          Neither Obj 2
                                                                           nor 3 will be
  *obj2 = nil                  *obj3 = 0x2               *obj2 = 0x3       released as
                                                                           they both own
                                                                           eachother
Using Weak References
•  Unlike strong references, weak references do not imply ownership
•  Create by adding “__unsafe_unretained” before pointer declaration
  •  Used to be “_weak”
•  Need to be very careful with this – no guarantees against null references
  •  Most times it’s better to just use strong references and break them when necessary
  •  Some collection classes (NSMapTable) are weak by default


    Obj 1                           Obj 2                       Obj 3
                                                                                 All objects
 *obj2 = 0x1                     *obj3 = 0x2                 *obj2 = 0x3         are retained




    Obj 1                           Obj 2                       Obj 3
                                                                                 Obj 2 then 3
 *obj2 = 0x1                     *obj3 = 0x2                 *obj2 = 0x3         will be
                                                                                 released
Code Example – Objects and Memory
//what's the problem here???!
//(assume this is not on the main thread)!
!
-(void)testAlert!
{!
    UIAlertView *alert =!
     "      "[[UIAlertView alloc] init];!
    [alert setTitle:@"Hello!"];!
    [alert addButtonWithTitle:@"Log Awesomeness"];!
    [alert addButtonWithTitle:@"Close"];!
    [alert setCancelButtonIndex:1];!
    [alert setDelegate:self];!
    [alert show];!
}
Released too soon!
•  This is a common type of problem created through ARC:
   1.  [alert show] tells the main thread to draw the alert box
   2.  If started from another thread (like in a block somewhere) that
        means it happens asynchronously
   3.  So while the box is still drawing, the function ends, the frame
        objects are released, and there are no more owners of “alert”
   •  ARC comes and releases the object before we’re done using it
   •  Resulting behavior can be erratic:
    •  In most cases the program will crash
    •  In some cases if ARC is fast enough the alert box won’t show
    •  When ARC is slow everything might run fine
       •  Users in the app store start complaining – your app is crashing!
Example Crash


                  EXC_BAD_ACCESS
                  There is nothing here




                Probably the last
                frame saved just
                before the crash
                (pointer not nil yet)
Getters and Setters (Accessors)
•  Methods to access variables from outside a class
•  Naming is by convention:

int myVariable;	                              Setters usually
	                                             start with “set”.
                                              Underscore is only
-(void)setMyVariable:(int)_myVariable	
                                              meant for
{	                                            synthesized
   myVariable = _myVariable;	                 setters, but
}	                                            everyone uses
	                                             them anyway.
-(int)myVariable	        getters usually
                                              **This example is
{	                       have the same
                         name as the          nonatomic
   return myVariable;
   variable
}
Accessing Getters and Setters
•  Dot notation follows the conventions
                                          Both are valid:
 -(void)setMyVariable:	
       	(int)_myVariable	           [class setMyVariable:1];	
 {	                                 class.myVariable=1;	
    myVariable = _myVariable;	      	
 }	


 -(void)myVariable:	
 {	
                                    [class myVariable];	
    return myVariable	              class.myVariable;	
 }
Notes Regarding Dot Notation
•  Depends on developer
•  Most objective C samples I’ve seen follow this:
   •  Brackets are used in majority of cases
   •  Dot notion is used for getters, but not setters
   •  Dot notation is used when you have a ton of brackets
   •  This is not a convention by any means

  [[self window] setRootViewController:	
     	[UIViewController alloc] init]];	
  //Becomes	
  self.window.rootViewController =	
     	[[UIViewController alloc] init];	
  //Or most commonly	
  [self.window setRootViewController:	
     	[UIViewController alloc] init]];
Be Careful:
 //say object is at 0xA123	
 //test.object1 points to 0xA123	
test.object1 = [[myClass alloc] init];	
 //test.object2 now points to 0xA123 also	
test.object2 = object1;	
 //both set the color of the object at 0xA123	
[test.object1 setColor:[UIColor whiteColor]];	
[test.object2 setColor:[UIColor whiteColor]];	
  //this has no impact to object1, just changes	
  //the pointer for object2 to something different	
test.object2=[[myClass alloc] init];	
 //traditional notation is a little clearer	
[test setObject2:[[myClass alloc] init];
Synthesizing Getters and Setters
         Header (XYClass.h)                Implementation (XYClass.m)

 @interface MyClass	                     @implementation
 	                                            	MyClass	
 @property (atomic,                      	
      	readonly)	                        @synthesize	
   NSString *myProperty;	                    myProperty;	
 	                                       	
 @end	                                   @end	

•  atomic = all or nothing (better for   •  Synthesize actually creates the
   threading) – see NSLock                  getter, setter and the variable – if
•  nonatomic = partial writing of           you forget “synthesize” the variable
   variables can happen                     won’t exist but the program can run
•  readonly = just create getter         •  Note: You still need to initialize the
                                            variable – synthesize won’t do that
Custom Accessors
•  Can either synthesize and replace (if nonatomic) or just create
   your own
•  See NSLock for thread locking atomic implementation (atomic is
   slower but probably not by much)

@synthesize myProperty; //create both getter and setter	
	
//override getter:	
-(NSString)myProperty	
{	
    //if there’s no object pointed to, make one	
    if (!myProperty) myProperty =	
      	[NSString stringWithUTF8String:"hi!"];	
      	//note: this is equivalent to myProperty = @"hi!"	
    return myProperty;	
}
Structs
•  Group of primitives that are created together
   •  Usually on the stack unless allocated with an object
•  Members accessible through dot notation
•  Commonly used in Cocoa (ex. CGRect)

typedef struct {	
    NSInteger myInt;	
    CGFloat myFloat;	
} myStruct;	
	
myStruct test;	
test.myFloat = 1.0f
Static Variables
•  Static variables are allocated at runtime
•  Shared between classes
•  Use for constants
   •  Preferred over compiler macros
   •  Unlike macros will be seen by debugger
•  Possible to assign values to static variables in
 implementation file, but not in header


static CGFloat test=1.0f;
NSLog
•  Extremely useful debugging tool – sends to app log
•  Following conventions from C’s printf:
   •  %d = integer
   •  %f = float, double
   •  %p = pointer
•  printf works with const char* - NSLog uses NSString
   •  printf(“test %d”,1);
   •  NSLog(@“test %d”,1);
•  %@ will also call the description function of an object
   •  NSLog(@”test string %@”,myString);
   •  [myString description] returns string itself
   •  Other objects might return more details
Delegates
•  Delegate classes correspond to a protocol
•  Any class can be declared as a delegate
   •  Add <delegate name> after name of superclass in header
•  Protocols contain necessary functions to run certain things
	
//set self as a delegate for the table view	
[myTableView setDelegate:self]	
	
//this function defines the table row height	
-(CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath	
{	
   return 3.0f;	
}
C Pre Processor Macros
•  Used to insert values before code is compiled


•  Simplest form:
   •  #DEFINE PI 3.14f;
   •  Everywhere in the code where “PI” is used replaced with 3.14f


•  Can be used for simple functions:
   •  Included a lot in frameworks
   •  Example: The “MIN” macro:
  #if !defined(MIN)	
      #define MIN(A,B) ({ __typeof__(A) __a = (A);	
       	__typeof__(B) __b = (B); __a < __b ? __a : __b; })	
  #endif
Static (Singleton) Classes
•  There is actually no way to make a singleton class in Obj-C
   •  All classes in Obj-C are allocated dynamically
•  Common method is to create a static pointer and reference that
 using a class function:

+(EXSingleton*)getSingleton {	
    static EXSingleton *getSingleton= nil;	
    if (!getSingleton) {	
        getSingleton = [[super allocWithZone:nil] init];	
    }	
    return getSingleton;	           Alloc calls allocWithZone, so
}	                                  overriding this is just a way of
	                                   getting the normal alloc method
+(id)allocWithZone:(NSZone *)zone{	 to return the singleton – it’s not
    return [self getSingleton];	    100% necessary. You can just
}	                                  call [myClass getSingleton] to
                                    get/create the singleton
Blocks
•  Use to pass function with variable frame values from one
   selector to another
•  Very common with asynchronous functions
•  How to define:
    typedef void (^blockName)(blockParam* pName);	
    typedef void (^blockName)(void); //no params	
    //blockName can now be passed like a variable	
•  Where you’ll need it (ex. defining what happens after pushing a
 new view controller onto the stack)
      	[self presentViewController:coolViewController	
      	     	animated:NO completion:^{	
      	     	      	//put code to be run	
      	     	      	//at completion here	
      	     	}];
Referencing Selectors
•  Use @selector(selectorName:) syntax to reference
   selectors
•  Used in timers, multi-threading, etc to fire a selector
•  Don’t forget to colons for each parameter passed to the
   selector or the app will crash (invalid signature)!!!

NSThread *newThread = [[NSThread alloc]!
    initWithTarget:self!
    selector:@selector(mySelector:)!
    object:nil];!
!
//Points to:!
-(void)mySelector:(id)testObject {}
COCOA TOUCH
PROJECTS
MVC – Model View Controller
•  Model = “Stuff in background”
   •  Creates notifications
   •  Provides data
   •  Doesn’t know anything about user, GUI, etc
•  View = Visual / GUI elements
   •  Same concept in Android
   •  No knowledge of what they’re displaying just how to display it
•  Controller = Logic
   •  Coordinates between model and view objects
   •  Similar to activities in Android
   •  Several different methods of pushing controllers onto a stack
Starting Your Project
•  File > New Project




                        Stick to these
Add Options

                  If you’re a
                  developer this
                  should match
                  your account



                This can be
                added later



              Check this
Necessary Files
•  main.m (required)
   •  Creates the run loop (the main thread)
   •  Usually creates the autorelease pool for ARC
•  App Delegate (required)
   •  Usually named “XYAppDelegate.m, XYAppDelegate.h”
   •  Contains delegate functions called by OS to:
    •  Create GUI after launch: application:didFinishLaunchingWithOptions:	
    •  Go to sleep: applicationDidEnterBackground:	
    •  Exit program: applicationWillTerminate:	
    •  Etc.

•  Main View Controller
   •  Usually named “XYViewController.m, XYViewController.h”
   •  Necessary to display something
Key GUI Elements
                                 Controls content in right pane
•  3 Panes:   Controls content in left pane
How Projects are Organized
•  All files are in a single folder
•  Things that look like folders are actually “groups”



                                            Group




                                        Startup Images
Key Graphics Concepts
•  Startup images are displayed when an app is starting
   •  Not recommended for use as a splash screen – amount of time
      they’re displayed varies (Apple recommends a screenshot)
•  Graphics for standard and retina displays can be mixed:
   •  Use normal image names for standard
   •  Add “@2x” to retina images – app will find them
•  Screen resolution for retina is double that of standard
   •  Point size comes from standard but with a screen scale of 2
   •  Eg:
                               iPhone 3G/3GS   iPhone 4
           Screen resolution   320 x 480       640 x 960
           Screen points       320 x 480       320 x 480
           Screen scale        1               2
IB and NIB/XIB Files
•  Interface Builder (IB) is a way of graphically laying out views to be
   used by a view controller
•  XIB is XML version, NIB is compiled (same concept as XAML)
•  Linked to a class, but not an object – if a view controller is initialized
   with a nib it’ll map to the nib as required
•  Views can also be created from a NIB
  •  But be careful as this is usually not efficient (you’re loading and interpreting a
     file every time)
  •  Never ever ever EVER create table view cells from a NIB
  •  Could be useful for laying out something like a tip window
•  I stay away from IB – I find it’s more reliable to lay out views
 programmatically
  •  IB won’t handle complex changes between portrait and landscape
  •  When the iPhone 5 came out all of my apps scaled automatically
•  Two non-obvious advantages IB
    •  Apple’s human interface guidelines are built in
    •  You can include key-value pairs in views
Linking NIBs to view controllers
•  First must set “File’s Owner” to the class you’re using it for (eg. ExViewController)
•  Linked to view/view controller through IBOutlet property
•  Actions can be linked through IBAction, but just as easy to do programmatically




                                This connection is made when the class is initialized
                                with the NIB (if there’s no NIB loaded it’s not made)
Breakpoints and Frames
 •  Breakpoints can be symbolic or exception
   •  Possible to break on all exceptions if desired
                                                       Breakpoint
 •  Frame is shown at breakpoint

Threads




                                                                    gdb debug
                                                                    shell

                                                                    Stack frame
iOS Simulator / Schemes
•  Not an emulator
   •  Apps are compiled for x86
   •  Different versions of iOS can be added
    •  Go to preferences > components to add

•  Use schemes to:
   •  Add debuggers
   •  Add launch arguments
Logs                                    Logs

•  Records output
 from:
  •  Compiler
  •  NSLog
  •  OS
  •  Other debugging
    tools
•  All logs
 throughout a
 single XCode
 session are
 saved
                       Current output
                       window
Frameworks
•  Frameworks can be added as necessary to any
 implementation or header and won’t throw an error:
         <CoreData/CoreData.h>	
•  Frameworks still need to be linked to the project
    •  If they’re used but not linked, you’ll get a linker error when trying to
       compile
•  To add a framework, go to:
    •  Target > Summary > Linked Frameworks




  •  Or Target > Build Phases > Link Binary with Libraries
Help
•  2 Sources:
   •  Quick help (in right pane)
     •  Easy to inspect framework headers
       (very useful)
  •  Detailed help (in organizer)
     •  Can get to detailed help from quick
        help
     •  Definitely not as good as MSDN – no
        short code examples, just sample
        projects
     •  Most useful section is the list of
        selectors


                                              Go to organizer
                                              help
Organizer
•  Contains documentation (help), archives and device
   management
•  Use Devices tab to copy provisioning profiles to devices
   for testing, or enable testing on certain devices
•  Create archives to upload to the app store or for ad-hoc
   distribution
•  Delete derived data in projects to fix problems (contains
   pre-compiled headers)
  •  Can also go to Product > Clean
KEY COCOA CLASSES
NSString/NSMutableString
•  Objective C classes for holding and manipulating unicode
   strongs
•  NSString is always static
•  Using shorthand @”” declares an NSString using UTF8
   characters
NSDictionary/NSMutableDictionary
•  Collection classes
   •  Own objects they contain
•  NSDictionary – can’t change
•  NSMutableDictionary – can change
•  Hold lists of pointers – can contain any object
•  Similar to arrays, but access value by key not index
   myDict = [[NSMutableDictionary alloc] init];	
   [myDict valueForKey:@”test”]	
   [myDict setValue:myClass forKey:@”test”]
Arrays / Sets
•  Collection Classes
   •  Own objects they contain
•  NSArray, NSSet – can’t change
•  NSMutableArray, NSMutableSet – can change
•  Hold lists of pointers – can contain any object
•  Arrays: values accessible by index
   myArr = [[NSMutableArray alloc] init];	
   [myArr objectAtIndex:1]	
   [myArr setObject:myClass atIndexedSubscript:1]	
•  Sets just hold non-indexed collections of objects
   •  Used for core data stores
   •  Use whenever you don’t need an index (significantly faster)
    •  Eg. holding pointers to retain them
Fast Enumeration
•  All collections support fast enumeration:


for (NSString* checkString in stringArray) {	
      if ([checkString isKindOfClass: 	
    	    	[NSString class]) {	
    	    	NSLog(@”it’s a string!”);	
      }	
}	
                                       Always smart to
                                       check classes
                                       when using fast
                                       enumeration
UIViewController
•  Root class that all view controllers are based on
•  Generally override initWithNibName:bundle to init
•  Use to push view onto the view controller stack:
   -(void)presentViewController:(UIViewController
   *)viewControllerToPresent animated:(BOOL)flag
   completion:(void (^)(void))completion	
•  Use to remove self from the view controller stack:
   -(void)removeFromParentViewController	
•  UINavigationController can also be used with a view
 controller to manipulate the stack (creates the
 standardized looking toolbars on the top and bottom of the
 screen)
NSNumber / NSValue
•  Objective C collections (and other classes) are based on
   pointers, so they can’t store primitives
•  NSNumber can hold any type of numeric value in an
   object wrapper and contains other functions for converting
   strings to numbers, etc.
•  NSValue serves the same purpose, but it’s just a wrapper
   for primitive values
Some GUI Views
(all derived from UIView)
UIView               Root class for views
UIButton             Button
                     (use class selector [UIButton
                     buttonWithType:] to init)
UIImageView          View for displaying UIImage
ULlabel              Simple text label
UITextField          Field for editing text
UIScrollView         Scrolling window view
UITableView          Creates a table (only contains
                     UITableViewCell objects as rows – no
                     columns)
UITableViewCell      Creates table cells for UITable
NSURL / Downloading Internet Data
•  Use NSURL to link to a URL
       "NSURL *postURL = [NSURL URLWithString:!
       "@"http:www.google.com/image.jpeg"];!
•  Use NSURLRequest (or mutable) to set up a net request
        "NSMutableURLRequest *request = "!
        "[NSMutableURLRequest requestWithURL:postURL!
        "cachePolicy:NSURLCacheStorageNotAllowed!
        "timeoutInterval:60.0];!
•  Send an asynchronous (or synchronous) request
        "[NSURLConnection sendAsynchronousRequest:request!
        "queue:[NSOperationQueue mainQueue]!
        "completionHandler:^(NSURLResponse *response,!
        "NSData *data, NSError *error) {!
        "      "if (error) {}!
        "      "//downloads to NSData; add your stuff here!
        "}];
BASIC COCOA
PROGRAMMING WITH IB
Adding a View Controller & Nib
•  Add an Obj C class derived from UIViewController
•  Select “With XIB for user interface”
•  Alternatively – add a User Interface with a UIView
The XIB Owner and First Responder
•  The owner is the class that will own the NIB
   •  Example: “EXViewController”
•  The first responder is the object that receives an action
   •  Example: A view you click on
   •  If the responder doesn’t handle the event it propagates down the
      responder chain:
    •  View > View Controller > Window > Application
  •  You can change the first responder, but it’s usually not necessary
Setting the Owner
•  Click on “File’s
   Owner” in the XIB
   window
•  Select the
   property
   inspector on the
   right pane
•  Change the class
   to your view or
   controller that the
   Nib will be
   dropped into
  •  Example:
    EXViewController
Add Views to the NIB
•  Drag views from objects in right pane
•  Use guides to stick to Apple’s Human Interface Guidelines
Connecting Views to the Controller
•  Open an assistant
   editor window (the
   guy in the tux) to
   have something to
   drag views to
•  Close the right pane if
   necessary to make
   space
•  Open the header of
   your view controller in
   the assistant window
   and the xib in the
   main window
•  Drag the views into
   the header of your
   view controller while
   holding down
   command
Creating an IBOutlet and IBAction
•  After dragging, name the item and add an outlet/action
•  An outlet creates a property with a pointer to the object
•  An action creates a selector that’s called through interaction
 with the object (eg. Touch Up Inside, Touch Down)
IB Code Added
•  IBOutlet *testButton pointer points to the button created
   by the nib
•  IBAction touchButton adds code to the header and
   implementation that can be used to add code when the button is
   pressed




        Filled in circle means this
        outlet is connected to
        something in the nib
Adding an Action to the Button
•  Assume we’ve added an IBOutlet property for the label as well
   – UILabel *testLabel
•  Pressing the button will set the label text to “Hello World” and
   the view controller’s view to a red background

•  @implementation EXViewController!


•  - (IBAction)touchButton:!
           (UIButton *)sender {!
     [self.testLabel setText:@"Hello World"];!
      [[self view] setBackgroundColor:!
     "     "[UIColor redColor]];!
}
Loading The Nib After App Launch
   //Note: This is all in the single window template…	
   //1. Import ExViewController.h into the app delegate	
#import "EXViewController.h"	
   //2. Use delegate application:didFinishLaunchingWithOptions	
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {	
   //3. Create a UIWindow to display the app in	
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen
mainScreen] bounds]];	
   //4. Create the root view controller & add the nib name (no	
   //   extension or leave nil for no nib (can also just use "init")	
myViewController *rootViewController = [[myViewController alloc]
initWithNibName:@"myNib" bundle:nil];	
   //5. Set the UIWindow’s rootViewController property to it	
window.rootViewController = rootViewController;	
   //6. Set the UIWindow as the key window	
[self.window makeKeyAndVisible];	
}
Result




         Press
         Button
COCOA PROGRAMMING
WITHOUT USING IB
Reasons Against Using IB
•  IB is slow
    •  Nib has to be loaded and interpreted to create layout
•  Only provides benefits for starting layout
    •  You’ll end up writing code to manipulate all of the views anyway
•  Easy to break links to Views
•  Lack of flexibility for rotations
    •  Pretty much have to stick to the standard automatic layout properties –
       can’t have two complex layouts
    •  I have trouble getting the auto layout properties to work the way I want
       them to, but that might just be me (there are books on the subject)
•  Need different Nibs for both iPad and iPhone
•  What happens if the screen size ever changes?
    •  When the iPhone 5 came out my apps all scaled fine
    •  Still an unreasonable number of apps in the app store that have black
       bars on the bottom and top of the iPhone 5 window
•  I don’t use it… so I can’t teach you much about it
View Frames
•  Every view has a frame to set the location and size
•  The frame is stored in/set using a CGRect structure, which
 contains a CGPoint specifying the origin and a CGSize
 specifying the frame size
    struct CGRect {	
        CGPoint origin;	
        CGSize size;	
    };	
    struct CGPoint {	
        CGFloat x;	
        CGFloat y;	
    };	
    struct CGSize {	
        CGFloat width;	
        CGFloat height;	
    };
View Frame Example
//graphics in iOS are usually	     origin.y
//done with floats, not ints	
//remember these are structs	
//so must use dot notation	
	
CGPoint origin;	
     	origin.x=10;	




                                                   size.height
                                         view
     	origin.y=20;	
                        origin.x
CGSize size;	
     	size.width=100;	
     	size.height=200;	
CGRect frame;	
     	frame.origin=origin;	
                                    size.width
     	frame.size=size;	                          superview
More on CGRect
•  CGRectMake can be used to make a CGRect in one line
   CGRect CGRectMake (	
        CGFloat x, CGFloat y,	
        CGFloat width, CGFloat height	
   );
   •  Also see CGPointMake, CGSizeMake
•  CGRectZero is a frame of all zeros
   •  A view make with CGPointZero would not be visible
   •  Also see CGPointZero, CGSizeZero
•  CGRects are structures not objects, so you can make copies
 using dot notation. But on a view they’re read only so you need
 to use a setter to set the entire frame at once (the superview
 redraws it’s subviews when a new frame is set)
  CGRect newFrame = obj1.frame;	
  newFrame.height+=100;	
  [obj2 setFrame:newFrame]; //or obj2.frame=newFrame;
Adding a View With a Frame
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil	
{	
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];	
    if (self) {	
        	//helpful to set a pointer to the controller’s view but not necessary	
        UIView *selfView = [self view];	
        CGRect selfFrame = [selfView frame];	
        CGRect textFrame = selfFrame;	
        	//this is the size of our text box	
        textFrame.size = CGSizeMake(100, 100);	
        	//some basic math to center it in the screen	
        textFrame.origin =	
        	         	CGPointMake((selfFrame.size.width-textFrame.size.width)/2,	
                              (selfFrame.size.height-textFrame.size.height)/2);	
        UITextView *textBox = [[UITextView alloc] initWithFrame:textFrame];	
        	//add some attributes	
        [textBox setText:@"Hello World"];	
        [textBox setBackgroundColor:[UIColor colorWithWhite:0.8f alpha:1.0f]];	
        	//don’t forget to add the textbox as a subview!	
        [selfView addSubview:textBox];	
    }	
    return self;	
}
Helpful Tip – Don’t Set Frames In Init
•  Make it easy to redraw views when calculations change
   •  Example: Screen rotation (note: you can also use autorotation, but
      I find that it’s never easy to get it working perfectly)
•  For init just set all frames to CGRectZero
•  For view controllers create a selector like “CreateFrames”
 and call it at the end of init
  •  Now you can call it again whenever you need to
•  For views, just override the view’s setFrame: selector
   •  Note: Don’t forget to call the super’s setFrame: selector also or the
      view won’t redraw frames properly
Adding Targets to Views (eg. Buttons)
- (id)initWithNibName:(NSString *)nibNameOrNil!
       "bundle:(NSBundle *)nibBundleOrNil {!
    self = [super initWithNibName:nibNameOrNil!
       "bundle:nibBundleOrNil];!
                                                target = object to send message to
    if (self) {!
       "testButton = //declared in interface!
       "        "[UIButton buttonWithType:UIButtonTypeCustom];!
         [testButton setFrame:CGRectZero];!
         [testButton setTitle:@"Test" forState:UIControlStateNormal];!
         [testButton addTarget:self action:@selector(mySelector:)!
              forControlEvents:UIControlEventTouchDown];!
       "[self setFrames]; //my own method to set view frames!
       "[[self view] addSubview:testButton];!
       "}!
    return self;!
                                                           2013-03-31 14:58:33.307
}!                                                         Example[2825:c07] I
                                                             pressed button
-(void)mySelector:(id)buttonObject {!                        <UIButton: 0x8868510;
    NSLog(@"I pressed button %@",buttonObject);!             frame = (10 10; 100
                                                             100); opaque = NO;
}                                                            layer = <CALayer:
                                                             0x8868640>>
Adding Actions to Views Without Targets
•  Two common options:
   •  UIGestureRecognizer
     UISwipeGestureRecognizer *recognizer;!
        recognizer = [[UISwipeGestureRecognizeralloc]!
            initWithTarget:self!
            action:@selector(handleSwipeFrom:)];!
        [recognizer setDirection:!
            (UISwipeGestureRecognizerDirectionRight!
                | UISwipeGestureRecognizerDirectionLeft)]
  •  Overriding touch selectors
     •  Every view contains touch tasks. See UIResponder documentation for
      more info (UIView inherits from UIResponder). Examples:
       •  touchesBegan:withEvent:
       •  touchesMoved:withEvent:
    •  Note: Gesture Recognizers can cancel touches
        •  Set cancelsTouchesInView property
APP EXAMPLE
GPS Tracker
Create the Project
Create A Root View Controller
Add A View Controller Property To The
App Delegate
//!
//    GTAppDelegate.h!
//    GPSTracker!
//!
//     Created by Louis Loizides on 3/31/13.!
//     Copyright (c) 2013 Louis Loizides. All rights reserved.!
//!

#import <UIKit/UIKit.h>!

@class GTViewController;!
@interface GTAppDelegate : UIResponder <UIApplicationDelegate>!

@property (strong, nonatomic) UIWindow *window;!

// Don’t forget to synthesize this in the implementation!!
@property (nonatomic) GTViewController *rootViewController;!

@end
Create The View Controller
//!
// GTAppDelegate.m!
// GPSTracker!
#import "GTAppDelegate.h"!
#import "GTViewController.h"!

@implementation GTAppDelegate!
@synthesize rootViewController;!

- (BOOL)application:(UIApplication *)application!
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions!
{!
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];!
    // Override point for customization after application launch.!
    rootViewController = [[GTViewController alloc] initWithNibName:nil bundle:nil];!
    [self.window setRootViewController:rootViewController];!
    !
    self.window.backgroundColor = [UIColor whiteColor];!
      [self.window makeKeyAndVisible];!
    return YES;!
}
Add Core Location Framework
 Go to
 Targets >
 GPSTracker >
 Frameworks
Add Pointers for Views,
CoreLocationManager and set Delegate
//   GTViewController.h!
//   GPSTracker!
!
#import <UIKit/UIKit.h>!
#import <CoreLocation/CoreLocation.h>!

@interface GTViewController : UIViewController!
    <CLLocationManagerDelegate,UITextFieldDelegate>!
{!
    UIButton *startStopButton;!
    UILabel *latLabel;!
    UILabel *lonLabel;!
    UITextField *latField;!
    UITextField *lonField;!
    CLLocationManager *locationManager;!
    BOOL isUpdating;!
}!

@end
Create Objects in Root View Controller
Implementation
-(id)initWithNibName:(NSString *)nibNameOrNil!
        "bundle:(NSBundle *)nibBundleOrNil {!
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];!
    if (self) {!
        latLabel = [[UILabel alloc] initWithFrame:CGRectZero];!
        lonLabel = [[UILabel alloc] initWithFrame:CGRectZero];!
        latField = [[UITextField alloc] initWithFrame:CGRectZero];!
        lonField = [[UITextField alloc] initWithFrame:CGRectZero];!
        startStopButton = [UIButton buttonWithType:UIButtonTypeCustom];!
        [startStopButton setFrame:CGRectZero];!
        [startStopButton addTarget:self action:@selector(startStop:)!
               forControlEvents:UIControlEventTouchDown];!
        [[self view] addSubview:latLabel];!
        [[self view] addSubview:lonLabel];!
        [[self view] addSubview:latField];!
        [[self view] addSubview:lonField];!
        [[self view] addSubview:startStopButton];!
        locationManager = [[CLLocationManager alloc] init];!
        [locationManager setDelegate:self];!
        [self createFrames];!
        isUpdating=NO;!
        [self startStop:nil]; //use to set the first start/stop title!
    }!
    return self;!
}
Add Some Style Stuff
/*!
Put this in init method!
Note: text fields are used for values instead of labels!
      "to allow cut and paste, but I really just wanted!
      "to have a couple of view examples here!
*/!
[[self view] setBackgroundColor:[UIColor lightGrayColor]];!
[latLabel setBackgroundColor:[UIColor clearColor]];!
[latLabel setTextAlignment:NSTextAlignmentCenter];!
[latField setBackgroundColor:[UIColor whiteColor]];!
[latField setTextAlignment:NSTextAlignmentCenter];!
[lonLabel setBackgroundColor:[UIColor clearColor]];!
[lonLabel setTextAlignment:NSTextAlignmentCenter];!
[lonField setBackgroundColor:[UIColor whiteColor]];!
[lonField setTextAlignment:NSTextAlignmentCenter];!
[latLabel setText:@"Latitude"];!
[lonLabel setText:@"Longitude"];!
Add a UITextFieldDelegate
//Get rid of the editing view on the UITextFields!
//so the keyboard doesn’t appear and set the!
//delegate to the view controller!
[latField setDelegate:self];!
[lonField setDelegate:self];!
[latField setInputView:[[UIView alloc] init]];!
[lonField setInputView:[[UIView alloc] init]];!
!
//Add a delegate function to prevent editing!
-(BOOL)textField:(UITextField *)textField!
     "shouldChangeCharactersInRange:(NSRange)range!
     "replacementString:(NSString *)string{!
    return NO;!
}
Add the Start/Stop Method
-(void)startStop:(id)sender!
{!
    if (!isUpdating && sender) {!
         [locationManager startUpdatingLocation];!
         [latField setText:@""];!
         [lonField setText:@""];!
         [startStopButton setTitle:@"Stop”!
       "        "forState:UIControlStateNormal];!
         isUpdating=YES;!
    }!
    else {!
         [locationManager stopUpdatingLocation];!
         [latField setText:@"Stopped"];!
         [lonField setText:@"Stopped"];!
         [startStopButton setTitle:@"Start”!
       "        "forState:UIControlStateNormal];!
         isUpdating=NO;!
    }!
}
Add A Function To Set Frames
-(void)createFrames!
{!
    CGRect vF = [[self view] frame];!                             Start with application
    CGFloat fontHeight = [[latLabel font] pointSize];!
    !                                                             frame or view frame
    CGRect latLabelFrame=vF;!
    latLabelFrame.size.width/=2;!
    latLabelFrame.size.height=fontHeight+5;!
    latLabelFrame.origin.x=(vF.size.width-latLabelFrame.size.width)/2;!
    latLabelFrame.origin.y=!
                     "(vF.size.height-(latLabelFrame.size.height+5)*5)/2;!
      [latLabel setFrame:latLabelFrame];!
      !
    CGRect latFieldFrame = latLabelFrame;!
    latFieldFrame.origin.y+=fontHeight+5;!                                      Lay out everything
        [latField setFrame:latFieldFrame];!
        !
                                                                                else relative to
    CGRect lonLabelFrame = latFieldFrame;!
    lonLabelFrame.origin.y+=fontHeight+5;!
                                                                                each other (this is
          [lonLabel setFrame:lonLabelFrame];!                                   my own personal
          !
    CGRect lonFieldFrame = lonLabelFrame;!                                      style, might not be
    lonFieldFrame.origin.y+=fontHeight+5;!
            [lonField setFrame:lonFieldFrame];!                                 for everyone)
            !
    CGRect buttonFrame = lonFieldFrame;!
    buttonFrame.origin.y+=fontHeight+10;!
    buttonFrame.size.height+=5;!
              [startStopButton setFrame:buttonFrame];!
}
Add CLLocationManagerDelegate
Methods
-(void)locationManager:(CLLocationManager *)manager!
    didUpdateToLocation:(CLLocation *)newLocation!
    fromLocation:(CLLocation *)oldLocation {!
    CLLocationCoordinate2D coord = newLocation.coordinate;!
    [latField setText:[NSString!
       "stringWithFormat:@"%f",coord.latitude]];!       Use   like printf in C
    [lonField setText:[NSString!
       "stringWithFormat:@"%f",coord.longitude]];!
    NSLog(@"Updated Location To %f, %f",!
       "coord.longitude,coord.longitude);!
}!

-(void)locationManager:(CLLocationManager *)manager!
       didFailWithError:(NSError *)error {!
       "//this is usually called when someone!
       "//doesn’t allow app to access location!
    [latField setText:@"Error"];!
    [lonField setText:[error description]];!
}
Simulate a Location
•  Go to Debug > Location in the Simulator
•  Set a Custom Location
Run The App




•  Note – the location won’t update in the simulator. Run the app on a phone
 to see the location change as you move or if the accuracy changes.

Mais conteúdo relacionado

Mais procurados

Никита Корчагин - Programming Apple iOS with Objective-C
Никита Корчагин - Programming Apple iOS with Objective-CНикита Корчагин - Programming Apple iOS with Objective-C
Никита Корчагин - Programming Apple iOS with Objective-CDataArt
 
Basic info on java intro
Basic info on java introBasic info on java intro
Basic info on java introkabirmahlotra
 
002. Introducere in type script
002. Introducere in type script002. Introducere in type script
002. Introducere in type scriptDmitrii Stoian
 
First fare 2011 frc-java-introduction
First fare 2011 frc-java-introductionFirst fare 2011 frc-java-introduction
First fare 2011 frc-java-introductionOregon FIRST Robotics
 
2 the essentials of effective java
2 the essentials of effective java2 the essentials of effective java
2 the essentials of effective javaHonnix Liang
 
Introduction to Kotlin for Android developers
Introduction to Kotlin for Android developersIntroduction to Kotlin for Android developers
Introduction to Kotlin for Android developersMohamed Wael
 
Java basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini indiaJava basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini indiaSanjeev Tripathi
 
Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript EngineKris Mok
 
Core Java Certification
Core Java CertificationCore Java Certification
Core Java CertificationVskills
 
Functional Java 8 - Introduction
Functional Java 8 - IntroductionFunctional Java 8 - Introduction
Functional Java 8 - IntroductionŁukasz Biały
 
Java 8 best practices - Stephen Colebourne
Java 8 best practices - Stephen ColebourneJava 8 best practices - Stephen Colebourne
Java 8 best practices - Stephen ColebourneJAXLondon_Conference
 

Mais procurados (19)

Никита Корчагин - Programming Apple iOS with Objective-C
Никита Корчагин - Programming Apple iOS with Objective-CНикита Корчагин - Programming Apple iOS with Objective-C
Никита Корчагин - Programming Apple iOS with Objective-C
 
Basic info on java intro
Basic info on java introBasic info on java intro
Basic info on java intro
 
002. Introducere in type script
002. Introducere in type script002. Introducere in type script
002. Introducere in type script
 
First fare 2011 frc-java-introduction
First fare 2011 frc-java-introductionFirst fare 2011 frc-java-introduction
First fare 2011 frc-java-introduction
 
2 the essentials of effective java
2 the essentials of effective java2 the essentials of effective java
2 the essentials of effective java
 
Introduction to Kotlin for Android developers
Introduction to Kotlin for Android developersIntroduction to Kotlin for Android developers
Introduction to Kotlin for Android developers
 
Core java
Core javaCore java
Core java
 
Java Tutorial
Java TutorialJava Tutorial
Java Tutorial
 
Core Java Tutorial
Core Java TutorialCore Java Tutorial
Core Java Tutorial
 
Java basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini indiaJava basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini india
 
Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript Engine
 
Core Java Certification
Core Java CertificationCore Java Certification
Core Java Certification
 
Java SE 8 best practices
Java SE 8 best practicesJava SE 8 best practices
Java SE 8 best practices
 
Functional Java 8 - Introduction
Functional Java 8 - IntroductionFunctional Java 8 - Introduction
Functional Java 8 - Introduction
 
Java Reflection @KonaTechAdda
Java Reflection @KonaTechAddaJava Reflection @KonaTechAdda
Java Reflection @KonaTechAdda
 
Introduction to Swift 2
Introduction to Swift 2Introduction to Swift 2
Introduction to Swift 2
 
Java 8 best practices - Stephen Colebourne
Java 8 best practices - Stephen ColebourneJava 8 best practices - Stephen Colebourne
Java 8 best practices - Stephen Colebourne
 
Core java
Core javaCore java
Core java
 
Java vs. C/C++
Java vs. C/C++Java vs. C/C++
Java vs. C/C++
 

Semelhante a iOS Programming Intro

Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not JavaChris Adamson
 
Objective-c for Java Developers
Objective-c for Java DevelopersObjective-c for Java Developers
Objective-c for Java DevelopersMuhammad Abdullah
 
Objective-C for iOS Application Development
Objective-C for iOS Application DevelopmentObjective-C for iOS Application Development
Objective-C for iOS Application DevelopmentDhaval Kaneria
 
What Makes Objective C Dynamic?
What Makes Objective C Dynamic?What Makes Objective C Dynamic?
What Makes Objective C Dynamic?Kyle Oba
 
UsingCPP_for_Artist.ppt
UsingCPP_for_Artist.pptUsingCPP_for_Artist.ppt
UsingCPP_for_Artist.pptvinu28455
 
Csharp introduction
Csharp introductionCsharp introduction
Csharp introductionSireesh K
 
Java Course — Mastering the Fundamentals
Java Course — Mastering the FundamentalsJava Course — Mastering the Fundamentals
Java Course — Mastering the Fundamentalsnehash4637
 
introduction to c #
introduction to c #introduction to c #
introduction to c #Sireesh K
 
Polymorphism Using C++
Polymorphism Using C++Polymorphism Using C++
Polymorphism Using C++PRINCE KUMAR
 
Blocks & GCD
Blocks & GCDBlocks & GCD
Blocks & GCDrsebbe
 
Programming Language
Programming  LanguageProgramming  Language
Programming LanguageAdeel Hamid
 

Semelhante a iOS Programming Intro (20)

Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not Java
 
Objective-c for Java Developers
Objective-c for Java DevelopersObjective-c for Java Developers
Objective-c for Java Developers
 
Objective-C for iOS Application Development
Objective-C for iOS Application DevelopmentObjective-C for iOS Application Development
Objective-C for iOS Application Development
 
What Makes Objective C Dynamic?
What Makes Objective C Dynamic?What Makes Objective C Dynamic?
What Makes Objective C Dynamic?
 
UsingCPP_for_Artist.ppt
UsingCPP_for_Artist.pptUsingCPP_for_Artist.ppt
UsingCPP_for_Artist.ppt
 
Csharp introduction
Csharp introductionCsharp introduction
Csharp introduction
 
Java Course — Mastering the Fundamentals
Java Course — Mastering the FundamentalsJava Course — Mastering the Fundamentals
Java Course — Mastering the Fundamentals
 
introduction to c #
introduction to c #introduction to c #
introduction to c #
 
core java
core javacore java
core java
 
Polymorphism Using C++
Polymorphism Using C++Polymorphism Using C++
Polymorphism Using C++
 
Blocks & GCD
Blocks & GCDBlocks & GCD
Blocks & GCD
 
c++ ppt.ppt
c++ ppt.pptc++ ppt.ppt
c++ ppt.ppt
 
lecture02-cpp.ppt
lecture02-cpp.pptlecture02-cpp.ppt
lecture02-cpp.ppt
 
java01.pdf
java01.pdfjava01.pdf
java01.pdf
 
Programming Language
Programming  LanguageProgramming  Language
Programming Language
 
RIBBUN SOFTWARE
RIBBUN SOFTWARERIBBUN SOFTWARE
RIBBUN SOFTWARE
 
Java01
Java01Java01
Java01
 
Java01
Java01Java01
Java01
 
Java01
Java01Java01
Java01
 
Java01
Java01Java01
Java01
 

iOS Programming Intro

  • 1. IOS DEVELOPMENT INTRODUCTION Lou Loizides, PE MS Computing Student @ Marquette 31 Mar 2013 http://boozall.com
  • 2. Presentations •  Class 1 – Objective C •  Background •  Requirements •  Concepts •  Syntax •  Class 2 – iPhone Programming •  XCode •  Cocoa Classes •  Programming With/Without IB •  Sample App •  If you need a book, the “Big Nerd Ranch” guides to iPhone Programming and Objective C are highly recommended
  • 4. Objective C •  Became popular on NextStep systems in the early 1980s •  Many objective C classes start with “NS” •  Superset of C •  “Thin layer” on top of C compiler •  C code can be used anywhere within objective c source •  Compiler (LLVM) Capable of compiling C++ •  Handy for open source libraries eg. (Tesseract, OpenCV) •  Not managed •  Apps are native code, not byte code •  Understanding of memory management is important •  Apps will crash on errors – no try/catch •  Objective C is the language, Cocoa is the framework
  • 5. Requirements •  Mac! •  Required an Intel processor •  Provisioning profiles need to be signed on Mac to distribute or test on a device •  XCode •  Download from Mac App Store •  If you need to test on an iOS device: •  Developer’s account: $100/yr •  Can distribute beta apps using ad-hoc methods •  Need phone UUIDs •  iPhone 4 or higher (3G/3GS won’t connect to XCode anymore) •  Note: Possible to run programs in the simulator without a developers’ account
  • 6. Alternatives to XCode •  Some alternatives to using XCode and Macs exist: •  Mono Touch •  App Titanium •  Unity 3D •  Flash CS5 •  Phone Gap •  The idea of Objective C is to create fast, efficient native code so these solutions aren’t the best •  Writing an iPhone app in Flash just seems like a bad idea
  • 7. Quirks •  Use “nil” instead of null •  Usually you chose a 2 char prefix for all classes in an app •  Example: “WB” for an app called “Workbench” •  @ symbol before a string is short hand for creating an NSString from a const char* (e.g. @"test") •  Instead of true/false it’s yes/no (true/false can be used but it’s not common) •  Almost all framework objects and functions use floats – integers are really only used in indices •  Eg. All graphics functions use floats for points •  Using floats mean you don’t have to cast as much •  NSInteger and CGFloat more common than int and float – set to compile to 32 bit or 64 bit depending on target
  • 8. Cocoa •  Objective C is just the language – syntax, etc. •  Cocoa provides the frameworks •  Consists of: •  Foundation Framework: •  Root class is NSObject •  The majority of objects •  Objective C •  Prefixed with NS, UI, others •  Compatible with ARC, autorelease •  Core Foundation Framework: •  No root class •  C, not Obj C •  All prefixed with CF •  Must release manually using CFRelease
  • 9. The Stack and Heap In Obj-C •  Understanding memory management is critical in Obj-C •  Stack: •  Transient storage of local primitives •  Last in, first out during functions •  Memory is released when function exits •  *Most* primitives (including pointers) will be on the stack •  Primitives allocated with classes end up on the heap •  If it’s declared within a function will be on the stack •  Heap: •  Memory allocated for objects •  Doesn’t automatically release •  Rule of thumb (few exceptions): if “alloc” is need it’s on the heap •  Requires a pointer somewhere (either to variable or class) to find
  • 10. Example static allocation in heap static int testA = 1.0f; Note: “.0f” means cast as int testB = 1; float (usually not necessary) @implementation foo heap in object { -(void)bar { float testC=1; Stack – will } disappear when } function is done
  • 11. Pointers 0xABC111 stack heap 0xABC111 Allocated Object 0xABC119 0xABC11F •  Pointers are int32 memory addresses (eg. ABC111) •  Mostly used for addressing classes in objective-C, but can also be used for anything else allocated: •  Arrays in C (allocated using malloc) •  Pointers to other primitives – use to pass values “by reference”
  • 12. Using Pointers Address of a variable, class, etc: int var = 16; int &varAddress = *int; Accessing data at pointer address: *varAddress = 17 Allocating memory and returning a pointer: //allocate 10 ints //Note: because this is C you will need release() int *varAddress = (*int)malloc(10*sizeof(int)); Two different ways to declare: myClass *pointer1, *pointer2; //preferred myClass* pointer1, pointer2;
  • 13. Key Pointer Concepts for Obj C •  Understand what’s on the stack •  Keep track of objects on the heap •  Recognize null references •  Pointers should point to objects or nil to avoid errors •  Un-initialized primitives won’t crash program but null references will •  All objects in Obj C are allocated dynamically using pointers •  “id” can be used in place of object pointer •  Sort of like generic “object” class in VB •  Example: NSString* myString = [[NSString alloc] init] id sameString = myString;
  • 14. Quirks & Pointers Code Example NSString *str = nil;! CGFloat gV = 5.0f;! BOOL testC = NO;! ! for (NSInteger i=0; i<10; i++)! {! testC = i>gV;! if (testC) str = @"test”;! //pointer will be 0x0 (nil) until it's past 5! NSLog(@"%d against %f and the pointer is %p”,! i,gV,str);! //a string is static so it’s always at the same ptr! //use NSMutableString if you want a copy! NSLog(@”text %@ still at %p",! "str,[str copy]); }
  • 15. Classes •  Classes consist of Interface (class declarations) and Implementation (methods) •  Usually two files are created for each class – one with each •  It is technically ok to put both in the same file, but this can slow down compiling •  It is technically ok to put multiple classes in the same file but most people don’t (I do it every now and then) •  Most classes will inherit from another class
  • 16. Class Inheritance in Objective C •  Any class in objective C can derive from any class •  Any function can be overridden •  Overriding a function requires no special syntax or keyword •  Program will first look for a function in the child class, then traverse up the class hierarchy until it finds a match •  Don’t forget to call [super methodName] if you need to keep traversing •  Access: “super” = parent class, “self” = current class Runs this one NSObject -(void)test NSObject -(void)test -(void)test No test MyObj MyObj method Runs this one
  • 17. Headers And Interfaces •  Same concept as C, C++ •  Provides forward declaration (for compiler & IDE) of: •  Classes •  Variables •  Selectors •  Memory for items declared in the class interface in the header (including structs and primitives) is allocated on the heap when the class is created •  At a minimum your class needs enough space for what’s in the interface •  Everything else is allocated dynamically as needed •  Selectors don’t have to be declared in the header, but won’t be visible to other classes unless they are •  Variables are never visible to other classes •  Headers are just for declaring “global” variables •  Getters and setters are required to access variables from other classes
  • 18. Interface/Implementation Example Header (XY.h) Implementation (XY.m) superclass @interface MyClass:NSObject static BOOL saveMe=YES; { @implementation MyClass NSInteger myInt; } -(void)myFunction { } //forward declare func -(void)myFunction; +(CGFloat)classFunction { return 1.0f; //static class func } +(CGFloat)classFunction; @end @end
  • 19. Import and @class Directive •  Headers must be imported when needed •  Because every header imports it’s own headers, importing headers within headers leads to memory problems and long compilation times •  Frameworks are imported with <> instead of quotes •  Use @class directive when possible to tell a header you’ll import the other header in the implementation #import <CoreData/CoreData.h> //Framework #import “myHeader.h” @class someClass; //“I’ll import someClass later” @interface myViewController:UIViewController { someClass *test; } @end
  • 20. Class Extensions •  In addition to creating a class derived from another class, you can modify existing classes with class extensions •  Specify class you’re extending in the interface: •  Syntax for a class extender for UIImage called “Pixels” "@interface UIImage (Pixels)! "@end! ! "@implementation UIImage (Pixels)! "@end! •  If you create a class using the File menu, the template will crate a class extension at the top of the .m file – comes in handy but not necessary "@implementation myClass () •  Common convention for class extender file name: •  UIImage+Pixels.m •  UIImage+Pixels.h !
  • 21. Class vs. Object Methods •  “-” before a method means it’s an object method •  “+” before a method means it’s a class method •  Class messages are statically allocated when class is created •  Commonly used for a custom alloc and init •  Same concept as local/global functions in C++ •  Example, for class “myClass” (methodàmessage): +(void)test{} à [myClass test] -(void)test{} à myClass *obj; [obj test]
  • 22. Objective C “Messages” •  In Obj C you “send messages” to objects to run methods •  Comparison syntax: •  Send message “method” to myclass in Obj C: [myClass method] •  C++ and Java equivalents: mClass->method() myClass.method() •  Objective C 2.0 (introduced in 2007) allows use of dot notation •  Examples in stack overflow will be mixed •  In my experience developers tend to use dot notation for getters, standard syntax for everything else •  I don’t recommend too much dot notation as it hides what’s happening •  “Selector” = signature of a method •  Eg: Selector for [view initWithFrame:frame] is “initWithFrame:”
  • 23. Passing Objects in Messages •  Only primitives can be passed Would be referred to as selector •  Objects are passed using pointers “selectorWith:andAlso:” •  Example Message: oClass *obj1; oClass *obj2; [myClass selectorWith:obj1 andAlso:obj2] •  Example Function: (void)selectorWith(oClass*)o1 Functions in objC are andAlso:(oClass*)o2 usually very descriptive, but the words before the {
 parameter is not } necessary (only need spaces)
  • 24. Cool Thing About Nil References •  Sending a message to an object with a nil reference just returns nil •  This can cause some headaches, though, because code will run if object not allocated •  If a class might be nil it’s safer to send a message to that class if the alternative is to pass a nil object to another class in a message to it (which crashes a lot of methods) •  Example: safe: [view2 removeFromSuperview] //just returns nil if view2=nil not safe: [view removeSubView:view2] //could crash if view2=nil
 (note: there is no removeSubView method for this reason) if ([myClass skyIsBlue]) { /* true if sky is blue false if sky is not blue or myClass = nil */ }
  • 25. Common Nil Reference Mistake UIButton *tBut; //just a pointer; nothing created //this will not generate errors [tBut setTitle:@"test” forState:UIControlStateNormal]; //what’s missing – need to point to something: UIButton *tBut = [[UIButton alloc] init]; [tBut setTitle:@"test” forState:UIControlStateNormal];
  • 26. Objective C Object Declaration •  Standard steps are: •  Allocate Memory •  Initialize object •  Syntax: myObj *pointer = [[myObj alloc] init]; •  Many standard classes have a class method that does both steps, ex: UIButton *t = [UIButton buttonWithType:UIButtonTypeCustom] UIColor *color = [UIColor redColor];
  • 27. Standard Init Methods •  Unlike in managed code, objective c objects always have to be initialized (memory starts out as random bits) •  NSObject uses the selector “init” for this, which can be overridden as necessary. Always follow this form: -(id)init { self = [super init]; if (self) { //your stuff here //only run if super initialized ok } return self; }
  • 28. Creating Custom Init Methods •  You don’t have to use provided init selector: -(id)createClassWithHelloString: (NSString*)helloS { self = [super init]; if (self) { NSLog(@”Hello String: %@”,helloS); } return self; } •  Views have initWithFrame: •  Controllers have initWithNibName:bundle:
  • 29. Objective C Heap Memory Management •  Objects on heap need to be accounted for and deallocated as necessary •  3 Options for Cocoa Touch: •  Allocate and release memory manually [myObj release]; •  Add objects to autorelease pool •  Autorelease pool retains objects until program exits or when it’s manually drained [myObj autorelease]; •  Use Automatic Reference Counting Note: Cocoa for OSX does have a GC, but we won’t be discussing it here
  • 30. ARC (Automatic Reference Counting) •  Introduced in 2011 •  Supercedes manual reference counting •  Retains objects that have “owners” (strong pointers to object) •  Only works with classes derived from NSObject (not foundation classes or anything based on C) •  Release other classes manually using release() and CFRelease() •  Automatically deallocates objects with no owners •  Can still compile individual classes without ARC: -fno-objc-arc flag (not common)
  • 31. More Notes Regarding ARC •  Reasons not to use it: •  Releasing yourself can help eliminate memory problems •  ARC does not allow use of release and autorelease in code •  Easy to create memory leaks •  ARC can take a few ms to a second to release objects •  Program can run ok during one test and crash during the next •  Easy to miss problems and have them show up later •  I will only be using ARC in my examples
  • 32. Releasing an Object in ARC •  Set all owners of an object (strong pointers) to nil. Once the object is floating and has zero owners ARC will grab it. //allocate the view UITableView *myTable = [[UITableView alloc] init]; *myTable UITableView Object pointer myTable = nil; *myTable Object has zero UITableView Object owners now, so pointer ARC will reclaim
  • 33. ARC vs. Garbage Collection ARC Garbage Collection Managed Not managed. ARC is Managed. Part of OS that code added at compile watches objects on the heap. time, so very little Can lead to performance overhead required problems if too many objects are allocated. Persistence Objects are released as Objects are released as soon as there’s no required to free up memory pointer to them. Need to be very careful about keeping track of pointers. Memory Leaks Prone to memory leaks Less prone to memory leaks as if there are pointers that objects that are no longer are unreachable in code being used will be released eventually
  • 34. Memory Leaks in ARC •  Most common cause of a leak is through a retain cycle •  With ARC you might not have to release but setting pointers to nil is important Obj 1 Obj 2 Obj 3 All objects have owners and are *obj2 = 0x1 *obj3 = 0x2 *obj2 = 0x3 retained Obj 2 will be Obj 1 Obj 2 Obj 3 released (no owner), then *obj2 = nil *obj3 = 0x2 *obj2 = 0x3 Obj 3 (no owner once Obj 2 is gone) Retain Cycle Obj 1 Obj 2 Obj 3 Neither Obj 2 nor 3 will be *obj2 = nil *obj3 = 0x2 *obj2 = 0x3 released as they both own eachother
  • 35. Using Weak References •  Unlike strong references, weak references do not imply ownership •  Create by adding “__unsafe_unretained” before pointer declaration •  Used to be “_weak” •  Need to be very careful with this – no guarantees against null references •  Most times it’s better to just use strong references and break them when necessary •  Some collection classes (NSMapTable) are weak by default Obj 1 Obj 2 Obj 3 All objects *obj2 = 0x1 *obj3 = 0x2 *obj2 = 0x3 are retained Obj 1 Obj 2 Obj 3 Obj 2 then 3 *obj2 = 0x1 *obj3 = 0x2 *obj2 = 0x3 will be released
  • 36. Code Example – Objects and Memory //what's the problem here???! //(assume this is not on the main thread)! ! -(void)testAlert! {! UIAlertView *alert =! " "[[UIAlertView alloc] init];! [alert setTitle:@"Hello!"];! [alert addButtonWithTitle:@"Log Awesomeness"];! [alert addButtonWithTitle:@"Close"];! [alert setCancelButtonIndex:1];! [alert setDelegate:self];! [alert show];! }
  • 37. Released too soon! •  This is a common type of problem created through ARC: 1.  [alert show] tells the main thread to draw the alert box 2.  If started from another thread (like in a block somewhere) that means it happens asynchronously 3.  So while the box is still drawing, the function ends, the frame objects are released, and there are no more owners of “alert” •  ARC comes and releases the object before we’re done using it •  Resulting behavior can be erratic: •  In most cases the program will crash •  In some cases if ARC is fast enough the alert box won’t show •  When ARC is slow everything might run fine •  Users in the app store start complaining – your app is crashing!
  • 38. Example Crash EXC_BAD_ACCESS There is nothing here Probably the last frame saved just before the crash (pointer not nil yet)
  • 39. Getters and Setters (Accessors) •  Methods to access variables from outside a class •  Naming is by convention: int myVariable; Setters usually start with “set”. Underscore is only -(void)setMyVariable:(int)_myVariable meant for { synthesized myVariable = _myVariable; setters, but } everyone uses them anyway. -(int)myVariable getters usually **This example is { have the same name as the nonatomic return myVariable;
 variable }
  • 40. Accessing Getters and Setters •  Dot notation follows the conventions Both are valid: -(void)setMyVariable: (int)_myVariable [class setMyVariable:1]; { class.myVariable=1; myVariable = _myVariable; } -(void)myVariable: { [class myVariable]; return myVariable class.myVariable; }
  • 41. Notes Regarding Dot Notation •  Depends on developer •  Most objective C samples I’ve seen follow this: •  Brackets are used in majority of cases •  Dot notion is used for getters, but not setters •  Dot notation is used when you have a ton of brackets •  This is not a convention by any means [[self window] setRootViewController: [UIViewController alloc] init]]; //Becomes self.window.rootViewController = [[UIViewController alloc] init]; //Or most commonly [self.window setRootViewController: [UIViewController alloc] init]];
  • 42. Be Careful: //say object is at 0xA123 //test.object1 points to 0xA123 test.object1 = [[myClass alloc] init]; //test.object2 now points to 0xA123 also test.object2 = object1; //both set the color of the object at 0xA123 [test.object1 setColor:[UIColor whiteColor]]; [test.object2 setColor:[UIColor whiteColor]]; //this has no impact to object1, just changes //the pointer for object2 to something different test.object2=[[myClass alloc] init]; //traditional notation is a little clearer [test setObject2:[[myClass alloc] init];
  • 43. Synthesizing Getters and Setters Header (XYClass.h) Implementation (XYClass.m) @interface MyClass @implementation MyClass @property (atomic, readonly) @synthesize NSString *myProperty; myProperty; @end @end •  atomic = all or nothing (better for •  Synthesize actually creates the threading) – see NSLock getter, setter and the variable – if •  nonatomic = partial writing of you forget “synthesize” the variable variables can happen won’t exist but the program can run •  readonly = just create getter •  Note: You still need to initialize the variable – synthesize won’t do that
  • 44. Custom Accessors •  Can either synthesize and replace (if nonatomic) or just create your own •  See NSLock for thread locking atomic implementation (atomic is slower but probably not by much) @synthesize myProperty; //create both getter and setter //override getter: -(NSString)myProperty { //if there’s no object pointed to, make one if (!myProperty) myProperty = [NSString stringWithUTF8String:"hi!"]; //note: this is equivalent to myProperty = @"hi!" return myProperty; }
  • 45. Structs •  Group of primitives that are created together •  Usually on the stack unless allocated with an object •  Members accessible through dot notation •  Commonly used in Cocoa (ex. CGRect) typedef struct { NSInteger myInt; CGFloat myFloat; } myStruct; myStruct test; test.myFloat = 1.0f
  • 46. Static Variables •  Static variables are allocated at runtime •  Shared between classes •  Use for constants •  Preferred over compiler macros •  Unlike macros will be seen by debugger •  Possible to assign values to static variables in implementation file, but not in header static CGFloat test=1.0f;
  • 47. NSLog •  Extremely useful debugging tool – sends to app log •  Following conventions from C’s printf: •  %d = integer •  %f = float, double •  %p = pointer •  printf works with const char* - NSLog uses NSString •  printf(“test %d”,1); •  NSLog(@“test %d”,1); •  %@ will also call the description function of an object •  NSLog(@”test string %@”,myString); •  [myString description] returns string itself •  Other objects might return more details
  • 48. Delegates •  Delegate classes correspond to a protocol •  Any class can be declared as a delegate •  Add <delegate name> after name of superclass in header •  Protocols contain necessary functions to run certain things //set self as a delegate for the table view [myTableView setDelegate:self] //this function defines the table row height -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 3.0f; }
  • 49. C Pre Processor Macros •  Used to insert values before code is compiled •  Simplest form: •  #DEFINE PI 3.14f; •  Everywhere in the code where “PI” is used replaced with 3.14f •  Can be used for simple functions: •  Included a lot in frameworks •  Example: The “MIN” macro: #if !defined(MIN) #define MIN(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; }) #endif
  • 50. Static (Singleton) Classes •  There is actually no way to make a singleton class in Obj-C •  All classes in Obj-C are allocated dynamically •  Common method is to create a static pointer and reference that using a class function: +(EXSingleton*)getSingleton { static EXSingleton *getSingleton= nil; if (!getSingleton) { getSingleton = [[super allocWithZone:nil] init]; } return getSingleton; Alloc calls allocWithZone, so } overriding this is just a way of getting the normal alloc method +(id)allocWithZone:(NSZone *)zone{ to return the singleton – it’s not return [self getSingleton]; 100% necessary. You can just } call [myClass getSingleton] to get/create the singleton
  • 51. Blocks •  Use to pass function with variable frame values from one selector to another •  Very common with asynchronous functions •  How to define: typedef void (^blockName)(blockParam* pName); typedef void (^blockName)(void); //no params //blockName can now be passed like a variable •  Where you’ll need it (ex. defining what happens after pushing a new view controller onto the stack) [self presentViewController:coolViewController animated:NO completion:^{ //put code to be run //at completion here }];
  • 52. Referencing Selectors •  Use @selector(selectorName:) syntax to reference selectors •  Used in timers, multi-threading, etc to fire a selector •  Don’t forget to colons for each parameter passed to the selector or the app will crash (invalid signature)!!! NSThread *newThread = [[NSThread alloc]! initWithTarget:self! selector:@selector(mySelector:)! object:nil];! ! //Points to:! -(void)mySelector:(id)testObject {}
  • 54. MVC – Model View Controller •  Model = “Stuff in background” •  Creates notifications •  Provides data •  Doesn’t know anything about user, GUI, etc •  View = Visual / GUI elements •  Same concept in Android •  No knowledge of what they’re displaying just how to display it •  Controller = Logic •  Coordinates between model and view objects •  Similar to activities in Android •  Several different methods of pushing controllers onto a stack
  • 55. Starting Your Project •  File > New Project Stick to these
  • 56. Add Options If you’re a developer this should match your account This can be added later Check this
  • 57. Necessary Files •  main.m (required) •  Creates the run loop (the main thread) •  Usually creates the autorelease pool for ARC •  App Delegate (required) •  Usually named “XYAppDelegate.m, XYAppDelegate.h” •  Contains delegate functions called by OS to: •  Create GUI after launch: application:didFinishLaunchingWithOptions: •  Go to sleep: applicationDidEnterBackground: •  Exit program: applicationWillTerminate: •  Etc. •  Main View Controller •  Usually named “XYViewController.m, XYViewController.h” •  Necessary to display something
  • 58. Key GUI Elements Controls content in right pane •  3 Panes: Controls content in left pane
  • 59. How Projects are Organized •  All files are in a single folder •  Things that look like folders are actually “groups” Group Startup Images
  • 60. Key Graphics Concepts •  Startup images are displayed when an app is starting •  Not recommended for use as a splash screen – amount of time they’re displayed varies (Apple recommends a screenshot) •  Graphics for standard and retina displays can be mixed: •  Use normal image names for standard •  Add “@2x” to retina images – app will find them •  Screen resolution for retina is double that of standard •  Point size comes from standard but with a screen scale of 2 •  Eg: iPhone 3G/3GS iPhone 4 Screen resolution 320 x 480 640 x 960 Screen points 320 x 480 320 x 480 Screen scale 1 2
  • 61. IB and NIB/XIB Files •  Interface Builder (IB) is a way of graphically laying out views to be used by a view controller •  XIB is XML version, NIB is compiled (same concept as XAML) •  Linked to a class, but not an object – if a view controller is initialized with a nib it’ll map to the nib as required •  Views can also be created from a NIB •  But be careful as this is usually not efficient (you’re loading and interpreting a file every time) •  Never ever ever EVER create table view cells from a NIB •  Could be useful for laying out something like a tip window •  I stay away from IB – I find it’s more reliable to lay out views programmatically •  IB won’t handle complex changes between portrait and landscape •  When the iPhone 5 came out all of my apps scaled automatically •  Two non-obvious advantages IB •  Apple’s human interface guidelines are built in •  You can include key-value pairs in views
  • 62. Linking NIBs to view controllers •  First must set “File’s Owner” to the class you’re using it for (eg. ExViewController) •  Linked to view/view controller through IBOutlet property •  Actions can be linked through IBAction, but just as easy to do programmatically This connection is made when the class is initialized with the NIB (if there’s no NIB loaded it’s not made)
  • 63. Breakpoints and Frames •  Breakpoints can be symbolic or exception •  Possible to break on all exceptions if desired Breakpoint •  Frame is shown at breakpoint Threads gdb debug shell Stack frame
  • 64. iOS Simulator / Schemes •  Not an emulator •  Apps are compiled for x86 •  Different versions of iOS can be added •  Go to preferences > components to add •  Use schemes to: •  Add debuggers •  Add launch arguments
  • 65. Logs Logs •  Records output from: •  Compiler •  NSLog •  OS •  Other debugging tools •  All logs throughout a single XCode session are saved Current output window
  • 66. Frameworks •  Frameworks can be added as necessary to any implementation or header and won’t throw an error: <CoreData/CoreData.h> •  Frameworks still need to be linked to the project •  If they’re used but not linked, you’ll get a linker error when trying to compile •  To add a framework, go to: •  Target > Summary > Linked Frameworks •  Or Target > Build Phases > Link Binary with Libraries
  • 67. Help •  2 Sources: •  Quick help (in right pane) •  Easy to inspect framework headers (very useful) •  Detailed help (in organizer) •  Can get to detailed help from quick help •  Definitely not as good as MSDN – no short code examples, just sample projects •  Most useful section is the list of selectors Go to organizer help
  • 68. Organizer •  Contains documentation (help), archives and device management •  Use Devices tab to copy provisioning profiles to devices for testing, or enable testing on certain devices •  Create archives to upload to the app store or for ad-hoc distribution •  Delete derived data in projects to fix problems (contains pre-compiled headers) •  Can also go to Product > Clean
  • 70. NSString/NSMutableString •  Objective C classes for holding and manipulating unicode strongs •  NSString is always static •  Using shorthand @”” declares an NSString using UTF8 characters
  • 71. NSDictionary/NSMutableDictionary •  Collection classes •  Own objects they contain •  NSDictionary – can’t change •  NSMutableDictionary – can change •  Hold lists of pointers – can contain any object •  Similar to arrays, but access value by key not index myDict = [[NSMutableDictionary alloc] init]; [myDict valueForKey:@”test”] [myDict setValue:myClass forKey:@”test”]
  • 72. Arrays / Sets •  Collection Classes •  Own objects they contain •  NSArray, NSSet – can’t change •  NSMutableArray, NSMutableSet – can change •  Hold lists of pointers – can contain any object •  Arrays: values accessible by index myArr = [[NSMutableArray alloc] init]; [myArr objectAtIndex:1] [myArr setObject:myClass atIndexedSubscript:1] •  Sets just hold non-indexed collections of objects •  Used for core data stores •  Use whenever you don’t need an index (significantly faster) •  Eg. holding pointers to retain them
  • 73. Fast Enumeration •  All collections support fast enumeration: for (NSString* checkString in stringArray) { if ([checkString isKindOfClass: [NSString class]) { NSLog(@”it’s a string!”); } } Always smart to check classes when using fast enumeration
  • 74. UIViewController •  Root class that all view controllers are based on •  Generally override initWithNibName:bundle to init •  Use to push view onto the view controller stack: -(void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion •  Use to remove self from the view controller stack: -(void)removeFromParentViewController •  UINavigationController can also be used with a view controller to manipulate the stack (creates the standardized looking toolbars on the top and bottom of the screen)
  • 75. NSNumber / NSValue •  Objective C collections (and other classes) are based on pointers, so they can’t store primitives •  NSNumber can hold any type of numeric value in an object wrapper and contains other functions for converting strings to numbers, etc. •  NSValue serves the same purpose, but it’s just a wrapper for primitive values
  • 76. Some GUI Views (all derived from UIView) UIView Root class for views UIButton Button (use class selector [UIButton buttonWithType:] to init) UIImageView View for displaying UIImage ULlabel Simple text label UITextField Field for editing text UIScrollView Scrolling window view UITableView Creates a table (only contains UITableViewCell objects as rows – no columns) UITableViewCell Creates table cells for UITable
  • 77. NSURL / Downloading Internet Data •  Use NSURL to link to a URL "NSURL *postURL = [NSURL URLWithString:! "@"http:www.google.com/image.jpeg"];! •  Use NSURLRequest (or mutable) to set up a net request "NSMutableURLRequest *request = "! "[NSMutableURLRequest requestWithURL:postURL! "cachePolicy:NSURLCacheStorageNotAllowed! "timeoutInterval:60.0];! •  Send an asynchronous (or synchronous) request "[NSURLConnection sendAsynchronousRequest:request! "queue:[NSOperationQueue mainQueue]! "completionHandler:^(NSURLResponse *response,! "NSData *data, NSError *error) {! " "if (error) {}! " "//downloads to NSData; add your stuff here! "}];
  • 79. Adding a View Controller & Nib •  Add an Obj C class derived from UIViewController •  Select “With XIB for user interface” •  Alternatively – add a User Interface with a UIView
  • 80. The XIB Owner and First Responder •  The owner is the class that will own the NIB •  Example: “EXViewController” •  The first responder is the object that receives an action •  Example: A view you click on •  If the responder doesn’t handle the event it propagates down the responder chain: •  View > View Controller > Window > Application •  You can change the first responder, but it’s usually not necessary
  • 81. Setting the Owner •  Click on “File’s Owner” in the XIB window •  Select the property inspector on the right pane •  Change the class to your view or controller that the Nib will be dropped into •  Example: EXViewController
  • 82. Add Views to the NIB •  Drag views from objects in right pane •  Use guides to stick to Apple’s Human Interface Guidelines
  • 83. Connecting Views to the Controller •  Open an assistant editor window (the guy in the tux) to have something to drag views to •  Close the right pane if necessary to make space •  Open the header of your view controller in the assistant window and the xib in the main window •  Drag the views into the header of your view controller while holding down command
  • 84. Creating an IBOutlet and IBAction •  After dragging, name the item and add an outlet/action •  An outlet creates a property with a pointer to the object •  An action creates a selector that’s called through interaction with the object (eg. Touch Up Inside, Touch Down)
  • 85. IB Code Added •  IBOutlet *testButton pointer points to the button created by the nib •  IBAction touchButton adds code to the header and implementation that can be used to add code when the button is pressed Filled in circle means this outlet is connected to something in the nib
  • 86. Adding an Action to the Button •  Assume we’ve added an IBOutlet property for the label as well – UILabel *testLabel •  Pressing the button will set the label text to “Hello World” and the view controller’s view to a red background •  @implementation EXViewController! •  - (IBAction)touchButton:! (UIButton *)sender {! [self.testLabel setText:@"Hello World"];! [[self view] setBackgroundColor:! " "[UIColor redColor]];! }
  • 87. Loading The Nib After App Launch //Note: This is all in the single window template… //1. Import ExViewController.h into the app delegate #import "EXViewController.h" //2. Use delegate application:didFinishLaunchingWithOptions - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //3. Create a UIWindow to display the app in UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; //4. Create the root view controller & add the nib name (no // extension or leave nil for no nib (can also just use "init") myViewController *rootViewController = [[myViewController alloc] initWithNibName:@"myNib" bundle:nil]; //5. Set the UIWindow’s rootViewController property to it window.rootViewController = rootViewController; //6. Set the UIWindow as the key window [self.window makeKeyAndVisible]; }
  • 88. Result Press Button
  • 90. Reasons Against Using IB •  IB is slow •  Nib has to be loaded and interpreted to create layout •  Only provides benefits for starting layout •  You’ll end up writing code to manipulate all of the views anyway •  Easy to break links to Views •  Lack of flexibility for rotations •  Pretty much have to stick to the standard automatic layout properties – can’t have two complex layouts •  I have trouble getting the auto layout properties to work the way I want them to, but that might just be me (there are books on the subject) •  Need different Nibs for both iPad and iPhone •  What happens if the screen size ever changes? •  When the iPhone 5 came out my apps all scaled fine •  Still an unreasonable number of apps in the app store that have black bars on the bottom and top of the iPhone 5 window •  I don’t use it… so I can’t teach you much about it
  • 91. View Frames •  Every view has a frame to set the location and size •  The frame is stored in/set using a CGRect structure, which contains a CGPoint specifying the origin and a CGSize specifying the frame size struct CGRect { CGPoint origin; CGSize size; }; struct CGPoint { CGFloat x; CGFloat y; }; struct CGSize { CGFloat width; CGFloat height; };
  • 92. View Frame Example //graphics in iOS are usually origin.y //done with floats, not ints //remember these are structs //so must use dot notation CGPoint origin; origin.x=10; size.height view origin.y=20; origin.x CGSize size; size.width=100; size.height=200; CGRect frame; frame.origin=origin; size.width frame.size=size; superview
  • 93. More on CGRect •  CGRectMake can be used to make a CGRect in one line CGRect CGRectMake ( CGFloat x, CGFloat y, CGFloat width, CGFloat height ); •  Also see CGPointMake, CGSizeMake •  CGRectZero is a frame of all zeros •  A view make with CGPointZero would not be visible •  Also see CGPointZero, CGSizeZero •  CGRects are structures not objects, so you can make copies using dot notation. But on a view they’re read only so you need to use a setter to set the entire frame at once (the superview redraws it’s subviews when a new frame is set) CGRect newFrame = obj1.frame; newFrame.height+=100; [obj2 setFrame:newFrame]; //or obj2.frame=newFrame;
  • 94. Adding a View With a Frame - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { //helpful to set a pointer to the controller’s view but not necessary UIView *selfView = [self view]; CGRect selfFrame = [selfView frame]; CGRect textFrame = selfFrame; //this is the size of our text box textFrame.size = CGSizeMake(100, 100); //some basic math to center it in the screen textFrame.origin = CGPointMake((selfFrame.size.width-textFrame.size.width)/2, (selfFrame.size.height-textFrame.size.height)/2); UITextView *textBox = [[UITextView alloc] initWithFrame:textFrame]; //add some attributes [textBox setText:@"Hello World"]; [textBox setBackgroundColor:[UIColor colorWithWhite:0.8f alpha:1.0f]]; //don’t forget to add the textbox as a subview! [selfView addSubview:textBox]; } return self; }
  • 95. Helpful Tip – Don’t Set Frames In Init •  Make it easy to redraw views when calculations change •  Example: Screen rotation (note: you can also use autorotation, but I find that it’s never easy to get it working perfectly) •  For init just set all frames to CGRectZero •  For view controllers create a selector like “CreateFrames” and call it at the end of init •  Now you can call it again whenever you need to •  For views, just override the view’s setFrame: selector •  Note: Don’t forget to call the super’s setFrame: selector also or the view won’t redraw frames properly
  • 96. Adding Targets to Views (eg. Buttons) - (id)initWithNibName:(NSString *)nibNameOrNil! "bundle:(NSBundle *)nibBundleOrNil {! self = [super initWithNibName:nibNameOrNil! "bundle:nibBundleOrNil];! target = object to send message to if (self) {! "testButton = //declared in interface! " "[UIButton buttonWithType:UIButtonTypeCustom];! [testButton setFrame:CGRectZero];! [testButton setTitle:@"Test" forState:UIControlStateNormal];! [testButton addTarget:self action:@selector(mySelector:)! forControlEvents:UIControlEventTouchDown];! "[self setFrames]; //my own method to set view frames! "[[self view] addSubview:testButton];! "}! return self;! 2013-03-31 14:58:33.307 }! Example[2825:c07] I pressed button -(void)mySelector:(id)buttonObject {! <UIButton: 0x8868510; NSLog(@"I pressed button %@",buttonObject);! frame = (10 10; 100 100); opaque = NO; } layer = <CALayer: 0x8868640>>
  • 97. Adding Actions to Views Without Targets •  Two common options: •  UIGestureRecognizer UISwipeGestureRecognizer *recognizer;! recognizer = [[UISwipeGestureRecognizeralloc]! initWithTarget:self! action:@selector(handleSwipeFrom:)];! [recognizer setDirection:! (UISwipeGestureRecognizerDirectionRight! | UISwipeGestureRecognizerDirectionLeft)] •  Overriding touch selectors •  Every view contains touch tasks. See UIResponder documentation for more info (UIView inherits from UIResponder). Examples: •  touchesBegan:withEvent: •  touchesMoved:withEvent: •  Note: Gesture Recognizers can cancel touches •  Set cancelsTouchesInView property
  • 100. Create A Root View Controller
  • 101. Add A View Controller Property To The App Delegate //! // GTAppDelegate.h! // GPSTracker! //! // Created by Louis Loizides on 3/31/13.! // Copyright (c) 2013 Louis Loizides. All rights reserved.! //! #import <UIKit/UIKit.h>! @class GTViewController;! @interface GTAppDelegate : UIResponder <UIApplicationDelegate>! @property (strong, nonatomic) UIWindow *window;! // Don’t forget to synthesize this in the implementation!! @property (nonatomic) GTViewController *rootViewController;! @end
  • 102. Create The View Controller //! // GTAppDelegate.m! // GPSTracker! #import "GTAppDelegate.h"! #import "GTViewController.h"! @implementation GTAppDelegate! @synthesize rootViewController;! - (BOOL)application:(UIApplication *)application! didFinishLaunchingWithOptions:(NSDictionary *)launchOptions! {! self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];! // Override point for customization after application launch.! rootViewController = [[GTViewController alloc] initWithNibName:nil bundle:nil];! [self.window setRootViewController:rootViewController];! ! self.window.backgroundColor = [UIColor whiteColor];! [self.window makeKeyAndVisible];! return YES;! }
  • 103. Add Core Location Framework Go to Targets > GPSTracker > Frameworks
  • 104. Add Pointers for Views, CoreLocationManager and set Delegate // GTViewController.h! // GPSTracker! ! #import <UIKit/UIKit.h>! #import <CoreLocation/CoreLocation.h>! @interface GTViewController : UIViewController! <CLLocationManagerDelegate,UITextFieldDelegate>! {! UIButton *startStopButton;! UILabel *latLabel;! UILabel *lonLabel;! UITextField *latField;! UITextField *lonField;! CLLocationManager *locationManager;! BOOL isUpdating;! }! @end
  • 105. Create Objects in Root View Controller Implementation -(id)initWithNibName:(NSString *)nibNameOrNil! "bundle:(NSBundle *)nibBundleOrNil {! self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];! if (self) {! latLabel = [[UILabel alloc] initWithFrame:CGRectZero];! lonLabel = [[UILabel alloc] initWithFrame:CGRectZero];! latField = [[UITextField alloc] initWithFrame:CGRectZero];! lonField = [[UITextField alloc] initWithFrame:CGRectZero];! startStopButton = [UIButton buttonWithType:UIButtonTypeCustom];! [startStopButton setFrame:CGRectZero];! [startStopButton addTarget:self action:@selector(startStop:)! forControlEvents:UIControlEventTouchDown];! [[self view] addSubview:latLabel];! [[self view] addSubview:lonLabel];! [[self view] addSubview:latField];! [[self view] addSubview:lonField];! [[self view] addSubview:startStopButton];! locationManager = [[CLLocationManager alloc] init];! [locationManager setDelegate:self];! [self createFrames];! isUpdating=NO;! [self startStop:nil]; //use to set the first start/stop title! }! return self;! }
  • 106. Add Some Style Stuff /*! Put this in init method! Note: text fields are used for values instead of labels! "to allow cut and paste, but I really just wanted! "to have a couple of view examples here! */! [[self view] setBackgroundColor:[UIColor lightGrayColor]];! [latLabel setBackgroundColor:[UIColor clearColor]];! [latLabel setTextAlignment:NSTextAlignmentCenter];! [latField setBackgroundColor:[UIColor whiteColor]];! [latField setTextAlignment:NSTextAlignmentCenter];! [lonLabel setBackgroundColor:[UIColor clearColor]];! [lonLabel setTextAlignment:NSTextAlignmentCenter];! [lonField setBackgroundColor:[UIColor whiteColor]];! [lonField setTextAlignment:NSTextAlignmentCenter];! [latLabel setText:@"Latitude"];! [lonLabel setText:@"Longitude"];!
  • 107. Add a UITextFieldDelegate //Get rid of the editing view on the UITextFields! //so the keyboard doesn’t appear and set the! //delegate to the view controller! [latField setDelegate:self];! [lonField setDelegate:self];! [latField setInputView:[[UIView alloc] init]];! [lonField setInputView:[[UIView alloc] init]];! ! //Add a delegate function to prevent editing! -(BOOL)textField:(UITextField *)textField! "shouldChangeCharactersInRange:(NSRange)range! "replacementString:(NSString *)string{! return NO;! }
  • 108. Add the Start/Stop Method -(void)startStop:(id)sender! {! if (!isUpdating && sender) {! [locationManager startUpdatingLocation];! [latField setText:@""];! [lonField setText:@""];! [startStopButton setTitle:@"Stop”! " "forState:UIControlStateNormal];! isUpdating=YES;! }! else {! [locationManager stopUpdatingLocation];! [latField setText:@"Stopped"];! [lonField setText:@"Stopped"];! [startStopButton setTitle:@"Start”! " "forState:UIControlStateNormal];! isUpdating=NO;! }! }
  • 109. Add A Function To Set Frames -(void)createFrames! {! CGRect vF = [[self view] frame];! Start with application CGFloat fontHeight = [[latLabel font] pointSize];! ! frame or view frame CGRect latLabelFrame=vF;! latLabelFrame.size.width/=2;! latLabelFrame.size.height=fontHeight+5;! latLabelFrame.origin.x=(vF.size.width-latLabelFrame.size.width)/2;! latLabelFrame.origin.y=! "(vF.size.height-(latLabelFrame.size.height+5)*5)/2;! [latLabel setFrame:latLabelFrame];! ! CGRect latFieldFrame = latLabelFrame;! latFieldFrame.origin.y+=fontHeight+5;! Lay out everything [latField setFrame:latFieldFrame];! ! else relative to CGRect lonLabelFrame = latFieldFrame;! lonLabelFrame.origin.y+=fontHeight+5;! each other (this is [lonLabel setFrame:lonLabelFrame];! my own personal ! CGRect lonFieldFrame = lonLabelFrame;! style, might not be lonFieldFrame.origin.y+=fontHeight+5;! [lonField setFrame:lonFieldFrame];! for everyone) ! CGRect buttonFrame = lonFieldFrame;! buttonFrame.origin.y+=fontHeight+10;! buttonFrame.size.height+=5;! [startStopButton setFrame:buttonFrame];! }
  • 110. Add CLLocationManagerDelegate Methods -(void)locationManager:(CLLocationManager *)manager! didUpdateToLocation:(CLLocation *)newLocation! fromLocation:(CLLocation *)oldLocation {! CLLocationCoordinate2D coord = newLocation.coordinate;! [latField setText:[NSString! "stringWithFormat:@"%f",coord.latitude]];! Use like printf in C [lonField setText:[NSString! "stringWithFormat:@"%f",coord.longitude]];! NSLog(@"Updated Location To %f, %f",! "coord.longitude,coord.longitude);! }! -(void)locationManager:(CLLocationManager *)manager! didFailWithError:(NSError *)error {! "//this is usually called when someone! "//doesn’t allow app to access location! [latField setText:@"Error"];! [lonField setText:[error description]];! }
  • 111. Simulate a Location •  Go to Debug > Location in the Simulator •  Set a Custom Location
  • 112. Run The App •  Note – the location won’t update in the simulator. Run the app on a phone to see the location change as you move or if the accuracy changes.