Wednesday, 7 September 2011

iOSDev UK: Using TDD to write an iOS App

Graham Lee, professional in-betweener, @iamleeg

Or, “What is TDD and why should you use it?”

  • discovering bugs is not the point of testing at all
    • instead, you are proving that there aren’t bugs
  • once we’ve fixed bugs, we don’t want to see them ever again
    • tests can ensure that regressions don’t come back
  • TDD allows us to prevent bugs from ever happening!
    • you won’t prove that the app works how the customer expects, but you will at least prove that it works how you expect it to work…
  • TDD imposes black-box thinking for the developer
    • makes you think about how the code should be designed and scoped
  • accurate planning: we know how much we’ve done
    • and we can be honest how much we have done
  • TDD does not:
    • ensure that the developer understood the requirements!
    • ensure that the requirements remain static
    • ensure that pieces work together (unless you add integration tests)
  • tests should be short and have descriptive, English names
    • e.g. testDatesOnTheSameDayAreConsideredSame
    • general pattern
  • tests should be fast — well under a hundredth of a second each, so a second or so for all of them
    • avoid integration tests in unit testing since they take too long
    • don’t interrupt your concentration by waiting for tests
  • as a result, your classes will be smaller and have obvious effects
    • any side-effects are few and easy to predict
    • if your test fixture gets big, then that’s a sign that you need to refactor (possibly including the tests!)
  • TDD encourages “tell, don’t ask” configuration
    • inversion of control
    • pass in helper data rather than discover it internally
  • avoiding testing everything at once:
    • use fake objects (with same interfaces) to provide simulated interactions
    • use mock objects to record and verify interactions
  • Objective-C mock frameworks:
  • Code coverage is useful for adding tests to an existing app
    • Not so useful for building new code
    • If you’re not covering code with TDD, then you’re kind of cheating yourself

Q&A

  • @pilky knows about using the accessibility framework to write automated UI tests using javascript
  • can use XCodeBuild to run unit tests from command line
  • use GHUnit instead of built-in OCUnit to output JUnit XML reports
  • iOS Enterprise Development — O’Reilly book by James Turner
    • includes lots of useful
  • squish automated GUI testing?
  • test code linking…
    • app should be plugin host, providing linked libraries
    • but it doesn’t work — have to link yourself from test code

iOSDev UK: Building Custom Controls with UIView

Rory Prior, ThinkMac Software, @roryprior

  • generally subclass UIView directly
    • can subclass other controls, but things might not happen how you expect since lots of things happen in the background
    • and you may need to use private APIs…
  • override methods:
    • initWithFrame for programmatic creation
    • initWithCoder for IB-created views
    • drawRect for actual drawing
  • UIKit uses top left as origin
    • but CoreGraphics uses bottom left…
  • adding UIImageView is easy
    • but quite heavyweight
    • instead can draw a UIImage directly
  • similarly, can use UILabel or draw string directly
    • NSString drawAtPoint:withFont:
    • NSString drawInRect:withFont:
    • NSString sizeWithFont:
  • drawing shapes:
    • CoreGraphics (nasty low-level C stuff :-) )
    • UIBezierPath (introduced in iOS 3.2)
  • complicated graphics often still done better by using bitmaps — UIBezierPath can be processor-intensive for lots of lines
  • UIColor can fill in patterns as well as flat colour

user interaction

  • override UIResponder methods to detect touches
  • you’ll need UIGestureRecognizers to detect swipes, pinches, etc
  • but use sub-views of UIButton etc to make thins much easier
  • see slides for nice example of adding UIResponder and UIGestureRecognizer
  • use the delegate pattern to send feedback from your view to the rest of your app

iOSDev UK: Beyond NSLog

Tim Isted, @timisted

NSLog, XCode and gdb

  • useful macros for logging:
    • __FILE__ (full path)
    • __LINE__
    • __FUNCTION__ (and __PRETTY_FUNCTION__)
  • NSStringFromSelector(_cmd) gives you current message
    • Lots of these useful NSString functions, e.g. NSStringFromCGRect
  • use macros in log define
    • non-debug version should be something like: TILog(...) do {} while (0)
  • XCode preferences > Behaviours
    • Run starts — can choose what displays
  • XCode also has a variables view, hidden in the next pane of the debugger
  • add breakpoints for exceptions or non-source code by using little plus button at bottom of breakpoints pane
  • breakpoints have really useful options
    • log to console on hit (with auto hit count)
    • continue automatically
    • only do stuff on conditions
  • gdb commands:
    • s = step = Step In
    • m = Step Over
    • c = Continue
    • p = Print
    • po = Print Object
  • debugging Core Data: use [self valueForKey:@"propertyName"]
  • can use addresses instead of variable names in po
  • can make breakpoints user-specific instead of project-specific

Instruments

  • Time Profiler — great for catching infinite loops!
    • shows you time spent at certain places in call stack
    • tick the “Show Obj-C Only” checkbox
    • look for purple user symbols!
  • Heap Shot tool find leaks
  • quite a few WWDC videos on Instruments

iOSDev UK: Programming iOS Sensors

Alasdair Allan, Babilim Light Industries

http://programmingiphonesensors.com/

Magnetometer (it’s not a digital compass!)

  • 4th gen iPod Touch doesn’t have magnetometer
    • so no outside AR apps without markers
  • UIAccelerometer API newly deprecated for CoreMotion in iOS5
  • if you want compass heading but not location, then just start up [locationManager startUpdatingHeading]
    • you won’t get location updates warning
  • however, magnetic north varies across the world
    • there’s a big lookup table in the iPhone that can translate the magnetic heading into true north
    • so you need actual location to work this out
  • watch out for device orientation: magnetometer always reports heading pointing out of top of device
    • need to rotate according to device orientation…
  • local magnetic anomalies cause a fluctuating magnetic field — which is when it tells you to wave your device around
  • Earth’s magnetic pole is a quadrapole, not a bipole — it swaps over every now and then and the north pole goes south

Gyroscope & Accelerometer (CoreMotion)

  • iPhone 4 has more bits in its accelerometer sampler
  • combining gyroscope and accelerometer provides very accurate device attitude
  • if there’s no natural timer in your app, then you may have to use the push API
    • otherwise much easier to use pull API
  • CMMotionManager should be treated as a singleton (but API allows you to create multiples…)
  • monitoring does take a lot of CPU, so remember to stop it when you’re finished
    • device motion at 100 samples/sec uses 65% of iPhone 4 CPU
    • see “Pushing Device Motion” slide
  • you can fetch a frame of reference and then work out attitude relative to that

AR Toolkits

External accessories