Alexandre C. do Carmo Alexandre C. do Carmo - 4 months ago 11
iOS Question

About notification iOS

I'm studying notifications, and I create a code thar show a notification using datePicker to schedule. The code worked very well.
But how to show the notification each 10 minutes when my app is in background?
This os my code:

AppDelegate :

func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {

print(notificationSettings.types.rawValue)
}

func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
print("Received Local Notification:")
print(notification.alertBody!)
}

func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) {

if identifier == "editList" {
NSNotificationCenter.defaultCenter().postNotificationName("modifyListNotification", object: nil)
}
else if identifier == "trashAction" {
NSNotificationCenter.defaultCenter().postNotificationName("deleteListNotification", object: nil)
}

completionHandler()
}


ViewController:

import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
@IBOutlet weak var txtAddItem: UITextField!

@IBOutlet weak var tblShoppingList: UITableView!

@IBOutlet weak var btnAction: UIButton!

@IBOutlet weak var datePicker: UIDatePicker!
var shoppingList: NSMutableArray!

var timer = NSTimer()



override func viewDidLoad() {
super.viewDidLoad()

self.tblShoppingList.delegate = self
self.tblShoppingList.dataSource = self

self.txtAddItem.delegate = self

datePicker.hidden = true

loadShoppingList()
setupNotificationSettings()

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.handleModifyListNotification), name: "modifyListNotification", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.handleDeleteListNotification), name: "deleteListNotification", object: nil)

listenerSchedule()


}


override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

func handleModifyListNotification() {
txtAddItem.becomeFirstResponder()
}

func handleDeleteListNotification() {
shoppingList.removeAllObjects()
saveShoppingList()
tblShoppingList.reloadData()
}

func setupNotificationSettings() {

let notificationSettings: UIUserNotificationSettings! = UIApplication.sharedApplication().currentUserNotificationSettings()

if (notificationSettings.types == UIUserNotificationType.None){

let notificationTypes = UIUserNotificationType.Alert.union(UIUserNotificationType.Sound)

let justInformAction = UIMutableUserNotificationAction()
justInformAction.identifier = "justInform"
justInformAction.title = "OK, got it"
justInformAction.activationMode = UIUserNotificationActivationMode.Background
justInformAction.destructive = false
justInformAction.authenticationRequired = false

let modifyListAction = UIMutableUserNotificationAction()
modifyListAction.identifier = "editList"
modifyListAction.title = "Edit list"
modifyListAction.activationMode = UIUserNotificationActivationMode.Foreground
modifyListAction.destructive = false
modifyListAction.authenticationRequired = true

let trashAction = UIMutableUserNotificationAction()
trashAction.identifier = "trashAction"
trashAction.title = "Delete list"
trashAction.activationMode = UIUserNotificationActivationMode.Background
trashAction.destructive = true
trashAction.authenticationRequired = true

let actionsArray = NSArray(objects: justInformAction, modifyListAction, trashAction)
let actionsArrayMinimal = NSArray(objects: trashAction, modifyListAction)

let shoppingListReminderCategory = UIMutableUserNotificationCategory()
shoppingListReminderCategory.identifier = "shoppingListReminderCategory"
shoppingListReminderCategory.setActions(actionsArray as? [UIUserNotificationAction], forContext: UIUserNotificationActionContext.Default)
shoppingListReminderCategory.setActions(actionsArrayMinimal as? [UIUserNotificationAction], forContext: UIUserNotificationActionContext.Minimal)


let categoriesForSettings = NSSet(objects: shoppingListReminderCategory)


let newNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: categoriesForSettings as? Set<UIUserNotificationCategory>)
UIApplication.sharedApplication().registerUserNotificationSettings(newNotificationSettings)
}

}

func setActions(actions: [AnyObject]!, forContext context: UIUserNotificationActionContext){}

func scheduleLocalNotification() {
let localNotification = UILocalNotification()
localNotification.fireDate = fixNotificationDate(datePicker.date)
localNotification.alertBody = "test test test"
localNotification.alertAction = "View List"
localNotification.category = "shoppingListReminderCategory"

UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}

func listenerSchedule() {
timer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: #selector(ViewController.startNotication), userInfo: nil, repeats: true)
}

func startNotication(){

}

func fixNotificationDate(dateToFix: NSDate) -> NSDate {

let dateComponets: NSDateComponents = NSCalendar.currentCalendar().components([.Day, .Month, .Year, .Hour, .Minute], fromDate: dateToFix)

dateComponets.second = 0

let fixedDate: NSDate! = NSCalendar.currentCalendar().dateFromComponents(dateComponets)

return fixedDate
}

func textFieldShouldReturn(textField: UITextField) -> Bool {
if shoppingList == nil{
shoppingList = NSMutableArray()
}
shoppingList.addObject(textField.text!)

tblShoppingList.reloadData()

txtAddItem.text = ""
txtAddItem.resignFirstResponder()

saveShoppingList()

return true
}

@IBAction func scheduleReminder(sender: AnyObject) {
if datePicker.hidden {
animateMyViews(tblShoppingList, viewToShow: datePicker)

UIApplication.sharedApplication().cancelAllLocalNotifications()
}
else{
animateMyViews(datePicker, viewToShow: tblShoppingList)

scheduleLocalNotification()
}

txtAddItem.enabled = !txtAddItem.enabled
}


func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}


func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var rows = 0

if let list = shoppingList{
rows = list.count
}

return rows
}


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("idCellItem")! as UITableViewCell

cell.textLabel?.text = shoppingList.objectAtIndex(indexPath.row) as! NSString as String

return cell
}


func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 50.0
}

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
removeItemAtIndex(indexPath.row)
}
}

func removeItemAtIndex(index: Int) {
shoppingList.removeObjectAtIndex(index)

tblShoppingList.reloadData()

saveShoppingList()
}



func saveShoppingList() {
let savePath = (NSTemporaryDirectory() as NSString).stringByAppendingPathComponent("shopping_list")

shoppingList.writeToFile(savePath, atomically: true)
}

func loadShoppingList() {
let shoppingListPath = (NSTemporaryDirectory() as NSString).stringByAppendingPathComponent("shopping_list")

if NSFileManager.defaultManager().fileExistsAtPath(shoppingListPath){
shoppingList = NSMutableArray(contentsOfFile: shoppingListPath)
tblShoppingList.reloadData()
}
}

func animateMyViews(viewToHide: UIView, viewToShow: UIView) {
let animationDuration = 0.35

UIView.animateWithDuration(animationDuration, animations: { () -> Void in
viewToHide.transform = CGAffineTransformScale(viewToHide.transform, 0.001, 0.001)
}) { (completion) -> Void in

viewToHide.hidden = true
viewToShow.hidden = false

viewToShow.transform = CGAffineTransformScale(viewToShow.transform, 0.001, 0.001)

UIView.animateWithDuration(animationDuration, animations: { () -> Void in
viewToShow.transform = CGAffineTransformIdentity
})
}
}


}

Answer

I solved the problem, created the code that working in background and calling the notification using Time, this is code:

AppDelagate

func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {

    print(notificationSettings.types.rawValue)
}


func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
    // Do something serious in a real app.
    print("Received Local Notification:")
    print(notification.alertBody!)
}
func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) {

    if identifier == "editList" {
        NSNotificationCenter.defaultCenter().postNotificationName("modifyListNotification", object: nil)
    }
    else if identifier == "trashAction" {
        NSNotificationCenter.defaultCenter().postNotificationName("deleteListNotification", object: nil)
    }

    completionHandler()
}

ViewController:

import UIKit

class ViewController: UIViewController {

var timer = NSTimer()
 var backgroundTaskIdentifier: UIBackgroundTaskIdentifier?

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    notificatioAppGoToBackground()

    setupNotificationSettings()

    //call handle notifications
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.handleModifyListNotification), name: "modifyListNotification", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.handleDeleteListNotification), name: "deleteListNotification", object: nil)

    backgroundTaskIdentifier = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({
        UIApplication.sharedApplication().endBackgroundTask(self.backgroundTaskIdentifier!)
    })


}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func alert(title:String, message:String ){

    let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)
    alert.addAction(UIAlertAction(title: "OK", style: .Default) { _ in })
    self.presentViewController(alert, animated: true){}
}

func handleModifyListNotification() {
    alert("Atenção", message: "Modificação")
}

func handleDeleteListNotification() {
    print("executou a exclusao")
}

func setupNotificationSettings() {

    let notificationSettings: UIUserNotificationSettings! = UIApplication.sharedApplication().currentUserNotificationSettings()

    if (notificationSettings.types == UIUserNotificationType.None){

        // Specify the notification types.
        let notificationTypes = UIUserNotificationType.Alert.union(UIUserNotificationType.Sound)

        let modifyListAction = UIMutableUserNotificationAction()
        modifyListAction.identifier = "editList"
        modifyListAction.title = "Edit list"
        modifyListAction.activationMode = UIUserNotificationActivationMode.Foreground
        modifyListAction.destructive = false
        modifyListAction.authenticationRequired = true

        let trashAction = UIMutableUserNotificationAction()
        trashAction.identifier = "trashAction"
        trashAction.title = "Delete list"
        trashAction.activationMode = UIUserNotificationActivationMode.Background
        trashAction.destructive = true
        trashAction.authenticationRequired = true

        let actionsArray = NSArray(objects: modifyListAction, trashAction)
        let actionsArrayMinimal = NSArray(objects: trashAction, modifyListAction)

        // Specify the category related to the above actions.
        let shoppingListReminderCategory = UIMutableUserNotificationCategory()
        shoppingListReminderCategory.identifier = "shoppingListReminderCategory"
        shoppingListReminderCategory.setActions(actionsArray as? [UIUserNotificationAction], forContext: UIUserNotificationActionContext.Default)
        shoppingListReminderCategory.setActions(actionsArrayMinimal as? [UIUserNotificationAction], forContext: UIUserNotificationActionContext.Minimal)


        let categoriesForSettings = NSSet(objects: shoppingListReminderCategory)


        // Register the notification settings.
        let newNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: categoriesForSettings as? Set<UIUserNotificationCategory>)
        UIApplication.sharedApplication().registerUserNotificationSettings(newNotificationSettings)
    }

}

func setActions(actions: [AnyObject]!, forContext context: UIUserNotificationActionContext){}


func notificatioAppGoToBackground(){
    let notificationCenter = NSNotificationCenter.defaultCenter()
    notificationCenter.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplicationWillResignActiveNotification, object: nil)
}

func appMovedToBackground() {
    print("App moved to background!!!")
    listenerSchedule()
}

func listenerSchedule() {
    timer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: #selector(ViewController.startNotication), userInfo: nil, repeats: true)
}

func startNotication(){
    let date = NSDate()
    let dateComponets: NSDateComponents = NSCalendar.currentCalendar().components([.Day, .Month, .Year, .Hour, .Minute, .Minute], fromDate: date)


    print("aguardando notificação  \(dateComponets.second)" )
    let localNotification = UILocalNotification()
    //localNotification .fireDate = fixNotificationDate(datePicker.date) //usar com datepicker
    localNotification.alertBody = "Teste de notificação"
    localNotification.alertAction = "View List"
    localNotification.category = "shoppingListReminderCategory"

    UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}

}