+ All Categories
Home > Mobile > Nikita Tuk: Handling background processes in iOS: problems & solutions

Nikita Tuk: Handling background processes in iOS: problems & solutions

Date post: 22-Jan-2018
Category:
Upload: mdevtalk
View: 108 times
Download: 0 times
Share this document with a friend
31
Transcript
Page 1: Nikita Tuk: Handling background processes in iOS: problems & solutions
Page 2: Nikita Tuk: Handling background processes in iOS: problems & solutions

NIKITA TUKiOS Developer, Coins.ph Toptal Speakers Network

Page 3: Nikita Tuk: Handling background processes in iOS: problems & solutions

Handling background processes in iOS:

problems & solutions

Page 4: Nikita Tuk: Handling background processes in iOS: problems & solutions

Yandex.Disk

Autoupload Offline

Page 5: Nikita Tuk: Handling background processes in iOS: problems & solutions

• The App Life Cycle before iOS7 • The App Life Cycle on iOS now • Experiments & limitations • Testing • Our approach

Agenda

Page 6: Nikita Tuk: Handling background processes in iOS: problems & solutions

Not Running

ForegroundSuspended

Background

Page 7: Nikita Tuk: Handling background processes in iOS: problems & solutions

Not Running

ForegroundSuspended

Background

NSURLSession Silent notifications

Background Fetch

Page 8: Nikita Tuk: Handling background processes in iOS: problems & solutions

Silent notificationsaps { content-available: 1 alert: {...} sound: ... badge: ... }

30 sec

Page 9: Nikita Tuk: Handling background processes in iOS: problems & solutions

Background fetch <key>UIBackgroundModes</key> <array> <string>fetch</string> </array> 30 sec

UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)

Page 10: Nikita Tuk: Handling background processes in iOS: problems & solutions

NSURLConnection

ConnectionConfiguration

ConnectionConfiguration

ConnectionConfiguration

Page 11: Nikita Tuk: Handling background processes in iOS: problems & solutions

NSURLSessionNSURLSession

Configuration

NSURLSessionTask

NSURLSessionTask

NSURLSessionTask

NSURLSessionDataTask

NSURLSessionUploadTask

NSURLSessionDownloadTaskNSURLSessionStreamTask

background

background

Page 12: Nikita Tuk: Handling background processes in iOS: problems & solutions

nsurlsessiond

Behind the scenes

task

task

30 sec

Page 13: Nikita Tuk: Handling background processes in iOS: problems & solutions

Behind the scenesfunc application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)

enum UIBackgroundFetchResult: UInt { case newData case noData case failed }

Page 14: Nikita Tuk: Handling background processes in iOS: problems & solutions

Experiments

iOS8 iOS10

Page 15: Nikita Tuk: Handling background processes in iOS: problems & solutions

• Call completion handler as early as possible • Save battery life • Always call completion handler

Experiments

Page 16: Nikita Tuk: Handling background processes in iOS: problems & solutions

Experiments

00pm 03am 06am 09am 12am 03pm 06pm 09pm

Page 17: Nikita Tuk: Handling background processes in iOS: problems & solutions

Experiments

00pm 03am 06am 09am 12am 03pm 06pm 09pm 11pm

Page 18: Nikita Tuk: Handling background processes in iOS: problems & solutions

Experiments

00pm 03am 06am 09am 12am 03pm 06pm 09pm 11pm

Page 19: Nikita Tuk: Handling background processes in iOS: problems & solutions

Limitations

Push notifications

Page 20: Nikita Tuk: Handling background processes in iOS: problems & solutions

Limitations

Page 21: Nikita Tuk: Handling background processes in iOS: problems & solutions

Testing

Charles

Page 22: Nikita Tuk: Handling background processes in iOS: problems & solutions

Testingprotocol URLSessionDataTaskProtocol { func resume() }

extension NSURLSessionDataTask: URLSessionDataTaskProtocol { }

protocol URLSessionProtocol { func dataTaskWithURL(url: NSURL, completionHandler: DataTaskResult) -> URLSessionDataTaskProtocol }

extension NSURLSession: URLSessionProtocol { func dataTaskWithURL(url: NSURL, completionHandler: DataTaskResult) -> URLSessionDataTaskProtocol { return (dataTaskWithURL(url, completionHandler: completionHandler) as NSURLSessionDataTask) as URLSessionDataTaskProtocol } }

Page 23: Nikita Tuk: Handling background processes in iOS: problems & solutions

Testingclass APIManager { private let session: URLSessionProtocol init(session: URLSessionProtocol) { self.session = session ... }

// Tests:let manager = APIManager(session: MockURLSession)

// App: let manager = APIManager(session: RealURLSession)

Page 24: Nikita Tuk: Handling background processes in iOS: problems & solutions

Our approach• Photos framework challenges • Uploading state machine • Modular architecture • Ensuring completion handler invocation • App restoration

Page 25: Nikita Tuk: Handling background processes in iOS: problems & solutions

Photos framework challenges// Creates an upload task with the given request. The body of the request will be created from the file referenced by fileURL func uploadTask(with request: URLRequest, fromFile fileURL: URL) -> URLSessionUploadTask

PHAsset • no URL • can be burst/live photo • can have filters (stored as original photo + delta) • need to calculate hash before uploading • can be stored in iCloud

Page 26: Nikita Tuk: Handling background processes in iOS: problems & solutions

Photos framework challenges// Copy PHAsset to sandbox PHAssetResourceManager.default().writeData(for: resource, toFile: filePathURL, options: options) { error in completion(error) }

Calculating PHAsset hash before uploading/uploading by chunks

OR

Page 27: Nikita Tuk: Handling background processes in iOS: problems & solutions

Uploading state machine

Page 28: Nikita Tuk: Handling background processes in iOS: problems & solutions

Modular architecture

NSURLSession NSURLSession NSURLSession

Data Upload (background)

Download (background)

Page 29: Nikita Tuk: Handling background processes in iOS: problems & solutions

Ensuring completion handler invocation

// Remote notifications func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)

// Tells the delegate that events related to a URL session are waiting to be processed.func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void)

// Tells the app that it can begin a fetch operation if it has data to download.func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)

Completion manager

Page 30: Nikita Tuk: Handling background processes in iOS: problems & solutions

nsurlsessiond

App restoration

task

Another session

var taskDescription: String

Page 31: Nikita Tuk: Handling background processes in iOS: problems & solutions

WWW.MDEVTALK.CZ

mdevtalk


Recommended