2

In my AppDelegate, I've added a method to do a fetch request on my Core Data, and in some case I'm showing a notification... But I see that there are some deprecated methods. I Tried to do some changes, but:

  • When I kill my app the background mode does not work

  • When my app is on foreground, the background mode works, but the notifications don't show up

  • When I run my app in background, everything is working fine

Here is my code:

The method that I want to run every time (every minute):

func notification(){

    let appDel: AppDelegate = UIApplication.shared.delegate as! AppDelegate
    let context: NSManagedObjectContext = appDel.managedObjectContext
    var messageNotif:String? = nil

    do {

        let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Leads")
        let predicate = NSPredicate(format: "statutSendLead=%@ OR statutSendSimulation=%@", "0", "0")
        request.predicate = predicate
        let results = try context.fetch(request)

        if results.count > 0 {
            if Reachability.isConnectedToNetwork() == false {

                messageNotif = "Votre demande n'a pas été envoyée, merci de vous connecter à internet."
            } else {

                Reachability.checkUrl(urlString:Configuration.MyVariables.url, finished: { isSuccess in


                    if isSuccess == false {
                        messageNotif = "Notre service d'enregistrement des demandes est temporairement indisponible, un renvoi sera effectué ultérieurement."
                    }
                })
            }
            */


            if (messageNotif != nil) {

                let identifier = self.stringWithUUID()


                if #available(iOS 10.0, *) {
                    let center = UNUserNotificationCenter.current()
                    center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in

                        let content = UNMutableNotificationContent()

                        content.body = messageNotif!
                        content.sound = UNNotificationSound.default()
                        // Deliver the notification in five seconds.
                        let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 5, repeats: false)
                        let request = UNNotificationRequest.init(identifier: "test", content: content, trigger: trigger)

                        // Schedule the notification.
                        let center = UNUserNotificationCenter.current()

                        UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
                        UNUserNotificationCenter.current().add(request) {(error) in
                            if let error = error {
                                print(error)
                            }
                        }
                    }
                } else {
                    let notification = UILocalNotification()
                    notification.alertBody = messageNotif
                    notification.fireDate = NSDate() as Date
                    notification.soundName = UILocalNotificationDefaultSoundName
                    UIApplication.shared.scheduleLocalNotification(notification)
                }
            }
        }

        /* else {
         timerNotification.invalidate()
         } */

    } catch {
        print(error)
    }
}

The other methods:

var window: UIWindow?
var timerUploadData:Timer!
var timerNotification:Timer!
var test:Timer!

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

    UIApplication.shared.setMinimumBackgroundFetchInterval(
        UIApplicationBackgroundFetchIntervalMinimum)

    let userDefaults = UserDefaults.standard

    if userDefaults.object(forKey: "ApplicationUniqueIdentifier") == nil {
        let UUID = Foundation.UUID().uuidString
        userDefaults.set(UUID, forKey: "ApplicationUniqueIdentifier")
        userDefaults.synchronize()
    }

    Thread.sleep(forTimeInterval: 3.0)
    window = UIWindow(frame: UIScreen.main.bounds)
    let containerViewController = ContainerViewController()
    window!.rootViewController = containerViewController
    window!.makeKeyAndVisible()


    if #available(iOS 10.0, *){

        application.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))
        timerNotification = Timer.scheduledTimer(timeInterval: 60 * 1, target: self, selector: #selector(AppDelegate.notification), userInfo: nil, repeats: true)

    }
    else { //If user is not on iOS 10 use the old methods we've been using
        let notificationSettings = UIUserNotificationSettings(
            types: [UIUserNotificationType.badge, UIUserNotificationType.alert, UIUserNotificationType.sound], categories: nil)
        timerNotification = Timer.scheduledTimer(timeInterval: 60 * 1, target: self, selector: "notification", userInfo: nil, repeats: true)
        application.registerUserNotificationSettings(notificationSettings)
    }

    registerPushNotifications()

    return true
}

func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    notification()
}


func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {
    if notificationSettings.types != UIUserNotificationType() {
        application.registerForRemoteNotifications()
    }
}

func registerPushNotifications() {
    DispatchQueue.main.async {
        let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)
        UIApplication.shared.registerUserNotificationSettings(settings)
    }
}

func stringWithUUID() -> String {
    let uuidObj = CFUUIDCreate(nil)
    let uuidString = CFUUIDCreateString(nil, uuidObj)!
    return uuidString as String
}
shallowThought
  • 19,212
  • 9
  • 65
  • 112
Ben
  • 761
  • 1
  • 12
  • 35
  • see this https://stackoverflow.com/questions/17044373/local-notification-in-foreground for your question why notifications are not shown when your app is in foreground (because the app have to show the notification itself) – data cosmos Jan 13 '17 at 10:49
  • Any response for the app terminated situation ? – Ben Jan 13 '17 at 14:48
  • Have you read this: https://blog.newrelic.com/2016/01/13/ios9-background-execution/ ? – data cosmos Jan 17 '17 at 14:00
  • Did you ever figure this out? Scheduling notifications from within a background fetch doesn't work. Scheduling notifications work in every other situation. Is Apple trying to say use push notifications or is this a bug? – TruMan1 Feb 08 '17 at 15:05
  • Btw, killing the app will also tell the OS not to wake up your app again. You have to let it naturally suspend and push out of memory by itself. You can use the Background Kill test app to try to force it. – TruMan1 Feb 08 '17 at 15:20
  • @TruMan1 look here : http://stackoverflow.com/questions/41674040/a-solution-to-retrieve-information-when-theyre-no-internet-connection – Ben Feb 08 '17 at 15:30

1 Answers1

0

although this is an old question I now got a good answer on a similar problem, see the answer from Rob

This is a possible answer why your background mode does not work when you kill your app and even a hint on how to test this.

The other question is already answered in the comments:

see this stackoverflow.com/questions/17044373/… for your question why notifications are not shown when your app is in foreground (because the app have to show the notification itself) – data cosmos Jan 13 at 10:49

Community
  • 1
  • 1
data cosmos
  • 313
  • 3
  • 14