Changing badge number daily - ios

I am looking for a medhold to add 1 for each day to the badge icon. I have tried multiple ways, but none of them have updated the icon badge number.
override func viewDidLoad() {
super.viewDidLoad()
let localNotification:UILocalNotification = UILocalNotification()
localNotification.fireDate = datePicker.date
localNotification.alertBody = nil;
localNotification.alertAction = nil;
localNotification.timeZone = NSTimeZone.defaultTimeZone()
localNotification.repeatInterval = NSCalendarUnit.Day
//Add one to the icon badge number
localNotification.applicationIconBadgeNumber = UIApplication.sharedApplication().applicationIconBadgeNumber + 1;
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)

So I would choose another approach. My idea is to set a self-repeating timer that fires every 86,400s (24hrs/1d) and sends a notification. If that works the badge count would increase automatically by one.
//!pseudo-code!
let timer = NSTimer.scheduledTimerWithTimeInterval(864000, target: self, selector: "sendNotification:", userInfo: nil, repeats: true)
func sendNotification(timer: NSTimer) {
//initialize and send your notification w/ repeatCount: 0 and fireDate: now
//hide the banner so the user does not visually see the notification if you wish
}
I am not sure whether this will work if the app is not running but it may be worth a try.

Related

Scheduling UILocalNotification causing lagging and delay of user interface

I have a function scheduleFutureLocalNotifications() in Swift code that creates 64 UILocalNotification that fire in the future.
Originally the function was called at viewDidLoad(), but this caused delays when starting the app.
Next, the function was called during the active application, but this caused unpredictable pauses or lagging of the user interface.
Finally, the function was moved to trigger when the app transitions to the background after receiving a UIApplicationDidEnterBackground notification, but this causes iOS to briefly lag as the local notifications are prepared in the background. This appears more evident on older devices.
Question:
1 - How can I reduce lag and improve user interface responsiveness
creating local notifications?
2 - What better techniques can be employed to schedule the 64
notifications?
3 - What other better times could the function scheduleFutureLocalNotifications() be called?
Code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
scheduleFutureLocalNotifications()
}
func scheduleFutureLocalNotifications() {
// Remove all previous local notifications
let application = UIApplication.sharedApplication()
application.cancelAllLocalNotifications()
// Set new local notifications to fire over the coming 64 days
for nextLocalNotification in 1...64 {
// Add calendar day
let addDayComponent = NSDateComponents()
addDayComponent.day = nextLocalNotification
let calendar = NSCalendar.currentCalendar()
let nextDate = calendar.dateByAddingComponents(addDayComponent, toDate: NSDate(), options: [])
// Set day components for next fire date
let nextLocalNotificationDate = NSCalendar.currentCalendar()
let components = nextLocalNotificationDate.components([.Year, .Month, .Day], fromDate: nextDate!)
let year = components.year
let month = components.month
let day = components.day
// Set notification fire date
let componentsFireDate = NSDateComponents()
componentsFireDate.year = year
componentsFireDate.month = month
componentsFireDate.day = day
componentsFireDate.hour = 0
componentsFireDate.minute = 0
componentsFireDate.second = 5
let fireDateLocalNotification = calendar.dateFromComponents(componentsFireDate)!
// Schedule local notification
let localNotification = UILocalNotification()
localNotification.fireDate = fireDateLocalNotification
localNotification.alertBody = ""
localNotification.alertAction = ""
localNotification.timeZone = NSTimeZone.defaultTimeZone()
localNotification.repeatInterval = NSCalendarUnit(rawValue: 0)
localNotification.applicationIconBadgeNumber = nextLocalNotification
application.scheduleLocalNotification(localNotification)
}
}
}
You can dispatch the function, asynchronously, onto another queue. This will ensure that the main queue isn't blocked performing the scheduling and will prevent the UI from becoming unresponsive:
override func viewDidLoad() {
super.viewDidLoad()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIO‌​RITY_BACKGROUND, 0)) {
scheduleFutureLocalNotifications()
}
}

how to run a function at certain time using swift

In my app, i have implemented functionality to check app version using bundleVersion String. Now, i want to run this function everyday at 8:00 a.m. This is kiosk based app which does not go into background. So, app would be active all the time.
I am using UILocalnotification to schedule a notification for that time. Now, my app has other UILocalnotification as well. I am not sure how can i identify notifications in app delegate didReceiveLocalNotification() method.
My method to schedule notification is below
func scheduleNotification() {
//UIApplication.sharedApplication().cancelAllLocalNotifications()
let notif = UILocalNotification()
let calendar = NSCalendar.currentCalendar()
let date = NSDate()
var calendarComponents = NSDateComponents()
calendarComponents = calendar.components([.Day,.Month,.Year], fromDate: date)
let day = calendarComponents.day
let month = calendarComponents.month
let year = calendarComponents.year
calendarComponents.day = day
calendarComponents.month = month
calendarComponents.year = year
calendarComponents.hour = 8
calendarComponents.second = 0
calendarComponents.minute = 0
calendar.timeZone = NSTimeZone.systemTimeZone()
let dateToFire = calendar.dateFromComponents(calendarComponents)
notif.fireDate = dateToFire
notif.timeZone = NSTimeZone.systemTimeZone()
notif.repeatInterval = NSCalendarUnit.NSWeekdayCalendarUnit
UIApplication.sharedApplication().scheduleLocalNotification(notif)
}
Any idea would be appreciated.
Following method could help you to execute any task at regular interval , i used this method to call webservice at regular interval to provide searching functionality :
let debounceTimer : NSTimer?
func test() {
if let timer = debounceTimer {
timer.invalidate()
}
debounceTimer = NSTimer(timeInterval: 0.3, target: self, selector: Selector("putmethodnamewhichneedstocall"), userInfo: nil, repeats: false)
NSRunLoop.currentRunLoop().addTimer(debounceTimer!, forMode: "NSDefaultRunLoopMode")
}
For specific time daily Refer to this SO link :Repeating local notification daily at a set time with swift
Hope it helps.

How to put notifications on iOS application to repeat every one (1) hour?

I tried to put notifications in my app, it was supposed to repeat every one hour but it repeat unregulated, to be clear, it repeats sometimes 30min sometimes one hour sometimes for a long time etc..
Code that I used in "AppDelegate.swift":
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
//Notification Repeat
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, categories: nil))
return true
}
and code that I used in "ViewController.swift":
//Notification Repeat
var Time = 1
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//Notification Repeat
var Timer = NSTimer.scheduledTimerWithTimeInterval(3600.0, target: self, selector: Selector("activateNotifications"), userInfo: nil, repeats: true)
}
//Notification Repeat
func activateNotifications() {
Time -= 1
if (Time <= 0){
var activateNotifications = UILocalNotification()
activateNotifications.alertAction = “Hey"
activateNotifications.alertBody = “Hello World!"
activateNotifications.fireDate = NSDate(timeIntervalSinceNow: 0)
UIApplication.sharedApplication().scheduleLocalNotification(activateNotifications)
}
}
Can someone help me, where I made mistake ?
You don't need the timer at all. The UILocalNotification class has a property entitled repeatInterval that, as you can expect, set the interval at which the notification will be repeated.
According to this, you can schedule a local notifications that is repeated every hour in the following way:
func viewDidLoad() {
super.viewDidLoad()
var notification = UILocalNotification()
notification.alertBody = "..." // text that will be displayed in the notification
notification.fireDate = NSDate() // right now (when notification will be fired)
notification.soundName = UILocalNotificationDefaultSoundName // play default sound
notification.repeatInterval = NSCalendarUnit.CalendarUnitHour // this line defines the interval at which the notification will be repeated
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}
NOTE: Be sure that you execute the code when you launch the notification only once, since it schedules a different notification every time that it is executed. For a better understanding of local notifications, you can read Local Notifications in iOS 8 with Swift (Part 1) and Local Notifications in iOS 8 with Swift (Part 2).

iOS locale notification pop-up doesn't appear

I'm a newbie in iOS programming and in my app I've a UILocaleNotification which have to appear at a certain time.
So first I setup parameters :
let notificationSettings: UIUserNotificationSettings! = UIApplication.sharedApplication().currentUserNotificationSettings()
if (notificationSettings.types == UIUserNotificationType.None) {
var notificationTypes: UIUserNotificationType = UIUserNotificationType.Alert | UIUserNotificationType.Sound
// Bouton d'envoi
var sendAction = UIMutableUserNotificationAction()
sendAction.identifier = "send"
sendAction.title = "Send"
sendAction.activationMode = UIUserNotificationActivationMode.Foreground
sendAction.destructive = false
sendAction.authenticationRequired = true
// Bouton de non-envoi
var dontSendAction = UIMutableUserNotificationAction()
dontSendAction.identifier = "dontsend"
dontSendAction.title = "Don't send"
dontSendAction.activationMode = UIUserNotificationActivationMode.Background
dontSendAction.destructive = true
dontSendAction.authenticationRequired = false
let actionsArray = NSArray(objects: sendAction, dontSendAction)
var reminderNotification = UIMutableUserNotificationCategory()
reminderNotification.identifier = "reminderNotification"
reminderNotification.setActions(actionsArray as [AnyObject], forContext: UIUserNotificationActionContext.Minimal)
let categoriesForSettings = NSSet(objects: reminderNotification)
let newNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: categoriesForSettings as Set<NSObject>)
UIApplication.sharedApplication().registerUserNotificationSettings(newNotificationSettings)
}
... and I schedule my notification like that :
var localNotification = UILocalNotification()
localNotification.fireDate = NSDate(timeIntervalSinceNow: 3)
localNotification.timeZone = NSTimeZone.defaultTimeZone()
localNotification.alertBody = "Hey, inform your contacts !"
localNotification.alertAction = "Send Message"
localNotification.category = "reminderNotification"
localNotification.soundName = UILocalNotificationDefaultSoundName
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
When I try this code, notifs are displaying right in the notification center, but there is no pop-up displayed...
I searched sources on the net and I don't understand why those examples and tutos are displaying pop-up because I wrote the same code...
Thanks for your help and have a good day !
EDIT : I forgot something : it's the notification center which have to detect an event, and not the locale notification. So I want the addObserver of the notification center to check an event, is it possible in background state ?
According to this line: localNotification.fireDate = NSDate(timeIntervalSinceNow: 3) you want your notification to be triggered 3 seconds later. I assume that the app is still in the foreground when it happens. If it's the case, you will not have a notification popup.
If the app linked to a notification is opened when the notification is received, it has to handle it in your AppDelegate to display a custom popup.
func application(application: UIApplication!, didReceiveLocalNotification notification: UILocalNotification!) {
// do your jobs here
}

Run a function every day or every hour in Swift

I can do it manually with the following code:
var myDate:NSDateComponents = NSDateComponents()
myDate.year = 2015
myDate.month = 04
myDate.day = 20
myDate.hour = 12
myDate.minute = 38
myDate.timeZone = NSTimeZone.systemTimeZone()
var calendar:NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
var date:NSDate = calendar.dateFromComponents(myDate)!
var notification:UILocalNotification = UILocalNotification()
notification.category = "First Category"
notification.alertBody = "Hi, I'm a notification"
notification.fireDate = date
UIApplication.sharedApplication().scheduleLocalNotification(notification)
But how can I run it every hour or every day? Any idea?
First: add an extension to the Date class:
extension Date {
func currentTimeMillis() -> Int64 {
return Int64(self.timeIntervalSince1970 * 1000)
}
}
then call this function in the viewDidLoad():
func run24HoursTimer() {
let currentDate = Date()
let waitingDateTimeInterval:Int64 = UserDefaults.standard.value(forKey: "waiting_date") as? Int64 ?? 0
let currentDateTimeInterval = currentDate.currentTimeMillis()
let dateDiffrence = currentDateTimeInterval - waitingDateTimeInterval
if dateDiffrence > 24*60*60*1000 {
// Call the function that you want to be repeated every 24 hours here:
UserDefaults.standard.setValue(currentDateTimeInterval, forKey: "waiting_date")
UserDefaults.standard.synchronize()
}
}
There is a separate property on a local notification called repeatInterval. See reference
notification.repeatInterval = .Day
Also keep in mind to register in application delegate (didFinishLaunchingWithOptions method) for local notification (alert asking for permission will be presented for the first time). In Swift this will be (an example):
if UIApplication.instancesRespondToSelector(Selector("registerUserNotificationSettings:"))
{
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge], categories: nil))
}
I would also recommend setting time zone for the notification, could be like this (example):
notification.timeZone = NSTimeZone.localTimeZone()
Not sure about "run function every...". This will create a notification fired with the specified repeat interval. I found this tutorial helpful.
Use This :-
1). save your daily time in user defaults
2). set notification on time for next day
3). check in app delegate if time is passed or not
4). if it is passed then set next day notification
5). if you change time update user defaults
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
let request = UNNotificationRequest(identifier: indentifier, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: {
(errorObject) in
if let error = errorObject{
print("Error \(error.localizedDescription) in notification \(indentifier)")
}
})
You mean something like this?
let timer = NSTimer(timeInterval: 3600, target: self, selector: "test", userInfo: nil, repeats: false)
func test() {
// your code here will run every hour
}
Put all that code in one class. Much more info at #selector() in Swift?
//Swift >=3 selector syntax
let timer = Timer.scheduledTimer(timeInterval: 3600, target: self, selector: #selector(self.test), userInfo: nil, repeats: true)
func test() {
// your code here will run every hour
}
Note: Time Interval is in seconds
Reference : How can I use NSTimer in Swift?

Resources