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_PRIORITY_BACKGROUND, 0)) {
scheduleFutureLocalNotifications()
}
}