ios 7 url session & motion fx apis
DESCRIPTION
Introduction to background downloading and parallax effects (new iOS 7 features), including sample code.TRANSCRIPT
iOS 7 URL Session & Motion FXAPIs
@rsebbe@creaceed@cocoaheadsBE
URL SESSION
•New in iOS 7 and OS X 10.9
• Preferred API for (up/down-)loading URL contents
•Many use case scenarios. Get URL contents as NSData or file, background download/upload, cookie/cache/authentication handling, etc.
• This talk is about background downloads only
• You should check AFNetworking 2.0. Was just released!
URL SESSION
• URL Session types: Default, Ephemeral, Background
• App initiates a download (in process)
• iOS handles it for you (out of process)
• Apps gets notified/restarted when finished
URL SESSION
•What happens when:
- App is iOS-terminated in the background? Download continues.
- Rebooting the phone? Download continues.
- App killed by user? Download is aborted.
• And when download finishes?
- Your app is restarted (if not running) to handle it.
URL SESSIONNSURLSession
NSURLSessionDownloadTaskcom.creaceed.iprizmo.ocrdata
com.creaceed.iprizmo.voices
NSURLSession
NSURLSessionDownloadTask
NSURLSessionDownloadTask
Dutch OCR Data.zip
French OCR Data.zip
Graham (British English Voice).zip
URL SESSIONPrepare Session
Initiate Download Task
App Killed (for some reason)
Download finishes
App restarted
Prepare Session (same id)
[retrieve pending tasks, if needed]
Notify Completion
Handle download
URL SESSIONurlSessionQueue = [NSOperationQueue mainQueue];! ! !configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:! [PRSpeechController urlSessionIdentifier]];configuration.discretionary = YES;
urlSession = [NSURLSession sessionWithConfiguration:configuration ! delegate:self delegateQueue:urlSessionQueue];
[self.urlSession getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {! for(NSURLSessionDownloadTask *task in downloadTasks) {
! if(task.state == NSURLSessionTaskStateRunning) {! ! }! }}];
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)cur totalBytesExpectedToWrite:(int64_t)tot
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffsetexpectedTotalBytes:(int64_t)expectedTotalBytes
URL SESSION- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{! if([identifier isEqualToString:[PRSpeechController urlSessionIdentifier]])! {! ! EX_ASSERT(self.speechController != nil);! ! self.speechController.backgroundDownloadCompletionHandler = completionHandler;! }}
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {! // do some work, then:! if(self.backgroundDownloadCompletionHandler) {! ! self.backgroundDownloadCompletionHandler();! ! self.backgroundDownloadCompletionHandler = nil;! }}
TIPS & TRICKS• Download tasks cannot use completion handler for background
session. Why? Because app process can be killed at any time! Use delegate methods.
• You should immediately copy the downloaded file somewhere.
• You need to identify the finished download. Parse the URL? No. There’s a better (& well hidden) solution:
• If your app is restarted, you can delay the call to the OS-passed completion handler until you have finished processing.
[NSURLProtocol setProperty:voiceKey forKey:@"voiceKey" inRequest:request];
MOTION EFFECTS
MOTION EFFECTS• Parallax: Objects move at
different speed depending on their distance to viewer
• iOS does not track your eyes, but gyroscope provides a good approximation of relative viewer position.
• With that information, you can simulate the parallax effect by moving contents
A
B
MOTION EFFECTS
• UIMotionEffect, that you can subclass@interface CRParallaxMotionEffect : UIMotionEffect
- (NSDictionary *)keyPathsAndRelativeValuesForViewerOffset:(UIOffset)viewerOffset {! return @{@”center”: [NSValue valueWithCGPoint: CGPointMake(viewerOffset.horizontal*10, viewerOffset.vertical*10)]};}
[view addMotionEffect:parallaxEffect];
MOTION EFFECTS• UIInterpolatingMotionEffect, to interpolate values along X or Y
axis
• UIMotionEffectGroup, to sync multiple motion effects together
! UIInterpolatingMotionEffect *imfx = [[UIInterpolatingMotionEffect alloc] ! ! ! initWithKeyPath:@"center"
! type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];! imfx.maximumRelativeValue = [NSValue valueWithCGPoint:CGPointMake(15,0)];! imfx.minimumRelativeValue = [NSValue valueWithCGPoint:CGPointMake(-15,0)];! [view addMotionEffect:imfx];
! UIInterpolatingMotionEffect *imfy = [[UIInterpolatingMotionEffect alloc] ! ! ! initWithKeyPath:@"center" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];! imfy.maximumRelativeValue = [NSValue valueWithCGPoint:CGPointMake(0,15)];! imfy.minimumRelativeValue = [NSValue valueWithCGPoint:CGPointMake(0,-15)];! [view addMotionEffect:imfy];
TIPS & TRICKS
•We used the first approach, add effect with single line of code
• CRParallaxMotionEffect available on GitHub: http://bit.ly/prllx
[view addMotionEffect:[CRParallaxMotionEffect parallaxEffectWithAmplitude:10.0]];
TIPS & TRICKS
•Make moving views bigger!
• For scrollviews, use ‘contentOffset’, but with motion in the opposite direction (negate amplitude)
•Not only points, but also colors, shadow offset, layer properties, 2D and 3D transforms.
view.frame = CGRectInset(container.bounds, -10.0, -10.0);
DEMO