SlideShare a Scribd company logo
mobile east
                                                       june 2012




advanced iOS
getting your knees wet, rather then your ankles




   PETE GOODLIFFE pete@goodliffe.net @petegoodliffe
@petegoodliffe
pete@goodliffe.net
goodliffe.blogspot.com
www.goodliffe.net




      PE TE G OODL
      PROGRAMME
                   IFFE
                R / AUTHOR / COLUMNIST / TEACHER ★ CON SCIENTIOUS CODER
Advanced iOS
me
you
this
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


                                      this
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
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


                                      this
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
the plan
but first...
http://www.dilbert.com/strips/comic/2012-04-02/
Advanced iOS
advanced
 what does that mean?
iPhone   objective C

101        cocoa
iPhone       objective C

101            cocoa




         ?
                           iPhone

                           201
topic #1
   user interface kung foo



 topic #2
”advanced” coding techniques



 topic #3
      getting animated



 topic #4
     audio shenanigans



 topic #5
         ninja tools
topic #1
user interface kung foo
advice case study code
user interface advice

    don’t be clever
     don’t be cute
     be idiomatic
standard iOS conventions
the “extra” conventions
cool stuff
cool stuff
Advanced iOS
pull to refresh
https://github.com/enormego/EGOTableViewPullRefresh
          https://github.com/leah/PullToRefresh
     https://github.com/shiki/STableViewController
cool stuff
Advanced iOS
Advanced iOS
Advanced iOS
(swipey) sidebar
Advanced iOS
https://github.com/Inferis/ViewDeck
http://cocoacontrols.com/platforms/ios/controls/pprevealsideviewcontroller

   http://cocoacontrols.com/platforms/ios/controls/hsimagesidebarview
ui joy is in the details
Advanced iOS
Advanced iOS
Advanced iOS
Advanced iOS
subtle shadow
No Carrier         00:49          Not Charging


UIBarButtonItem                Mahjong Score Book                    UINavigationBar



                                                                    UIScrollView




     UIView
      (parent)

                                                                   Custom UIView
No Carrier         00:49          Not Charging


                        Mahjong Score Book
Gradient
No C
     arrie
           r
               19:2
                   4

                       100%




                              ✘
No C
     arrie
           r
               19:2
                   4

                       100%




                              ✘
No C
                    arrie
                          r
                              19:2
                                  4

                                      100%



pass touches
  through




                                             ✔
No C
     arrie
           r
               19:2
                   4

                       100%
No C
     arrie
           r
               19:2
                   4

                       100%
@interface FadeView : UIView
@end
@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
theming toolbars
toolbar background




         button background

   normal                    pressed




                           highlighted &
highlighted                pressed
- (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];
}
- (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];
    }

}
topic #2
”advanced” coding techniques
♪
three
PROBLEMS
AVAudioPlayer



✔  Play theme tune
✘ Fade in/out
categories
associative references
        blocks
PROBLEM#1


       a nice API
categories
(because one interface is never enough)
AVAudioPlayer *player = … ;
[player play];
[player stop];
AVAudioPlayer *player = … ;
[player play];
[player stop];

[player playWithFadeDuration:1.0];
[player stopWithFadeDuration:1.0];
@interface AVAudioPlayer
{
    …
}

- (id) initWithContentsOfURL:(NSURL*)url;

- (void) play;
- (void) stop;



@end
@interface AVAudioPlayer
{
    …
}

- (id) initWithContentsOfURL:(NSURL*)url;

-   (void)   play;
-   (void)   stop;
-   (void)   playWithFadeDuration:(float)secs;
-   (void)   stopWithFadeDuration:(float)secs;

@end
@interface AVAudioPlayer (Fades)

- (void) playWithFadeDuration:(float)secs;
- (void) stopWithFadeDuration:(float)secs;

@end
@implementation AVAudioPlayer (Fades)

- (void) playWithFadeDuration:(float)secs
{
    // magic happens here
}

- (void) stopWithFadeDuration:(float)secs
{
    // clever stuff in here
}

@end
AVAudioPlayer *player = … ;
[player play];
[player stop];

[player playWithFadeDuration:1.0];
[player stopWithFadeDuration:1.0];




                                     ✔
PROBLEM#2

    we need some new
    instance variables
associative references
    (a posh name for cheating)
static const char volumeLevelKey = ‘Q’;
NSNumber *number = [NSNumber numberWithFloat:1.0];

objc_setAssociatedObject(self,
    &volumeLevelKey,
    number,
    OBJ_ASSOCIATION_RETAIN_NONATOMIC);
NSNumber *number =
    (NSNumber*)objc_getAssociatedObject(self, &volumeLevelKey);
@interface AVAudioPlayer (Fades)

- (void) playWithFadeDuration:(float)secs;
- (void) stopWithFadeDuration:(float)secs;

@property float fadeVolume;

@end
- (void) fadeVolume
{
    // gibberish in here
}

- (void) setFadeVolume
{
    // cobblers in here
}




                                   ✔
float fadeVolume = player.fadeVolume;
PROBLEM#3

  we need to use another
  fancy language feature
blocks
(because C++ isn’t the only cool language)
PROBLEM#3

 when a fade has completed,
      do “something”
typedef void (^FadeCompleteBlock)();
typedef void (^FadeCompleteBlock)();




- (void) fadeToVolume:(float)volume
         withDuration:(float)secs
              andThen:(FadeCompleteBlock)action
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;
             }];
http://goodliffe.blogspot.co.uk/2011/04/ios-fading-avaudioplayer.html
   https://gitorious.org/audioplayerwithfade/audioplayerwithfade
topic #3
 getting animated
video>>>
Advanced iOS
- (void) documentsViewControllerSelected:(NSString*)file fromRect:(CGRect)from;
{
    lastDocumentRect = from;

    scoresViewController.filename = file;
    [scoresViewController animateAppearingFrom:from afterDelay:0.1];
    [window setRootViewController:scoresViewController animated:YES];
}
- (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];
                     }];
}
@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;
}
- (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];
                     }];
}
Advanced iOS
Advanced iOS
@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
-(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];
}
topic #4
 audio shenanigans
you have a phone
 it makes a noise
   how do you do that?
CoreAudio

                                      Audio




            } {
                                     Services


                                     OpenAL        Headphones



                                   AVAudioPlayer    Speaker
Your code                 Audio
                         Session
                                      Audio           USB
                                      Queue

                                      Audio
                                       Unit         Bluetooth



            Audio File
             Services
Audio Session                                      Services




                                                              }                              {
                                                                             OpenAL              Phones

                                                                             AVAudioPlayer
                                                                                                 Speaker
                                                       Code       Session

                                                                              Queue               USB

                                                                                Unit               BT




                                              Phone Call



         Describe type
 App                         Doing my
         of audio use &                     INTERRUPTION!                   Resume
starts                      audio thing
          start session




                               Other apps
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
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.
AVAudioPlayer                                  Services




                                        }                             {
                                                      OpenAL              Phones

                                                      AVAudioPlayer
                                                                          Speaker
                                 Code       Session

                                                       Queue               USB

                                                         Unit               BT




“Apple recommends that you use
this class for audio playback unless




                                ”
   you are playing audio captured
 from a network stream or require
        very low I/O latency.
AVAudioPlayer                              Services




                             }                             {
                                           OpenAL              Phones

                                           AVAudioPlayer
                                                               Speaker
                      Code       Session

                                            Queue               USB

                                              Unit               BT




play single sound
    (memory or file)

      seek
  control level
   read level
Services




                                       }                             {
                                                     OpenAL              Phones

                                                     AVAudioPlayer
                                                                         Speaker
                                Code       Session

                                                      Queue               USB

                                                        Unit               BT




 Audio                     Audio
 Queue                      Unit
low latency            lowest latency
                           plug-in
                         architecture
dealing with plain old PCM audio data
topic #5
  ninja tools
#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;
    . . .
TestFlight
Advanced iOS
(don’t reinvent)
http://cocoacontrols.com/
http://www.stackoverflow.com/
    http://www.github.com/
QA
                  ★★★




                    &
                  ★★★


Pete Goodliffe @petegoodliffe pete@goodliffe.net
@petegoodliffe
pete@goodliffe.net
goodliffe.blogspot.com
www.goodliffe.net
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 WEB
THANK YOU FOR READING // I HOPE IT WAS USEFUL
                                      Version 1.0 2012-08-14

More Related Content

KEY
jQTouch – Mobile Web Apps with HTML, CSS and JavaScript
PDF
Inside Flutter: Widgets, Elements, and RenderObjects
PDF
iOS 101 - Xcode, Objective-C, iOS APIs
KEY
Objective-C Crash Course for Web Developers
PPTX
Presentation on iOS
PDF
Chapter 10 - Views Part 2
PDF
Infinum Android Talks #03 - Android Design Best Practices - for Designers and...
PPTX
iPhone Development For Experienced Web Developers
jQTouch – Mobile Web Apps with HTML, CSS and JavaScript
Inside Flutter: Widgets, Elements, and RenderObjects
iOS 101 - Xcode, Objective-C, iOS APIs
Objective-C Crash Course for Web Developers
Presentation on iOS
Chapter 10 - Views Part 2
Infinum Android Talks #03 - Android Design Best Practices - for Designers and...
iPhone Development For Experienced Web Developers

Viewers also liked (19)

PDF
iOS Basic Development Day 2 - Objective-C 2.0 & iOS Framework
PDF
Introduction to objective c
PPTX
iOS Basic
PDF
Smart Lock for Password @ Game DevFest Bangkok 2015
PPT
Objective-C for iOS Application Development
PDF
Introduction to xcode
PDF
wtf is in Java/JDK/wtf7?
PDF
Deep dive into android restoration - DroidCon Paris 2014
PPT
Web Services with Objective-C
PDF
Advance Android Layout Walkthrough
PDF
iOS Development - A Beginner Guide
PDF
Introduction to Objective - C
PPTX
Apple iOS Introduction
PPTX
Ios operating system
PDF
200810 - iPhone Tutorial
PDF
Prenetics InsurTech Award Presentation
PPTX
Apple iOS
PDF
Никита Корчагин - Programming Apple iOS with Objective-C
iOS Basic Development Day 2 - Objective-C 2.0 & iOS Framework
Introduction to objective c
iOS Basic
Smart Lock for Password @ Game DevFest Bangkok 2015
Objective-C for iOS Application Development
Introduction to xcode
wtf is in Java/JDK/wtf7?
Deep dive into android restoration - DroidCon Paris 2014
Web Services with Objective-C
Advance Android Layout Walkthrough
iOS Development - A Beginner Guide
Introduction to Objective - C
Apple iOS Introduction
Ios operating system
200810 - iPhone Tutorial
Prenetics InsurTech Award Presentation
Apple iOS
Никита Корчагин - Programming Apple iOS with Objective-C
Ad

Similar to Advanced iOS (20)

PDF
MOPCON 2014 - Best software architecture in app development
PDF
Assignment2 B Walkthrough
PDF
Ios 7 Programming Cookbook 2nd Edition Vandad Nahavandipoor
PPTX
iOS UI best practices
PPTX
Code camp 2011 Getting Started with IOS, Una Daly
PDF
Programming iOS 14 11th Edition Matt Neuburg
PDF
Hi performance table views with QuartzCore and CoreText
PDF
iOS 7 Human Interface Guidelines
PPTX
IOS Swift language 1st Tutorial
PDF
HCI Guidelines for iOS Platforms
PPTX
Hello world ios v1
PDF
PDF
IOS APPs Revision
PDF
iOS 7 Programming Cookbook 2nd Edition Vandad Nahavandipoor
PDF
iOS 7 Programming Cookbook 2nd Edition Vandad Nahavandipoor
PDF
Casestudy
PDF
Mobile hig
PDF
iOS 7 in Action 1st Edition Brendan G. Lim
PDF
iOS 7 Human Interface Guidelines
PDF
iOS 7 Programming Cookbook 2nd Edition Vandad Nahavandipoor
MOPCON 2014 - Best software architecture in app development
Assignment2 B Walkthrough
Ios 7 Programming Cookbook 2nd Edition Vandad Nahavandipoor
iOS UI best practices
Code camp 2011 Getting Started with IOS, Una Daly
Programming iOS 14 11th Edition Matt Neuburg
Hi performance table views with QuartzCore and CoreText
iOS 7 Human Interface Guidelines
IOS Swift language 1st Tutorial
HCI Guidelines for iOS Platforms
Hello world ios v1
IOS APPs Revision
iOS 7 Programming Cookbook 2nd Edition Vandad Nahavandipoor
iOS 7 Programming Cookbook 2nd Edition Vandad Nahavandipoor
Casestudy
Mobile hig
iOS 7 in Action 1st Edition Brendan G. Lim
iOS 7 Human Interface Guidelines
iOS 7 Programming Cookbook 2nd Edition Vandad Nahavandipoor
Ad

More from Pete Goodliffe (16)

PDF
Becoming a Better Programmer
PDF
Words in Code
PDF
Running Effective Worship Rehearsals
PDF
Becoming a Better Programmer (2013)
PDF
Design Sins
PDF
Version Control Done Right
PDF
Getting Into Git
PDF
C++: The Cathedral and the Bizarre
PDF
iOS Development (BCS Newcastle)
PDF
Three Objectionable Things
PDF
Coping with Complexity
PDF
Manyfestos
PDF
iOS Development (BCS Edinburgh 2011-03-09)
PDF
Stood at the bottom of a mountain looking up
PDF
iPhone development: A brief introduction
PDF
Legacy Code: Learning To Live With It
Becoming a Better Programmer
Words in Code
Running Effective Worship Rehearsals
Becoming a Better Programmer (2013)
Design Sins
Version Control Done Right
Getting Into Git
C++: The Cathedral and the Bizarre
iOS Development (BCS Newcastle)
Three Objectionable Things
Coping with Complexity
Manyfestos
iOS Development (BCS Edinburgh 2011-03-09)
Stood at the bottom of a mountain looking up
iPhone development: A brief introduction
Legacy Code: Learning To Live With It

Recently uploaded (20)

PDF
Electronic commerce courselecture one. Pdf
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
Spectroscopy.pptx food analysis technology
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
KodekX | Application Modernization Development
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
cuic standard and advanced reporting.pdf
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
Cloud computing and distributed systems.
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
Electronic commerce courselecture one. Pdf
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Reach Out and Touch Someone: Haptics and Empathic Computing
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
20250228 LYD VKU AI Blended-Learning.pptx
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Digital-Transformation-Roadmap-for-Companies.pptx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
The Rise and Fall of 3GPP – Time for a Sabbatical?
Spectroscopy.pptx food analysis technology
Dropbox Q2 2025 Financial Results & Investor Presentation
Network Security Unit 5.pdf for BCA BBA.
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
KodekX | Application Modernization Development
MIND Revenue Release Quarter 2 2025 Press Release
cuic standard and advanced reporting.pdf
MYSQL Presentation for SQL database connectivity
Cloud computing and distributed systems.
“AI and Expert System Decision Support & Business Intelligence Systems”

Advanced iOS

  • 1. mobile east june 2012 advanced iOS getting your knees wet, rather then your ankles PETE GOODLIFFE pete@goodliffe.net @petegoodliffe
  • 2. @petegoodliffe pete@goodliffe.net goodliffe.blogspot.com www.goodliffe.net PE TE G OODL PROGRAMME IFFE R / AUTHOR / COLUMNIST / TEACHER ★ CON SCIENTIOUS CODER
  • 4. me
  • 5. you
  • 7. 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 this 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
  • 8. 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 this 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
  • 13. advanced what does that mean?
  • 14. iPhone objective C 101 cocoa
  • 15. iPhone objective C 101 cocoa ? iPhone 201
  • 16. topic #1 user interface kung foo topic #2 ”advanced” coding techniques topic #3 getting animated topic #4 audio shenanigans topic #5 ninja tools
  • 19. user interface advice don’t be clever don’t be cute be idiomatic
  • 26. https://github.com/enormego/EGOTableViewPullRefresh https://github.com/leah/PullToRefresh https://github.com/shiki/STableViewController
  • 34. ui joy is in the details
  • 40. No Carrier 00:49 Not Charging UIBarButtonItem Mahjong Score Book UINavigationBar UIScrollView UIView (parent) Custom UIView
  • 41. No Carrier 00:49 Not Charging Mahjong Score Book Gradient
  • 42. No C arrie r 19:2 4 100% ✘
  • 43. No C arrie r 19:2 4 100% ✘
  • 44. No C arrie r 19:2 4 100% pass touches through ✔
  • 45. No C arrie r 19:2 4 100%
  • 46. No C arrie r 19:2 4 100%
  • 47. @interface FadeView : UIView @end
  • 48. @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
  • 50. toolbar background button background normal pressed highlighted & highlighted pressed
  • 51. - (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]; }
  • 52. - (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]; } }
  • 54.
  • 56. AVAudioPlayer ✔ Play theme tune ✘ Fade in/out
  • 58. PROBLEM#1 a nice API
  • 60. AVAudioPlayer *player = … ; [player play]; [player stop];
  • 61. AVAudioPlayer *player = … ; [player play]; [player stop]; [player playWithFadeDuration:1.0]; [player stopWithFadeDuration:1.0];
  • 62. @interface AVAudioPlayer { … } - (id) initWithContentsOfURL:(NSURL*)url; - (void) play; - (void) stop; @end
  • 63. @interface AVAudioPlayer { … } - (id) initWithContentsOfURL:(NSURL*)url; - (void) play; - (void) stop; - (void) playWithFadeDuration:(float)secs; - (void) stopWithFadeDuration:(float)secs; @end
  • 64. @interface AVAudioPlayer (Fades) - (void) playWithFadeDuration:(float)secs; - (void) stopWithFadeDuration:(float)secs; @end
  • 65. @implementation AVAudioPlayer (Fades) - (void) playWithFadeDuration:(float)secs { // magic happens here } - (void) stopWithFadeDuration:(float)secs { // clever stuff in here } @end
  • 66. AVAudioPlayer *player = … ; [player play]; [player stop]; [player playWithFadeDuration:1.0]; [player stopWithFadeDuration:1.0]; ✔
  • 67. PROBLEM#2 we need some new instance variables
  • 68. associative references (a posh name for cheating)
  • 69. static const char volumeLevelKey = ‘Q’; NSNumber *number = [NSNumber numberWithFloat:1.0]; objc_setAssociatedObject(self, &volumeLevelKey, number, OBJ_ASSOCIATION_RETAIN_NONATOMIC);
  • 70. NSNumber *number = (NSNumber*)objc_getAssociatedObject(self, &volumeLevelKey);
  • 71. @interface AVAudioPlayer (Fades) - (void) playWithFadeDuration:(float)secs; - (void) stopWithFadeDuration:(float)secs; @property float fadeVolume; @end
  • 72. - (void) fadeVolume { // gibberish in here } - (void) setFadeVolume { // cobblers in here } ✔ float fadeVolume = player.fadeVolume;
  • 73. PROBLEM#3 we need to use another fancy language feature
  • 74. blocks (because C++ isn’t the only cool language)
  • 75. PROBLEM#3 when a fade has completed, do “something”
  • 77. typedef void (^FadeCompleteBlock)(); - (void) fadeToVolume:(float)volume withDuration:(float)secs andThen:(FadeCompleteBlock)action
  • 78. 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; }];
  • 79. http://goodliffe.blogspot.co.uk/2011/04/ios-fading-avaudioplayer.html https://gitorious.org/audioplayerwithfade/audioplayerwithfade
  • 80. topic #3 getting animated
  • 83. - (void) documentsViewControllerSelected:(NSString*)file fromRect:(CGRect)from; { lastDocumentRect = from; scoresViewController.filename = file; [scoresViewController animateAppearingFrom:from afterDelay:0.1]; [window setRootViewController:scoresViewController animated:YES]; }
  • 84. - (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]; }]; }
  • 85. @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; }
  • 86. - (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]; }]; }
  • 89. @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
  • 90. -(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]; }
  • 91. topic #4 audio shenanigans
  • 92. you have a phone it makes a noise how do you do that?
  • 93. CoreAudio Audio } { Services OpenAL Headphones AVAudioPlayer Speaker Your code Audio Session Audio USB Queue Audio Unit Bluetooth Audio File Services
  • 94. Audio Session Services } { OpenAL Phones AVAudioPlayer Speaker Code Session Queue USB Unit BT Phone Call Describe type App Doing my of audio use & INTERRUPTION! Resume starts audio thing start session Other apps
  • 95. 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
  • 96. 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.
  • 97. AVAudioPlayer Services } { OpenAL Phones AVAudioPlayer Speaker Code Session Queue USB Unit BT “Apple recommends that you use this class for audio playback unless ” you are playing audio captured from a network stream or require very low I/O latency.
  • 98. AVAudioPlayer Services } { OpenAL Phones AVAudioPlayer Speaker Code Session Queue USB Unit BT play single sound (memory or file) seek control level read level
  • 99. Services } { OpenAL Phones AVAudioPlayer Speaker Code Session Queue USB Unit BT Audio Audio Queue Unit low latency lowest latency plug-in architecture dealing with plain old PCM audio data
  • 100. topic #5 ninja tools
  • 101. #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; . . .
  • 106. QA ★★★ & ★★★ Pete Goodliffe @petegoodliffe pete@goodliffe.net
  • 108. 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 WEB THANK YOU FOR READING // I HOPE IT WAS USEFUL Version 1.0 2012-08-14