Advanced iOS

4,090 views

Published on

iOS is a great platform to work on, and many developers have spend some time looking at the platform. This talk is aimed at programmers with prior iOS experience who want to get into iOS in more depth.

This presentation will take you from a basic level of understanding of iOS to look at advanced topics that will make you apps more polished, better designed and, ideally, more successful.

Abstract concepts are no use, so in this talk we'll take some existing successful commercial iOS applications as a case study, and see how a selection of iOS technologies and techniques combine within it.

On the way, we'll see:
* How to use Objective-C language facilities to their best advantage
* How to exploit key iOS technologies to save you time and effort
* iOS development idioms that will improve the quality of your code
* Creating "universal" iPhone/iPad/retina applications without going mad
* Successful deployment and testing strategies

Published in: Technology
2 Comments
7 Likes
Statistics
Notes
No Downloads
Views
Total views
4,090
On SlideShare
0
From Embeds
0
Number of Embeds
11
Actions
Shares
0
Downloads
0
Comments
2
Likes
7
Embeds 0
No embeds

No notes for slide

Advanced iOS

  1. 1. mobile east june 2012advanced iOSgetting your knees wet, rather then your ankles PETE GOODLIFFE pete@goodliffe.net @petegoodliffe
  2. 2. @petegoodliffepete@goodliffe.netgoodliffe.blogspot.comwww.goodliffe.net PE TE G OODL PROGRAMME IFFE R / AUTHOR / COLUMNIST / TEACHER ★ CON SCIENTIOUS CODER
  3. 3. me
  4. 4. you
  5. 5. this
  6. 6. iOS is a great platform to work on, and many developers have spend some time looking atthe platform. This talk is aimed at programmers with prior iOS experience who want to getinto iOS in more depth.This presentation will take you from a basic level of understanding of iOS to look atadvanced topics that will make you apps more polished, better designed and, ideally, moresuccessful.Abstract concepts are no use, so in this talk well take some existing successful commercial thisiOS applications as a case study, and see how a selection of iOS technologies andtechniques combine within it.On the way, well see: ‣How to use Objective-C language facilities to their best advantage ‣How to exploit key iOS technologies to save you time and effort ‣iOS development idioms that will improve the quality of your code ‣Creating "universal" iPhone/iPad/retina applications without going mad ‣Successful deployment and testing strategies
  7. 7. iOS is a great platform to work on, and many developers have spend some time looking atthe platform. This talk is aimed at programmers with prior iOS experience who want to getinto iOS in more depth.This presentation will take you from a basic level of understanding of iOS to look atadvanced topics that will make you apps more polished, better designed and, ideally, moresuccessful.Abstract concepts are no use, so in this talk well take some existing successful commercial thisiOS applications as a case study, and see how a selection of iOS technologies andtechniques combine within it.On the way, well see: ‣How to use Objective-C language facilities to their best advantage ‣How to exploit key iOS technologies to save you time and effort ‣iOS development idioms that will improve the quality of your code ‣Creating "universal" iPhone/iPad/retina applications without going mad ‣Successful deployment and testing strategies
  8. 8. the plan
  9. 9. but first...
  10. 10. http://www.dilbert.com/strips/comic/2012-04-02/
  11. 11. advanced what does that mean?
  12. 12. iPhone objective C101 cocoa
  13. 13. iPhone objective C101 cocoa ? iPhone 201
  14. 14. topic #1 user interface kung foo topic #2”advanced” coding techniques topic #3 getting animated topic #4 audio shenanigans topic #5 ninja tools
  15. 15. topic #1user interface kung foo
  16. 16. advice case study code
  17. 17. user interface advice don’t be clever don’t be cute be idiomatic
  18. 18. standard iOS conventions
  19. 19. the “extra” conventions
  20. 20. cool stuff
  21. 21. cool stuff
  22. 22. pull to refresh
  23. 23. https://github.com/enormego/EGOTableViewPullRefresh https://github.com/leah/PullToRefresh https://github.com/shiki/STableViewController
  24. 24. cool stuff
  25. 25. (swipey) sidebar
  26. 26. https://github.com/Inferis/ViewDeckhttp://cocoacontrols.com/platforms/ios/controls/pprevealsideviewcontroller http://cocoacontrols.com/platforms/ios/controls/hsimagesidebarview
  27. 27. ui joy is in the details
  28. 28. subtle shadow
  29. 29. No Carrier 00:49 Not ChargingUIBarButtonItem Mahjong Score Book UINavigationBar UIScrollView UIView (parent) Custom UIView
  30. 30. No Carrier 00:49 Not Charging Mahjong Score BookGradient
  31. 31. No C arrie r 19:2 4 100% ✘
  32. 32. No C arrie r 19:2 4 100% ✘
  33. 33. No C arrie r 19:2 4 100%pass touches through ✔
  34. 34. No C arrie r 19:2 4 100%
  35. 35. No C arrie r 19:2 4 100%
  36. 36. @interface FadeView : UIView@end
  37. 37. @interface FadeView : UIView@end@implementation FadeView- (void) setUp{ self.backgroundColor = [UIColor clearColor]; CAGradientLayer *gradientLayer = [[CAGradientLayer alloc] init]; gradientLayer.colors = [NSArray arrayWithObjects: (id)[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5].CGColor, (id)[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0].CGColor, nil]; gradientLayer.startPoint = CGPointMake(0,0); gradientLayer.endPoint = CGPointMake(0,1); gradientLayer.frame = CGRectMake(0,0,self.bounds.size.width, self.bounds.size.height); [self.layer insertSublayer:gradientLayer atIndex:0];}- (id) initWithCoder:(NSCoder *)aDecoder{ if ((self = [super initWithCoder:aDecoder])) { [self setUp]; } return self;}- (id) initWithFrame:(CGRect)frame { /* ... */ }@end
  38. 38. theming toolbars
  39. 39. toolbar background button background normal pressed highlighted &highlighted pressed
  40. 40. - (void)viewDidLoad{ gridView.dataSource = self; gridView.delegate = self; [gridView reloadData]; self.navigationItem.title = AppName; self.navigationItem.rightBarButtonItem = self.editButtonItem; navigationBar.items = [NSArray arrayWithObject:self.navigationItem]; [self setEditing:NO animated:NO]; if ([[UINavigationBar class] respondsToSelector:@selector(appearance)]) { UIEdgeInsets insets = {6, 6, 6, 6}; UIImage *image = [[UIImage imageNamed:@"ToolbarBlack"] resizableImageWithCapInsets:insets]; [self.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault]; [self styleButton:self.navigationItem.leftBarButtonItem]; [self styleButton:self.navigationItem.rightBarButtonItem]; } [super viewDidLoad];}
  41. 41. - (void) setEditButtonAppearance{ if ([[UINavigationBar class] respondsToSelector:@selector(appearance)]) { UIEdgeInsets insets = {10, 10, 10, 10}; UIImage *navButton = !self.editing ? [[UIImage imageNamed:@"ToolbarBlackButton"] resizableImageWithCapInsets:insets] : [[UIImage imageNamed:@"ToolbarBlackButtonSelected"] resizableImageWithCapInsets:insets]; UIImage *navButtonPressed = !self.editing ? [[UIImage imageNamed:@"ToolbarBlackButtonPressed"] resizableImageWithCapInsets:insets] : [[UIImage imageNamed:@"ToolbarBlackButtonSelectedPressed"] resizableImageWithCapInsets:insets]; [self.editButtonItem setBackgroundImage:navButton forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; [self.editButtonItem setBackgroundImage:navButtonPressed forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]; }}
  42. 42. topic #2”advanced” coding techniques
  43. 43.
  44. 44. threePROBLEMS
  45. 45. AVAudioPlayer✔ Play theme tune✘ Fade in/out
  46. 46. categoriesassociative references blocks
  47. 47. PROBLEM#1 a nice API
  48. 48. categories(because one interface is never enough)
  49. 49. AVAudioPlayer *player = … ;[player play];[player stop];
  50. 50. AVAudioPlayer *player = … ;[player play];[player stop];[player playWithFadeDuration:1.0];[player stopWithFadeDuration:1.0];
  51. 51. @interface AVAudioPlayer{ …}- (id) initWithContentsOfURL:(NSURL*)url;- (void) play;- (void) stop;@end
  52. 52. @interface AVAudioPlayer{ …}- (id) initWithContentsOfURL:(NSURL*)url;- (void) play;- (void) stop;- (void) playWithFadeDuration:(float)secs;- (void) stopWithFadeDuration:(float)secs;@end
  53. 53. @interface AVAudioPlayer (Fades)- (void) playWithFadeDuration:(float)secs;- (void) stopWithFadeDuration:(float)secs;@end
  54. 54. @implementation AVAudioPlayer (Fades)- (void) playWithFadeDuration:(float)secs{ // magic happens here}- (void) stopWithFadeDuration:(float)secs{ // clever stuff in here}@end
  55. 55. AVAudioPlayer *player = … ;[player play];[player stop];[player playWithFadeDuration:1.0];[player stopWithFadeDuration:1.0]; ✔
  56. 56. PROBLEM#2 we need some new instance variables
  57. 57. associative references (a posh name for cheating)
  58. 58. static const char volumeLevelKey = ‘Q’;NSNumber *number = [NSNumber numberWithFloat:1.0];objc_setAssociatedObject(self, &volumeLevelKey, number, OBJ_ASSOCIATION_RETAIN_NONATOMIC);
  59. 59. NSNumber *number = (NSNumber*)objc_getAssociatedObject(self, &volumeLevelKey);
  60. 60. @interface AVAudioPlayer (Fades)- (void) playWithFadeDuration:(float)secs;- (void) stopWithFadeDuration:(float)secs;@property float fadeVolume;@end
  61. 61. - (void) fadeVolume{ // gibberish in here}- (void) setFadeVolume{ // cobblers in here} ✔float fadeVolume = player.fadeVolume;
  62. 62. PROBLEM#3 we need to use another fancy language feature
  63. 63. blocks(because C++ isn’t the only cool language)
  64. 64. PROBLEM#3 when a fade has completed, do “something”
  65. 65. typedef void (^FadeCompleteBlock)();
  66. 66. typedef void (^FadeCompleteBlock)();- (void) fadeToVolume:(float)volume withDuration:(float)secs andThen:(FadeCompleteBlock)action
  67. 67. typedef void (^FadeCompleteBlock)();- (void) fadeToVolume:(float)volume withDuration:(float)secs andThen:(FadeCompleteBlock)action[player fadeToVolume:0.0 withDuration:1.0 andThen:^{ [player stop]; player.volume = 1.0; }];
  68. 68. http://goodliffe.blogspot.co.uk/2011/04/ios-fading-avaudioplayer.html https://gitorious.org/audioplayerwithfade/audioplayerwithfade
  69. 69. topic #3 getting animated
  70. 70. video>>>
  71. 71. - (void) documentsViewControllerSelected:(NSString*)file fromRect:(CGRect)from;{ lastDocumentRect = from; scoresViewController.filename = file; [scoresViewController animateAppearingFrom:from afterDelay:0.1]; [window setRootViewController:scoresViewController animated:YES];}
  72. 72. - (void) animateAppearingFrom:(CGRect)rect afterDelay:(NSTimeInterval)delay{ (void)self.view; UIImage *image = [mainView drawIntoImage]; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; [mainView.superview addSubview:imageView]; imageView.frame = rect; mainView.hidden = YES; [UIView animateWithDuration:1.0 delay:delay options:UIViewAnimationOptionAllowUserInteraction animations:^{ imageView.frame = mainView.frame; } completion:^(BOOL finished){ mainView.hidden = NO; [imageView removeFromSuperview]; }];}
  73. 73. @interface UIView (PGLib)- (UIImage*) drawIntoImage;@end- (UIImage*) drawIntoImage{ UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, [[UIScreen mainScreen] scale]); [self.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image;}
  74. 74. - (void) animateAppearingFrom:(CGRect)rect afterDelay:(NSTimeInterval)delay{ (void)self.view; UIImage *image = [mainView drawIntoImage]; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; [mainView.superview addSubview:imageView]; imageView.frame = rect; mainView.hidden = YES; [UIView animateWithDuration:1.0 delay:delay options:UIViewAnimationOptionAllowUserInteraction animations:^{ imageView.frame = mainView.frame; } completion:^(BOOL finished){ mainView.hidden = NO; [imageView removeFromSuperview]; }];}
  75. 75. @interface TitlePageView : UIView{ CAShapeLayer *shapeLayer1; CAShapeLayer *shapeLayer2; CAShapeLayer *shapeLayer3; CALayer *imageLayer;}@property (nonatomic, retain) IBOutlet UIButton *playButton;- (void) startAnimation;- (void) checkAnimationsRunning;- (void) stopAnimation;- (void) setBackgroundImage:(UIImage*)backgroundImage;@end
  76. 76. -(void) startAnimation{ CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; animation.duration = 5.0; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; animation.repeatCount = 10000; animation.autoreverses = YES; animation.fromValue = [NSNumber numberWithDouble:0]; animation.toValue = [NSNumber numberWithDouble:M_PI]; [shapeLayer1 addAnimation:animation forKey:@"animatePath"]; animation.duration = 8.0; [shapeLayer2 addAnimation:animation forKey:@"animatePath"]; animation.duration = 13.0; [shapeLayer3 addAnimation:animation forKey:@"animatePath"];}-(void) stopAnimation{ [shapeLayer1 removeAllAnimations]; [shapeLayer2 removeAllAnimations]; [shapeLayer3 removeAllAnimations];}
  77. 77. topic #4 audio shenanigans
  78. 78. you have a phone it makes a noise how do you do that?
  79. 79. CoreAudio Audio } { Services OpenAL Headphones AVAudioPlayer SpeakerYour code Audio Session Audio USB Queue Audio Unit Bluetooth Audio File Services
  80. 80. Audio Session Services } { OpenAL Phones AVAudioPlayer Speaker Code Session Queue USB Unit BT Phone Call Describe type App Doing my of audio use & INTERRUPTION! Resumestarts audio thing start session Other apps
  81. 81. Audio Services Services } { OpenAL Phones AVAudioPlayer Speaker Code Session Queue USB Unit BT@interface Sounds : NSObject{ SystemSoundID lock;}- (void) lock;@end @implementation Sounds - (id)init { if ((self = [super init])) { NSBundle *bundle = [NSBundle mainBundle]; NSURL *lockUrl = [bundle URLForResource:@"Noise" withExtension:@"wav"]; AudioServicesCreateSystemSoundID((__bridge CFURLRef)lockUrl, &lock); } return self; } - (void) lock { AudioServicesPlayAlertSound(lock); } @end
  82. 82. OpenAL Services } { OpenAL Phones AVAudioPlayer Speaker Code Session Queue USB Unit BT OpenAL is a cross-platform 3D audio API appropriate for use with gaming applications and many other types of audio applications. The library models a collection of audio sources moving in a 3D space that are heard by a single listener somewhere in that space.The basic OpenAL objects are a Listener, a Source, and a Buffer. There can be a large number of Buffers, which contain audio data. Each buffer can be attached to one or more Sources, which represent points in 3D space which are emitting audio. There is always one Listener object (per audio context), which represents the position where the sources are heard -- rendering is done from the perspective of the Listener.
  83. 83. AVAudioPlayer Services } { OpenAL Phones AVAudioPlayer Speaker Code Session Queue USB Unit BT“Apple recommends that you usethis class for audio playback unless ” you are playing audio captured from a network stream or require very low I/O latency.
  84. 84. AVAudioPlayer Services } { OpenAL Phones AVAudioPlayer Speaker Code Session Queue USB Unit BTplay single sound (memory or file) seek control level read level
  85. 85. Services } { OpenAL Phones AVAudioPlayer Speaker Code Session Queue USB Unit BT Audio Audio Queue Unitlow latency lowest latency plug-in architecturedealing with plain old PCM audio data
  86. 86. topic #5 ninja tools
  87. 87. #pragma mark . . . } afterDelay:0.5]; } return imported >= 0;}//==============================================================================#pragma mark - IBActions- (IBAction)add:(id)sender{ [self hideTipView]; unsigned index = [documents addNewGame]; [gridView . . . . . . [popup presentFromRect:popupRect inView:gridView.superview withText:view.name withObject:[NSNumber numberWithUnsignedInt:[gridView indexForCell:cell]]];}#pragma mark UIActionSheetDelegate- (void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ sheet = 0; if (buttonIndex != 0) return; . . .
  88. 88. TestFlight
  89. 89. (don’t reinvent)
  90. 90. http://cocoacontrols.com/http://www.stackoverflow.com/ http://www.github.com/
  91. 91. QA ★★★ & ★★★Pete Goodliffe @petegoodliffe pete@goodliffe.net
  92. 92. @petegoodliffepete@goodliffe.netgoodliffe.blogspot.comwww.goodliffe.net
  93. 93. BUMPH DULL, but important ★THIS DOCUMENT WAS CREATED BY PETE GOODLIFFE IT IS COPYRIGHT // © 2012 PETE GOODLIFFE>> ALL RIGHTS RESERVED>> ALL THOUGHTS ARE OWNED>> PHOTOS AND IMAGES ARE MOSTLY SOURCED FROM THE WEBTHANK YOU FOR READING // I HOPE IT WAS USEFUL Version 1.0 2012-08-14

×