Local banner notification for terminating App - ios

I want to show banner notification when user quits the Application. And on tapping that banner I want my Application to open.
func showBanner() {
UIApplication.shared.cancelAllLocalNotifications()
let notif = UILocalNotification.init()
notif.alertBody = "Your Message Here..."
localNotif.soundName = UILocalNotificationDefaultSoundName
UIApplication.shared.presentLocalNotificationNow(notif)
}
If I put this code in applicationDidEnterBackground it works fine; But, when I put it in applicationWillTerminate, it doesn't.
Any workaround?
EDIT:
Added fireDate like following:
var dc = DateComponents()
dc.second = 2 // 2 seconds from current date time
notif.fireDate = Calendar.current.date(byAdding: dc, to: Date())
Still not working. Any idea?

The same code works when I set in App communicates using CoreBluetooth in info.plist for Requires Background Modes.
Got the hint from This Answer
Let's hope, Apple does not reject my App.

no guarantee that applicationWillTerminate will ever get called may that is the reasone your code not working . so if your need to do anything before app exist then call applicationDidEnterBackground
more check this iOS - How to guarantee that applicationWillTerminate will be executed

Related

Local Notification on offline (Swift)

I want to receive a local notification in my app (swift) when I'm not connected to Internet and I have some information registered in my Local Data base.
Is it possible to do that please?
Local Notification doesnot requires internet.
About Local Notification from apple developer site
Local notifications give you a way to alert the user at times when your app might not be running. You schedule local notifications at a time when your app is running either in the foreground or background. After scheduling a notification, the system takes on the responsibility of delivering the notification to the user at the appropriate time. Your app does not need to be running for the system to deliver the notification.
For more info check this link. You can also check this link for tutorial.
do like this :
public func presentNotification(_ notifAction: String, notifBody: String) {
let application = UIApplication.shared
let applicationState = application.applicationState
if applicationState == UIApplicationState.background {
let localNotification = UILocalNotification()
localNotification.alertBody = notifBody
localNotification.alertAction = notifAction
localNotification.soundName = UILocalNotificationDefaultSoundName
localNotification.applicationIconBadgeNumber += 1
application.presentLocalNotificationNow(localNotification)
}
}
UIApplicationState has these states :
case active
case inactive
case background

How to Run a Task in swift on a particular date-time in background either application is on or off

I am working on alarm application, i need to schedule alarm on specific time, I use scheduleLocalNotification for scheduling alarms and it's working fine as i want. BUT I need to run to a request to my API server before triggering alarm. In that request I want to check some parameters returning from API server, If that satisfies some condition.
If any one have a method that run on a particular date - time in swift
Please help me for that
func addAlarm (newAlarm: Alarm) {
// Create persistent dictionary of data
var alarmDictionary = NSUserDefaults.standardUserDefaults().dictionaryForKey(ALARMS_KEY) ?? Dictionary()
// Copy alarm object into persistent data
alarmDictionary[newAlarm.UUID] = newAlarm.toDictionary()
// Save or overwrite data
NSUserDefaults.standardUserDefaults().setObject(alarmDictionary, forKey: ALARMS_KEY)
scheduleNotification(newAlarm, category: "ALARM_CATEGORY")
scheduleNotification(newAlarm, category: "FOLLOWUP_CATEGORY")
}
/* NOTIFICATION FUNCTIONS */
func scheduleNotification (alarm: Alarm, category: String) {
let notification = UILocalNotification()
notification.category = category
notification.repeatInterval = NSCalendarUnit.Day
switch category {
case "ALARM_CATEGORY":
notification.userInfo = ["UUID": alarm.UUID]
notification.alertBody = "Time to wake up!"
notification.fireDate = alarm.wakeup
notification.timeZone = NSTimeZone.localTimeZone()
notification.soundName = "loud_alarm.caf"
break
case "FOLLOWUP_CATEGORY":
notification.userInfo = ["UUID": alarm.followupID]
notification.alertBody = "Did you arrive yet?"
notification.fireDate = alarm.arrival
notification.timeZone = NSTimeZone.localTimeZone()
notification.soundName = UILocalNotificationDefaultSoundName
break
default:
print("ERROR SCHEDULING NOTIFICATION")
return
}
print("Notification=\(notification)")
// For debugging purposes
if alarm.isActive {
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}
}
Waking up an app through a local notification is not possible, this is available only for remote notifications. According to the Notification Programming Guide:
When a remote notification arrives, the system handles user
interactions normally when the app is in the background. It also
delivers the notification payload to the
application:didReceiveRemoteNotification:fetchCompletionHandler:
method of the app delegate in iOS and tvOS
But there is still a catch; even then it is not guaranteed that the app will be launched since, according to didReceiveRemoteNotification:fetchCompletionHandler: documentation:
However, the system does not automatically launch your app if the user
has force-quit it. In that situation, the user must relaunch your app
or restart the device before the system attempts to launch your app
automatically again.
I don't think there is a guaranteed way to schedule a block for execution in some later moment, independently from the state of the app at that time. Depending on your specific requirements and frequency, you could perhaps register for the fetch background mode and implement application:performFetchWithCompletionHandler: to opportunistically fetch and validate server data. Last note: make sure that you are a responsible background app (from my experience Apple takes this requirement seriously)

What function gets called when loading app from homescreen?

I want to be able to change the background color of my app depending on the time of day. I believe the way to go about this is saying if the hour component is greater than whatever number, set the background to the nighttime background, otherwise it's the daytime background.
To test out what I was worried about, I threw
timeLabel.text = NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .NoStyle, timeStyle: .FullStyle)
into viewDidLoad. This shows the time that the app loads. This also obviously keeps updating if I kill the app and reload it completely.
However, if the user goes the the home screen or goes to a different app, then comes back to this the time isn't going to be updated. It will show the time the app was first loaded up. Only if the user completely kills the app, which obviously can't be relied on, will the correct time be shown.
So in my example if my "switch to nighttime time" was 5pm, if the user loads up at the at at 4:30 and then goes to the homescreen, loads up the app at 5pm, nothing will be changed as the stored time will still be 4:30.
I tried throwing the code in viewDidAppear and nothing changed.
What code is run when the app is loaded up from being on the homescreen or coming back from another app?
You want to key off of the UIApplicationDidBecomeActiveNotification event. Try this:
override func viewDidLoad()
{
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: "applicationDidBecomeActive:",
name: UIApplicationDidBecomeActiveNotification,
object: nil)
}
func applicationDidBecomeActive(notification: NSNotification)
{
// do something when the app is active again.
timeLabel.text = NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .NoStyle, timeStyle: .FullStyle)
}
The method -applicationWillEnterForeground: in your application delegate will be called every time a user enters your app.
You'll want to look at using NSCalendar for this:
let currentDate = NSDate() // You can input the custom as well
let calendar = NSCalendar.currentCalendar()
let components = calendar.components(.CalendarUnitHour | .CalendarUnitMinute, fromDate: NSDate())
let currentHour = components.hour // You can play around with the ""components""
The following method is what you're after:
applicationDidBecomeActive: it's called every time a user opens the app.

iOS Local Notification Trigger Handling

I am currently making an app which counts the steps walked and check with goal and release local notification if met.
I have set up the local notification but I want that to trigger just once at that moment. I got this working through dispatch_once_t:
if stepsData >= stepsGoalData {
let localNotification = UILocalNotification()
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
localNotification.fireDate = NSDate()
localNotification.alertBody = "Acheived"
localNotification.soundName = UILocalNotificationDefaultSoundName
}
But in case if the user increases the stepsGoalData, currently the code doesn't trigger the notification. Can someone please provide me with an idea to handle this case. Thank you!
So, you should really just change the check for wether to notify or not so that it considers not just the count but also a flag to indicate if the notification has been made. This can be a var defined beside your stepsGoalData as a simple Bool.
Now, your check would be:
if stepsData >= stepsGoalData && !hasNotified {
hasNotified = true
...
And when you set the stepsGoalData to a new target value you also set hasNotified = false.

Executing code, when the application is in background not working on physical device (SWIFT)

I am making an app, that is reliant on executing some minor code in the background and I ran into a peculiar problem.
The app has a timer, an NSTimer(). The principle behind all of this is similiar to that of timer (in Clock application, that is installed on all iOS devices), meaning, when the timer ends a UILocalNotification is displayed.
Everything works as expected when I run it on an emulated device in Xcode, but when I test it on my iPhone, there are no notifications. It is something along the lines of:
var end = timerHasEnded()
if end == true{
println("the timer has ended")
}
and it was not working. So I checked if the application even detects the background UIApplicationState by doing this and it does not on the physical device. Interestingly enough, it does so on an emulated device.
I tried running the timer on background thread, using QOS_CLASS_BACKGROUND and dispatch_async to no avail. Can anybody help me?
Could you just schedule a UILocalNotification to appear after a delay, when the delay was the remaining time left in your alarm?
var date: NSDate = /*time until your timer expires*/
let app = UIApplication.sharedApplication()
let oldNotifications = app.scheduledLocalNotifications
if oldNotifications.count > 0 {
app.cancelAllLocalNotifications()
}
let alarm = UILocalNotification()
alarm.fireDate = date
alarm.timeZone = NSTimeZone.defaultTimeZone()
alarm.repeatInterval = 0
alarm.soundName = "myAlarmSound.caf"
alarm.alertBody = "Do something!"
app.scheduleLocalNotification(alarm)
I wrote this code from an Obj-C example provided by Apple.
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

Resources