1

I have question regarding to iOS Background Tasks or Process. I have an application which should inform you by local notification every 15 minutes if you have new email -> if you do not have any, nothing happen.

I have found lot of tutorials for Swift 4, Swift 5 but only few should working on iOS 13 and new framework BackgroundTask. I tried all of them and I did not get the working solution (firstly I get errors because I tried it on Simulator, now I getting a message "Can't end a bg task..." - It seems to be bug in Xcode.) and app could not refresh because of no reason.

AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    UNUserNotificationCenter.current().delegate = self
    registerBackgroundTaks()

    return true
}

func applicationDidEnterBackground(_ application: UIApplication) {
    scheduleEmailFetcher()
}

//MARK: Register BackGround Tasks
private func registerBackgroundTaks() {
    BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.InformationSystem.emailFetch", using: nil) { task in
        //This task is cast with processing request (BGProcessingTask)
        self.setNotification()
        self.handleEmailFetcher(task: task as! BGProcessingTask)
    }
}

func cancelAllPandingBGTask() {
    BGTaskScheduler.shared.cancelAllTaskRequests()
}

func handleEmailFetcher(task: BGProcessingTask) {
    scheduleEmailFetcher() // Recall

    task.expirationHandler = {
        self.cancelAllPandingBGTask()
    }

    print("Handling BG Task!")
    // GET Request to server and other logic here?
    setNotification()

    task.setTaskCompleted(success: true)

}

func scheduleEmailFetcher() {
    let request = BGProcessingTaskRequest(identifier: "com.InformationSystem.emailFetch")
    request.requiresNetworkConnectivity = true
    request.requiresExternalPower = false
    print("Scheduled")
    request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60) 
    do {
        try BGTaskScheduler.shared.submit(request)
    } catch {
        print("Could not schedule email fetch: \(error)")
    }
}

Is there anybody who can help me get rid of it?

Thanks a lot for help!

Peter Hlavatík
  • 117
  • 1
  • 1
  • 11
  • Hii can you please check this url: https://stackoverflow.com/questions/23882495/cant-endbackgroundtask-no-background-task-exists-with-identifier-or-it-may-ha let me know it's working or not.? – Yogesh Patel Mar 19 '20 at 14:07
  • Hi, I already tried solutions in this question. But nothing helped. I think my BGTask did not working at all ... I tried to send local notification every minute with some lorem ipsum text but nothing happen. – Peter Hlavatík Mar 19 '20 at 14:10
  • 2
    try to do one simple thing first. Just change any ViewController background color. when your app going to background. For this you can check that this issue is in background task or in your LocalNotification code. got this? – Yogesh Patel Mar 19 '20 at 14:13
  • I will try it on sample project and let you know if something happen. Do you have some advice about "How should look like the code for background process"? – Peter Hlavatík Mar 19 '20 at 14:19
  • 1
    I feel I should downvote your question but won't. Why? You say you've found many examples but you haven't posted any code to let someone else duplicate your issue. In fact, you are rather vague about whether you tried this on an actual device versus the simulator. An alarm is ringing in my head the moment you talk about *"send GET request to server"*... and separately from simulator. Are you **really** sure you're looking at the correct issue? Details that we can duplicate really help us help you. And as @YogeshPatel states, try doing one thing at a time. Good luck. –  Mar 19 '20 at 14:45
  • Hi @dfd, I edit the question. Thanks for feedback – Peter Hlavatík Mar 19 '20 at 14:57
  • 1
    `BGProcessingTaskRequest` is not designed to run a background in precisely 15 minutes. It’s designed to request that some background task be run at the sole discretion of the OS at some future time, but not sooner than 15 minutes. It could be 15 minutes. It could be hours, while the user recharges their phone. You don’t dictate when it happens. The OS does. – Rob Mar 19 '20 at 16:28
  • Okay, it's even possible to do that except push notifications? – Peter Hlavatík Mar 19 '20 at 16:31
  • 1
    Yep, push notifications are ideal. You can also use the background fetch service, where the OS will at its sole discretion, fire up your app in the background so it can check to see if there is data to retrieve, but this isn’t ideal for mail app, where user might expect a more reliable and proactive notification. Background fetch uses an opaque algorithm to initiate background fetches based upon the user’s historical use patterns. Esp if user doesn’t use app consistently, this can be unreliable. Anyway, see [background execution video](https://developer.apple.com/videos/play/wwdc2019/707) – Rob Mar 19 '20 at 17:40
  • It basically means that I will not use `BGProccessingTaskRequest` but `BGRefreshTaskRequest` ? The app runs on reading html with XPaths (not clear solution, but we can't use own server) so push notifications are impossible. – Peter Hlavatík Mar 19 '20 at 18:07
  • 1
    Yep, but sadly, I don’t think you’re going to find any of these background tasks will get you anywhere close to your desired “every 15 minutes” logic. But for reasonably active users, at least you’ll get some background fetching... Sorry. This fixed schedule pattern is just not something that Apple endorses because it’s just so darn power-inefficient. – Rob Mar 20 '20 at 21:39
  • I will do that with push notifications. It will be better and more clear. – Peter Hlavatík Mar 23 '20 at 07:59
  • Hey @Rob, do you have experience with silent push notifications? I have already connected my device to push notifications, I receive silent push notification but I am not able to run url post request with completion. It's faster then 30 seconds anyway get's pause or how to call it. – Peter Hlavatík Mar 27 '20 at 06:30
  • Are you talking about notification while your app was in the background? Common problem would be premature calling of the completion handler that the notification supplied to `application(_:didReceiveRemoteNotification:fetchCompletionHandler:)` before your `POST` request finished. I think if you search S.O. you will find relevant questions. But we’re not going to be able to diagnose it here in comments and it’s a different topic than this question. I might just delete this question and post a background fetch question if you are unable to figure it out after researching it... – Rob Mar 27 '20 at 17:55
  • @Rob https://stackoverflow.com/questions/60899650/silent-push-not-triggering-the-code-execution – Peter Hlavatík Mar 28 '20 at 10:00

0 Answers0