Our application allows people to back up their content (Photos / Videos) into the cloud. To have our backup working more efficiently while the application is in background, we have implemented background tasks. We schedule refresh and processing task (BGProcessingTask). Processing task is used for uploading content. We are looking into improving the number of triggers for processing tasks. There are one or two triggers in 24 hours but not as frequently as we expected. We did an exercise to compare google photo v/s our application: the time google gets to execute in background is 6 times more than personal cloud. What are the possible reason for this difference.
See some sample code below.
We were lucky to have an appointment for a tech talk with @George V. from Apple and he suggested to use BGProcessingTask and set a flag to defer those tasks to run at a time where the device was less used. We do work with BGProcessingTask and are using the flags request.requiresNetworkConnectivity and request.requiresExternalPower.
Where it's not clear for me is: would setting requiresExternalPower to true prevent our app to run in background while the device is not plugged?
Any guidance would be appreciated :) Maybe @George, if you're available. Thanks
import UIKit
import BackgroundTasks
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
registerBgTasks()
//registerBatteryBgTasks()
return true
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
}
func registerBgTasks() {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.photos-upload",
using: nil) { (task) in
self.handleProcessingTask(task: task as! BGProcessingTask)
}
}
func registerBatteryBgTasks() {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.photos-upload-power",
using: nil) { (task) in
self.handlePowerProcessingTask(task: task as! BGProcessingTask)
}
}
func handlePowerProcessingTask(task: BGProcessingTask) {
let startTime = Date()
let taskId = task.identifier
if let url = URL(string: "https://imaging.nikon.com/lineup/dslr/df/sample.htm") {
let session = URLSession.shared
let networkTask = session.dataTask(with: url) { data, _, _ in
}
networkTask.resume()
}
task.expirationHandler = {
let endTime = Date()
let diffComponents = Calendar.current.dateComponents([.second], from: startTime, to: endTime)
let taskEntry = TaskEntry(taskId: taskId, taskLaunchedTime: DateUtility.readableDate(date: startTime),
taskExpirationTime: DateUtility.readableDate(date: endTime),
taskTotalTime: "\(diffComponents.second ?? 0)")
let fileName = "\(Date().timeIntervalSince1970)power.plist"
APIPreferencesLoaderPower.write(preferences: TaskArray(tasks: [taskEntry]), fileName: fileName)
task.setTaskCompleted(success: true)
}
}
func handleProcessingTask(task: BGProcessingTask) {
let startTime = Date()
let taskId = task.identifier
if let url = URL(string: "https://imaging.nikon.com/lineup/dslr/df/sample.htm") {
let session = URLSession.shared
let networkTask = session.dataTask(with: url) { data, _, _ in
}
networkTask.resume()
}
task.expirationHandler = {
let endTime = Date()
let diffComponents = Calendar.current.dateComponents([.second], from: startTime, to: endTime)
let taskEntry = TaskEntry(taskId: taskId, taskLaunchedTime: DateUtility.readableDate(date: startTime),
taskExpirationTime: DateUtility.readableDate(date: endTime),
taskTotalTime: "\(diffComponents.second ?? 0)")
let fileName = "\(Date().timeIntervalSince1970)normal.plist"
APIPreferencesLoader.write(preferences: TaskArray(tasks: [taskEntry]), fileName: fileName)
task.setTaskCompleted(success: true)
}
}
}
other class:
func scheduleBgTask() {
let request = BGProcessingTaskRequest(identifier: "com.synchronoss.cloud.photos-upload")
request.requiresNetworkConnectivity = true
request.requiresExternalPower = false
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("error")
}
}
func schedulePowerBgTask() {
let request = BGProcessingTaskRequest(identifier: "com.synchronoss.cloud.photos-upload-power")
request.requiresNetworkConnectivity = true
request.requiresExternalPower = true
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("error")
}
}