Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Real Life iOS Coding: a Journey Down the iOS De...

Real Life iOS Coding: a Journey Down the iOS Development Lane

When developing iOS apps, you'll have to overcome some small and major challenges. We'll take a short excursion into the real problems and solutions faced by an iOS developer. This journal-like trip will also share some tips and tricks and a small showcase of real life coding based on projects developed by the Milan-based digital agency Mutado.
(Italian video available at: http://vimeo.com/29137002 )

Luca Bernardi

May 08, 2012
Tweet

More Decks by Luca Bernardi

Other Decks in Technology

Transcript

  1. @”Hello, WhyMCA!” •Luca Bernardi •Works as iOS Developer @ Mutado

    •Currently taking my Master Degree in Computer Science •Stay in touch: •[email protected] •http://lucabernardi.com •@luka_bernardi
  2. Enhanced Logging Function •The DLog macro take advantage of __PRETTY_FUNCTION__

    and __LINE__ to print the function name and the line in where the macro is called •The macro definition depends on a compiler flag -DDEBUG •You can define the flag in “debug” build config and remove in “release” #ifdef DEBUG # define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); #else # define DLog(...) #endif
  3. [UIView recursiveDescription] •UIView undocumented API: -(NSString *)recursiveDescription; •Apple have talk

    about it in the tecnical note “iOS Debugging Magic” •http://developer.apple.com/library/ios/#technotes/tn2239/_index.html •Returns an NSString describing the entire view hierarchy rooted at the receiver
  4. [UIView recursiveDescription] •Output Example: NSLog(@"\n%@", [self.window recursiveDescription]); <UIWindow: 0x4d14330; frame

    = (0 0; 320 480); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x4d143e0>> | <UILayoutContainerView: 0x4d13b40; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x4d13b90>> | | <UINavigationTransitionView: 0x4d13ee0; frame = (0 0; 320 480); clipsToBounds = YES; autoresize = W +H; layer = <CALayer: 0x4d16200>> | | <UINavigationBar: 0x4d14c20; frame = (0 20; 320 44); clipsToBounds = YES; opaque = NO; autoresize = W; layer = <CALayer: 0x4d14e50>> | | | <UINavigationItemView: 0x4d14010; frame = (160 8; 0 27); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x4d14e00>>
  5. [UIView recursiveDescription] •Is a private API therefor remember to remove

    before submitting the App to Apple •Generate a Warning. You can remove it with a Category: @interface UIView (privateAPI) - (NSString *)recursiveDescription; @end
  6. Use Clang Static Analyzer ! •The Clang Static Analyzer is

    source code analysis tool that finds bugs in C and Objective-C programs •The Clang Static Analyzer can find bug like: •Memory Leak •Dead store •Using uninitalized or released variables •... •Early discovery of bugs •you have the chance to find bug while your hacking on code and not a month after
  7. Use Clang Static Analyzer ! •Why don’t static analyze at

    every build? •Xcode has a build option to run Clang Static Analysis tool on every build •Slow down a bit the build processes •False Positives can occours
  8. You can’t ignore memory warning •When memory dips below a

    safe threshold iOS notifies all running applications with a memory warning •In your application the following things happen: •The applicationDidReceiveMemoryWarning: method is called in your app delegate •The UIApplicationDidReceiveMemoryWarningNotification is posted •Each view controller calls its didReceiveMemoryWarning method
  9. •Focus on what happens in your in view controller AKA

    unload cycle : •[UIViewController didReceiveMemoryWarning] invokes [self setView:nil] •Only if view.superview is nil = the view isn’t visible •Then the viewDidUnload method is called You can’t ignore memory warning
  10. •You should: •in didReceiveMemoryWarning release: •cached and image data •Data

    structures associated with your view controller •in viewDidUnload method: •relinquish ownership of outlets calling the accessor method to set outlets to nil •release data that is not needed when your view is not visible •Keep a meaningful logic between viewDidLoad and viewDidUnload You can’t ignore memory warning
  11. •iOS Simulator uses all available memory on your Mac •iOS

    Simulator can fake a memory warning •Hardware > Simulate Memory Warning •Memory warning handling can’t be a feature but must be a requirement •Always keep in mind your view controller lifecycle You can’t ignore memory warning
  12. Image and Video to the Cloud •What’s wrong with Image

    and Video? •Photos taken with the iPhone’s camera use the industry-standard EXIF orientation flag to store rotation information •That means that the image data is always saved like the iPhone was in Landscape Right
  13. Image and Video to the Cloud •If you send the

    picked image to server side script that doesn’t take care of EXIF flag strange thing happens. •You need to pre-rotate the image before send it to you remote server •https://gist.github.com/968154
  14. Image and Video to the Cloud •The same happens to

    picked video •iOS stores the iPhone’s orientations when the rec button is tapped •Orientation is not stored as exif flag •You need to read the video transformation matrix in order to know the rotation •Don’t process the video on iPhone but tell to server the rotation
  15. Image and Video to the Cloud ! AVURLAsset *avAsset! !

    = [[AVURLAsset alloc] initWithURL:self.video options:nil]; ! AVAssetTrack* videoTrack! = [[avAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; ! CGAffineTransform txf! ! = [videoTrack preferredTransform]; ! CGFloat videoAngleInDegree = RadiansToDegrees(atan2(txf.b, txf.a)); ! [avAsset release]; 1)http://iphonedevelopment.blogspot.com/2008/10/demystifying-cgaffinetransform.html 2)http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/ drawingwithquartz2d/dq_affine/dq_affine.html
  16. UIScrollView trick - The problem •UIScrollView with pagination enabled stops

    at multiples of its frame width or height •But I want the scrollview’s subviews aligned in center
  17. UIScrollView trick - The solution •Make the UIScrollView width as

    wide as the page content •Set the UIScrollView clipsToBounds to NO
  18. UIScrollView trick - The solution •We still have a problem:

    if the user start dragging outside the scroll view it doesn’t scroll •Create a UIView subclass that will contain the UIScrollView and all it’s subviews •Will be as wide as the scrollable area •Will pass the touch down to UIScrollView
  19. UIScrollView trick - The solution •How can I “pass down”

    the touch? •Obviously you need to have a reference to UIScrollView •You should override - (UIView *)hitTest:withEvent: - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { ! ! ! if ([self pointInside:point withEvent:event]) { ! ! return scrollView; ! } ! return nil;! }
  20. One more thing... •Mutado always has a cup of coffee

    for a mobile developer •Don’t be shy we are based in central Milan, C.so Sempione 10 •We are always looking for talented mobile developers •Drop your CV at [email protected]