If you've used iPhone OS applications, you've no doubt seen a number of common tricks that are in no way obvious from looking at the documentation provided in the SDK. In this session, we'll look at a grab-bag of some of the most popular and least obvious techniques you'll want in your developer's toolkit.
5. SORTING ARRAYS
NSSortDescriptor works nicely with key-value-coding
Values need to implement compare:
Alternatives
sortedArrayUsingSelector: - called on value
sortedArrayUsingFunction:context: - calls a C
function
7. CUSTOM TABLE CELLS
Cell goes in its own nib, connected to an outlet in an
owner
Owner uses this outlet when creating new cells
Find subviews of cell by tag, or subclass
UITableViewCell and set up outlets and properties.
9. TABLE FILTERING
IB provides “Search Bar and
Search Display Controller”
UISearchBar and a UITable that
slides in to show filter results.
You implement
UISearchBarDelegate
10. TOO MUCH MORE!
Tweetie 2 - pull-to-reload
http://github.com/enormego/
EGOTableViewPullRefresh
http://www.drobnik.com/touch/2009/12/how-to-
make-a-pull-to-reload-tableview-just-like-tweetie-2/
Controls in tables - see Apple’s table guide
15. PLAYING NICE WITH IPOD
Use AVAudioSession categories to set behavior
AVAudioSessionCategoryAmbient
AVAudioSessionCategorySoloAmbient
AVAudioSessionCategoryPlayback
AVAudioSessionCategoryRecord
AVAudioSessionCategoryPlayAndRecord
AVAudioSessionCategoryAudioProcessing
16. PLAYING NICE WITH IPOD
Core Audio uses same categories, different names
kAudioSessionCategory_AmbientSound
kAudioSessionCategory_SoloAmbientSound
kAudioSessionCategory_MediaPlayback
kAudioSessionCategory_RecordAudio
kAudioSessionCategory_PlayAndRecord
kAudioSessionCategory_AudioProcessing
18. HANDLING INTERRUPTIONS
Can be from alarms, incoming calls, etc. If accepted,
your app terminates
AVAudioSessionDelegate beginInterruption,
endInterruption
Core Audio makes you set an interruption callback
when you InitializeAudioSession
App-level is different: applicationWillResignActive: and
applicationWillTerminate:
22. KEYCHAIN ON IPHONE
No access to a system-wide keychain
Apps get access to their own items only (well…)
Four essential C functions:
SecItemAdd, SecItemDelete, SecItemUpdate,
SecItemCopyMatching
All are a huge hassle to call
23. KEYCHAIN FTW!
Keychain items survive application wipes and
reinstalls
Keychain is encrypted, and backed up by iTunes
Works with untyped void* data types
You can put whatever you like in a keychain item
24. KEYCHAIN FTW 2!
Can share data between applications with Keychain
Create Entitlements file with a keychain-access-group
that matches first fragment of your apps’ identifiers.
Use key kSecAttrAccessGroup in keychain calls
Use same signing credentials
That said… I couldn’t get this working in time
27. BUILDING “LITE” VERSIONS
Create multiple targets
Each target has different Info.plist and different build
settings
Potentially different Icon.png, MainWindow.xib, etc.
Can omit resource files from your lite version
Set OTHER_CFLAGS to do #ifdef
29. COMMAND-LINE BUILDS
/usr/bin/xcodebuild builds project in current
directory with current settings.
Can build any or all targets, supports different SDKs
(iPhone 2.2 / 3.0 / 3.1), and configurations (Debug /
Release)
Only on Mac
Buy an XServe for your build farm
31. /USR/BIN/AFCONVERT
Reads and writes all default Core Audio formats
Useful for converting into .caf format (preferred
format for iPhone audio files) and transcoding (no
floating-point PCM samples on iPhone)
Getting the arguments right can be tough
afconvert -d LEI16 -f 'caff' orig-cymbal.caf
35. USEFUL REACHABILITY FLAGS
Good: kSCNetworkReachabilityFlagsReachable,
Probably OK:
kSCNetworkReachabilityFlagsConnectionRequired,
kSCNetworkReachabilityFlagsConnectionOnTraffic,
kSCNetworkReachabilityFlagsConnectionOnDemand
How to know you’re not on wi-fi:
kSCNetworkReachabilityFlagsIsWWAN
36. MAKE NETWORK FAST
URL Loading System quietly supports gzip and deflate
You just get the decoded data
NSMutableURLRequest *request = [NSMutableURLRequest
requestWithURL:postURL];
[request setHTTPMethod: @"POST"];
[request addValue:@"gzip"
forHTTPHeaderField:@"Accepts-Encoding"];