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
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
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];
}
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
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
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;!
}
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.