BGAppRefreshTask never called - ios

BGAppRefreshTask is not working, I marked the option of background fetch capability
The method inside BGTaskScheduler.shared.register is never called
my code:
private let appRefreshTaskId = "internetDisconnectionsId"
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 13, *) {
BGTaskScheduler.shared.register(forTaskWithIdentifier: appRefreshTaskId, using: nil) { task in
self.handleAppRefreshTask(task: task as! BGAppRefreshTask)
}
}
return true
}
func handleAppRefreshTask(task: BGAppRefreshTask) {
task.expirationHandler = {
print("Background Working")
task.setTaskCompleted(success: true)
}
}
#available(iOS 13.0, *)
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: appRefreshTaskId)
request.earliestBeginDate = Date(timeIntervalSinceNow: 2 * 60) // Refresh after 2 minutes.
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh task \(error.localizedDescription)")
}
}
func sceneDidEnterBackground(_ scene: UIScene) {
(UIApplication.shared.delegate as! AppDelegate).scheduleAppRefresh()
print("called")
}
I would love to understand where I am wrong

Related

When entering the application, no ads is displayed

I'm trying to display an ad with GADAppOpenAd
The problem is, every initial login to the application, no advertisement is displayed, only when I go to the background and return to the application, then an advertisement appears,
I'm trying to have an advertisement appear on the initial login as well
var appOpenAd: GADAppOpenAd?
var loadTime = Date()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
GADMobileAds.sharedInstance().start(completionHandler: nil)
requestAppOpenAd()
return true
}
extension AppDelegate:GADFullScreenContentDelegate {
func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
requestAppOpenAd()
}
func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
requestAppOpenAd()
}
func requestAppOpenAd() {
let request = GADRequest()
GADAppOpenAd.load(withAdUnitID: "ca-app-pub-3940256099942544/5662855259",
request: request,
orientation: UIInterfaceOrientation.portrait,
completionHandler: { (appOpenAdIn, _) in
self.appOpenAd = appOpenAdIn
self.appOpenAd?.fullScreenContentDelegate = self
self.loadTime = Date()
print("Ad is ready")
})
}
func tryToPresentAd() {
guard let rootViewController = (UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.window?.rootViewController else {
return
}
if let gOpenAd = self.appOpenAd, wasLoadTimeLessThanNHoursAgo(thresholdN: 4){
gOpenAd.present(fromRootViewController: rootViewController)
} else {
self.requestAppOpenAd()
}
}
func wasLoadTimeLessThanNHoursAgo(thresholdN: Int) -> Bool {
let now = Date()
let timeIntervalBetweenNowAndLoadTime = now.timeIntervalSince(self.loadTime)
let secondsPerHour = 3600.0
let intervalInHours = timeIntervalBetweenNowAndLoadTime / secondsPerHour
return intervalInHours < Double(thresholdN)
}
}
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func sceneDidBecomeActive(_ scene: UIScene) {
(UIApplication.shared.delegate as? AppDelegate)?.tryToPresentAd()
}
}

BGTaskScheduler.shared.register Not Working Swift 5

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.fetch.background", using: nil) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
return true
}
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: "com.fetch.background")
// Fetch no earlier than 15 minutes from now.
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: \(error)")
}
}
func handleAppRefresh(task: BGAppRefreshTask) {
// Schedule a new refresh task.
scheduleAppRefresh()
print("this background fetch called")
}
Above Code BGTaskScheduler completion Not working in swift 5, I added identifier with info.plist file permission. I need to use API with app background state. Please assist how can I achieve this one. Thanks

Why has BGProcessingTask already been registered?

I am creating my own background task and I keep getting an error stating: 'Launch handler for task with identifier "processingTaskId" has already been registered'. I am still learning and would like to understand this error more.
code
import UIKit
import Flutter
import BackgroundTasks
#UIApplicationMain
#objc class AppDelegate: FlutterAppDelegate {
let processingTaskId = "com.demo.processingtask"
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
GeneratedPluginRegistrant.register(with: self)
if #available(iOS 13, *) {
BGTaskScheduler.shared.register(forTaskWithIdentifier: processingTaskId, using: nil) { task in
self.handleTask(task: task as! BGProcessingTask)
}
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
#available(iOS 13.0, *)
func handleTask(task: BGProcessingTask) {
scheduleTask()
task.setTaskCompleted(success: true)
}
#available(iOS 13.0, *)
func scheduleTask() {
let request = BGProcessingTaskRequest(identifier: processingTaskId)
request.earliestBeginDate = nil
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule task: (error)")
}
}
}

BackgroundTasks not changing values when activated

I am trying to use the BackgroundTask framework to run a block of code periodically when the user closes the app. Preferably, I would want the code to run once every hour. In the project file below, I have the code change a value stored in UserDefaults, but no matter how long I wait it never runs the code in the task.
AppDelegate.swift
import UIKit
import BackgroundTasks
import OSLog
#main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.example.refresh", using: nil) { task in
Logger().info("[BGTASK] Preform bg fetch \("com.example.refresh")")
task.setTaskCompleted(success: true)
self.scheduleAppRefresh()
}
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.example.restock", using: nil) { task in
Logger().info("[BGTASK] Preform bg fetch \("com.example.restock")")
AppUserDefaults.newString = "New String" // <-- The string is changed here
task.setTaskCompleted(success: true)
self.scheduleBackgroundProcessing()
}
return true
}
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: "com.example.refresh")
request.earliestBeginDate = Date(timeIntervalSinceNow: 60)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh task \(error.localizedDescription)")
}
}
func scheduleBackgroundProcessing() {
let request = BGProcessingTaskRequest(identifier: "com.example.restock")
request.requiresNetworkConnectivity = true
request.requiresExternalPower = false
request.earliestBeginDate = Date(timeIntervalSinceNow: 1 * 60)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule image fetch: (error)")
}
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func applicationDidEnterBackground(_ application: UIApplication) {
Logger().info("App did enter background")
self.scheduleAppRefresh()
self.scheduleBackgroundProcessing()
}
}
When the app loads, I show newString in the ContentView:
ContentView.swift
import SwiftUI
import UserNotifications
struct ContentView: View {
var body: some View {
Text("New String: \(AppUserDefaults.newString)")
}
}
Project

BackgroundTask iOS 13 Swift

I want to run the function in the background. But I get an error. The error I received is
"nw_connection_receive_internal_block_invoke.
Why am I getting this problem? I'm trying it on an iOS 13 device. But I can't run the application in the background. I added a background run feature in Info.plist. I want to run the interator.tickTimer function in the background. But I'm getting an error. Does not work in the background. In the background, I want to periodically retrieve data from firebase.
import BackgroundTasks
#available(iOS 13.0, *)
extension AppDelegate {
func cancelAllPandingBGTask() {
BGTaskScheduler.shared.cancelAllTaskRequests()
}
func scheduleImageFetcher() {
let request = BGProcessingTaskRequest(identifier: "....")
request.requiresNetworkConnectivity = true // Need to true if your task need to network process. Defaults to false.
request.requiresExternalPower = false
request.earliestBeginDate = Date(timeIntervalSinceNow: 40)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule image featch: \(error)")
}
}
func handleAppRefreshTask(task: BGAppRefreshTask) {
task.expirationHandler = {
}
DispatchQueue.main.async {
let interator = MainTableViewController()
interator.tickTimer()
}
task.setTaskCompleted(success: true)
}
func handleImageFetcherTask(task: BGProcessingTask) {
scheduleImageFetcher() // Recall
//Todo Work
task.expirationHandler = {
}
task.setTaskCompleted(success: true)
}
}
xtension AppDelegate {
func registerLocalNotification() {
let notificationCenter = UNUserNotificationCenter.current()
let options: UNAuthorizationOptions = [.alert, .sound, .badge]
notificationCenter.requestAuthorization(options: options) {
(didAllow, error) in
if !didAllow {
// print("User has declined notifications")
}
}
}
func scheduleLocalNotification() {
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.getNotificationSettings { (settings) in
if settings.authorizationStatus == .authorized {
self.fireNotification()
}
}
}
func fireNotification() {
// Create Notification Content
let notificationContent = UNMutableNotificationContent()
// Configure Notification Content
notificationContent.title = "Bg"
notificationContent.body = "BG Notifications."
// Add Trigger
let notificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 1.0, repeats: false)
// Create Notification Request
let notificationRequest = UNNotificationRequest(identifier: "local_notification", content: notificationContent, trigger: notificationTrigger)
// Add Request to User Notification Center
UNUserNotificationCenter.current().add(notificationRequest) { (error) in
if let error = error {
print("Unable to Add Notification Request (\(error), \(error.localizedDescription))")
}
}
}
}
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UITabBarControllerDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 13.0, *) {
registerBackgroundTaks()
registerLocalNotification()
} else {
// Fallback on earlier versions
}
return true
}
func applicationDidEnterBackground(_ application: UIApplication) {
if #available(iOS 13.0, *) {
cancelAllPandingBGTask()
scheduleImageFetcher()
} else {
// Fallback on earlier versions
}
}
//MARK: Regiater BackGround Tasks
#available(iOS 13.0, *)
private func registerBackgroundTaks() {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "....-...", using: nil) { task in
//This task is cast with processing request (BGProcessingTask)
self.scheduleLocalNotification()
self.handleImageFetcherTask(task: task as! BGProcessingTask)
}
}

Resources