swift – iOS background activity fails to run
[ad_1]
I’m attempting to create a background activity whereby my app contacts an API endpoint each quarter-hour and if the response accommodates a sure worth the background activity will show an area notification. My app is rarely contacting the API endpoint, which leads me to imagine the background activity is rarely working.
The API is my very own, and solely helps http site visitors proper now. I’ve created an data.plist
entry for App Transport Safety Settings
setting Permit Arbitrary Masses
equal to YES
.
I’ve additionally added a Background Modes
configuration in Signing & Capabilities
enabling Background fetch
and added a Permitted background activity scheduler identifier
entry in my data.plist
.
A minimal reproducible instance follows. Notice that I’ve swapped out the URL for my API with one thing free and public, so anybody ought to have the ability to run this with out worrying about authentication or API keys. This MRE additionally fails, however I can not monitor the endpoint’s site visitors to see if my app has ever contacted it.
BackgroundAlertApp.swift:
class AppDelegate: NSObject, UIApplicationDelegate {
func software(_ software: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
/*
Entry the person notification middle and request permission to ship notifications
*/
let middle = UNUserNotificationCenter.present()
middle.requestAuthorization(choices: [.alert, .sound]) { granted, error in
if let error = error {
print(error)
}
}
/*
Outline an motion permitting the person to dismiss the air high quality alert and add this motion
to an AirQualityNotification Class of notifications.
*/
let dismissAction = UNNotificationAction(identifier: "DISMISS", title: "OK", choices: [])
let airQualityNotification = UNNotificationCategory(identifier: "AIR_QUALITY", actions: [dismissAction], intentIdentifiers: [])
middle.setNotificationCategories([airQualityNotification])
/*
Register the background activity answerable for scheduling API calls to verify for an alert
*/
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.my_org.bundle_id.apiRequest", utilizing: nil) { activity in
self.performApiRequest(activity: activity as! BGAppRefreshTask)
}
return true
}
func scheduleApiRequest() {
let request = BGAppRefreshTaskRequest(identifier: "com.my_org.bundle_id.apiRequest")
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
do {
strive BGTaskScheduler.shared.submit(request)
} catch {
print("Couldn't schedule API request: (error)")
}
}
func performApiRequest(activity: BGAppRefreshTask) {
scheduleApiRequest()
let operation = ApiRequestOperation()
let operationQueue = OperationQueue()
activity.expirationHandler = {
operation.cancel()
}
operation.completionBlock = {
activity.setTaskCompleted(success: !operation.isCancelled)
}
operationQueue.addOperation(operation)
}
}
class ApiRequestOperation: Operation, UNUserNotificationCenterDelegate {
var apiResponse: Response?
func requestAlert() {
let api = URL(string: "https://api.agify.io/?title=john")
let sesson = URLSession(configuration: .default)
let activity = sesson.dataTask(with: api!) { knowledge, response, error in
if error == nil {
let decoder = JSONDecoder()
if let safeData = knowledge {
do {
let outcomes = strive decoder.decode(Response.self, from: safeData)
self.apiResponse = outcomes
print(outcomes)
if self.apiResponse!.title == "john" {
// present distant noticifaction as alert
let content material = UNMutableNotificationContent()
content material.title = "Air High quality Alert"
content material.physique = "(self.apiResponse!.title) is predicted to be (self.apiResponse!.age) years outdated and has been searched (self.apiResponse!.rely) occasions."
content material.categoryIdentifier = "AIR_QUALITY"
content material.sound = UNNotificationSound.default
let request = UNNotificationRequest(identifier: "AIR_QUALITY", content material: content material, set off: nil)
}
} catch {
print(error)
}
}
}
}
activity.resume()
}
func userNotificationCenter(
_ middle: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
completionHandler()
}
}
When penning this code I referenced the next Apple Documentation:
Utilizing Background duties to replace your app
[ad_2]