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

Post on 22-Jan-2018

108 Views

Category:

Mobile

0 Downloads

Preview:

Click to see full reader

Transcript

NIKITA TUKiOS Developer, Coins.ph Toptal Speakers Network

Handling background processes in iOS:

problems & solutions

Yandex.Disk

Autoupload Offline

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

Agenda

Not Running

ForegroundSuspended

Background

Not Running

ForegroundSuspended

Background

NSURLSession Silent notifications

Background Fetch

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

30 sec

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

UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)

NSURLConnection

ConnectionConfiguration

ConnectionConfiguration

ConnectionConfiguration

NSURLSessionNSURLSession

Configuration

NSURLSessionTask

NSURLSessionTask

NSURLSessionTask

NSURLSessionDataTask

NSURLSessionUploadTask

NSURLSessionDownloadTaskNSURLSessionStreamTask

background

background

nsurlsessiond

Behind the scenes

task

task

30 sec

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

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

Experiments

iOS8 iOS10

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

Experiments

Experiments

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

Experiments

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

Experiments

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

Limitations

Push notifications

Limitations

Testing

Charles

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

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

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

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

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

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

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

Uploading state machine

Modular architecture

NSURLSession NSURLSession NSURLSession

Data Upload (background)

Download (background)

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

nsurlsessiond

App restoration

task

Another session

var taskDescription: String

WWW.MDEVTALK.CZ

mdevtalk

top related