How to conditionally push local notification in ios app? - ios

i'm working on an ios app which will send notification after the app being sent to the background. I only want the notification to work when the user set a value to true in MainviewController.swift. So I have something like this :
func setDelegateToTrue () {
Appdelegate().setToStart()
}
func setDelegateToFalse () {
Appdelegate().setToEnd()
}
and in my Appdelegate.swift, I have something like this :
var started = false
func applicationDidEnterBackground(application: UIApplication) {
if(started) {
let notification: UILocalNotification = UILocalNotification()
notification.category = "FIRST_CATEGORY"
notification.alertBody = "do not forget your app"
notification.repeatInterval = NSCalendarUnit.Day
notification.timeZone = NSTimeZone.defaultTimeZone()
UIApplication.sharedApplication().scheduleLocalNotification(notification)
started = false
}
}
func setToStart() {
started = true
}
func setToEnd() {
started = false
}
The notification works fine while there is no if statement, however, when I have the if statement and call setDelegateToTrue() in viewdidload, it stopped working. It seems like the boolean value started was to changed after calling setToStart(), but I actually can print things out of setToStart(). Can anyone help me?

Your problem is that you're creating a new instance of AppDelegate when you run AppDelegate().setToStart(). So, when the application delegate it called later it's flag is still set to false, because you set a flag on a different instance (which was immediately destroyed).
To do what you're currently trying to you need to get the delegate from UIApplication (the sharedApplication) and set the flag on that.
Bear this in mind when communication with view controllers and such in OO languages as you always need to get the instance you want to talk to rather than create a new one.

For this behaviour you can make use of NSUserDefault:
Set the value inside the Main ViewController as:
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "shouldSendNotification")
And access this user default in applicationDidEnterBackground of app delegate as follow:
func applicationDidEnterBackground(application: UIApplication) {
let shouldSendNotification = NSUserDefaults.standardUserDefaults().boolForKey("shouldSendNotification")
if shouldSendNotification {
let notification: UILocalNotification = UILocalNotification()
notification.category = "FIRST_CATEGORY"
notification.alertBody = "do not forget your app"
notification.repeatInterval = NSCalendarUnit.Day
notification.timeZone = NSTimeZone.defaultTimeZone()
UIApplication.sharedApplication().scheduleLocalNotification(notification)
NSUserDefaults.standardUserDefaults().setBool(false, forKey: "shouldSendNotification")
}
}

You need to do is
func setDelegateToTrue () {
AppDelegate.sharedAppDelegate().setToStart()
}
func setDelegateToFalse () {
AppDelegate.sharedAppDelegate().setToEnd()
}

Related

How to put notes/reminder on the Lock screen

I want create a app to save the notes, reminders, daily task and want to display these on the Lockscreen and when user tap the note, app will open and display the task on its screen with Customised view and background. I've done a lot of search about how to do this but got no luck.
For reference
ScreenMemo, Task Paper and many more apps doing the same.
I've no Idea which library to use to achieve this. Please help and share your code/links for better understandability.
Thanks
What you can do is to let your app display a Local Notification. Local notification pops up on the Lock screen with your desired text and clicking on it will open your App. You can as well configure which page to open the app if the notification is clicked.
Here is an example:
Step1:
import UIKit
Step2:
override func viewDidLoad() {
super.viewDidLoad()
let notification = UILocalNotification()
if #available(iOS 8.2, *) {
notification.alertTitle = "Notification Title!"
} else {
// Fallback on earlier versions
}
notification.alertBody = "This is the notification text"
notification.fireDate = NSDate(timeIntervalSinceNow: 10)
notification.applicationIconBadgeNumber = 1
notification.timeZone = NSTimeZone.defaultTimeZone()
notification.soundName = UILocalNotificationDefaultSoundName
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
//showinitial = false
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
Happy coding!

How to get notification on iOS on change of network in not running state

In Android there is a broadcast sent by the OS whenever there is change in system configurations(like change in network state etc).
Those broadcast messages can be received by the broadcastreceiver in our app and change the behaviour of the app accordingly,though our app is not in running state.
How I can achieve the similar broadcastreceiver behavior in iOS?
You can use NSNotificationCenter to monitor changes.
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: "batteryLevelChanged:",
name: NSUserDefaultsDidChangeNotification,
object: nil)
Here is the API reference:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/
EDIT 1:
For your case, you can follow the steps and try.
Using library Reachability to get notification on changing of
network and define customized notification function.
func reachabilityChanged(note: NSNotification) {
let reachability = note.object as! Reachability
if reachability.isReachable() {
if reachability.isReachableViaWiFi() {
print("Reachable via WiFi")
} else {
print("Reachable via Cellular")
}
} else {
print("Network not reachable")
}
}
In your notification function, create a corresponding local
notification
var notification = UILocalNotification()
notification.alertBody = "Notification message!!!" // text that will be displayed in the notification
notification.alertAction = "open" // text that is displayed after "slide to..." on the lock screen - defaults to "slide to view"
notification.fireDate = NSDate() // todo item due date (when notification will be fired)
notification.soundName = UILocalNotificationDefaultSoundName // play default sound
notification.userInfo = ["UUID": UUID, ] // assign a unique identifier to the notification so that we can retrieve it later
notification.category = "CATEGORY"
UIApplication.sharedApplication().scheduleLocalNotification(notification)
You have use Reachability class in order to implement network change notification, here is example:
https://developer.apple.com/library/ios/samplecode/Reachability/Listings/Reachability_Reachability_h.html

Geofencing UILocalNotification not working properly swift

I am facing a strange problem with local notification in swift.
I am presenting local notification like this
let notification = UILocalNotification()
var body = "Hi Krishna";
if(region.identifier == "entry1") {
body += " Welcome";
} else {
body += " Bye! Bye!";
}
notification.alertBody = body
notification.soundName = "Default";
notification.userInfo = ["id": "id"];
notification.fireDate = NSDate(timeIntervalSinceNow: 1)
UIApplication.sharedApplication().scheduleLocalNotification(notification)
and how I am handling launch options in my appdelegate
if(launchOptions != nil) {
window?.rootViewController?.view.backgroundColor = UIColor.cyanColor();
if let notification = launchOptions![UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification {
window?.rootViewController?.view.backgroundColor = UIColor.blackColor();
if let userInfo = notification.userInfo {
window?.rootViewController?.view.backgroundColor = UIColor.blueColor();
if let id = userInfo["id"] as? String {
window?.rootViewController?.view.backgroundColor = UIColor.redColor();
}
}
}
}
for debugging purpose I am changing the background color of the view.
when I tap to the notification I get the cyan color that means below line is failing
launchOptions![UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification
because I set cyan color right above this line.
so I am not getting why this is not castable to UILocalNotification?
can somebody help me to get rid from this issue?+
one more thing actually if I am doing it normally its working but I am using geofencing and I am scheduling notification from
locationManager(manager: CLLocationManager, didExitRegion region: CLRegion)
In this case its not working.
You could implement application(_:didReceiveLocalNotification:) (which gives you the notification directly) in your AppDelegate and handle the notification there.
More: https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/index.html#//apple_ref/occ/intfm/UIApplicationDelegate/application:didReceiveLocalNotification:
Can you please try to cast like this:
if let notification:UILocalNotification = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification {
//do stuff with notification
}

how to cancel a localNotification with the press of a button in swift?

I am scheduling a location based UILocalNotification with the click of a button . But when i try to cancel the localNotification by clicking the same button again, it doesn't cancel the notification.
I am using UIApplication.sharedApplication().cancelLocalNotification(localNotification)
to cancel my scheduled location based local notification.
What am i doing wrong ?
here is my implementation
#IBAction func setNotification(sender: UIButton!) {
if sender.tag == 999 {
sender.setImage(UIImage(named: "NotificationFilled")!, forState: .Normal)
sender.tag = 0
regionMonitor() //function where notification get scheduled
} else {
sender.setImage(UIImage(named: "Notification")!, forState: .Normal)
sender.tag = 999 }
what should i enter into the else block so that the scheduled notification gets canceled. Cannot clear all notifications.
here is the didEnterRegion block code where i trigger the local notification
func locationManager(manager: CLLocationManager!, didEnterRegion region: CLRegion!) {
localNotification.regionTriggersOnce = true
localNotification.alertBody = "Stack Overflow is great"
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
NSLog("Entering region")
}
You could try to remove all notifications if this is acceptable in your context.
Like this:
for notification in UIApplication.sharedApplication().scheduledLocalNotifications as! [UILocalNotification] {
UIApplication.sharedApplication().cancelLocalNotification(notification)
}
Or as stated by Logan:
UIApplication.sharedApplication().cancelAllLocalNotifications()
Or as stated by Gerard Grundy for Swift 4:
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
You can cancel a notification using its identifier :
let center = UNUserNotificationCenter.current()
center.removeDeliveredNotifications(withIdentifiers: [String])
center.removePendingNotificationRequests(withIdentifiers: [String])
Solution for iOS 10+ Swift 3.1
let center = UNUserNotificationCenter.current()
center.removeAllDeliveredNotifications() // To remove all delivered notifications
center.removeAllPendingNotificationRequests()
You can save a unique value for key in your local notification's userinfo and cancel it by getting the localnotification using that key's Value.
Try this (for Objective C):
NSArray *notifArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
for (int i=0; i<[notifArray count]; i++)
{
UILocalNotification* notif = [notifArray objectAtIndex:i];
NSDictionary *userInfoDict = notif.userInfo;
NSString *uniqueKeyVal=[NSString stringWithFormat:#"%#",[userInfoDict valueForKey:#"UniqueKey"]];
if ([uniqueKeyVal isEqualToString:keyValToDelete])
{
[[UIApplication sharedApplication] cancelLocalNotification:notif];
break;
}
}
For Swift 3.0 and iOS 10:
UNUserNotificationCenter.current().removeAllDeliveredNotifications()
Hard to tell without seeing the implementation of the code.
so you have an
- IBAction methodName{
//scheduleNotification
//cancelNotification
}
Is that about right? If so add a bool so
Bool didCancel;
- IBAction methodName{
if didCancel == No{
//scheduleNotification
didCancel = YES;
}else if didCancel == YES{
//cancelNotifications
didCancel = NO;
}

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).

Resources