when creating an alarm clock, is it the right way to directly display all scheduled local notifications on a table view? If so, After the notifications have fired they disappear. How can i stop them from disappearing so i can use switches to set them on and off?
What i understood about UIswitch is that i have to cancel the notification when off then reschedule them when on.
#IBAction func addAlarm(sender: UIButton) {
let notification = UILocalNotification()
notification.fireDate = timePicker.date.fireDate
notification.timeZone = NSTimeZone.localTimeZone()
notification.alertBody = "Its time"
notification.applicationIconBadgeNumber = UIApplication.sharedApplication().applicationIconBadgeNumber + 1
notification.hasAction = true
notification.alertAction = "View"
UIApplication.sharedApplication().scheduleLocalNotification(notification)
alarmTable.reloadData()
}
Use an array to store the times of the alarms.
Then you can easily show and manage them and create UILocalNotifications based on them.
You have to define the timezone before defining the firedate
Related
Is there any option to kill/hide/cancel current Toast Notification under Android 10 + TNS?
I want to show the meaning of some words by tapping on them, but under Android 10 user needs to wait until previous Toast Notification times out until he/she can see the next one.
The answer is found!
just store the Toast.makeText( var ) in a variabile like myToast and use cancel() function to remove it.
let myToast = Toast.makeText( var ); // show() function shouldn't be used here!
myToast.show();
...
myToast.cancel();
I have set up some code that looks like this
let queue = DispatchQueue(label: "queue.1", qos: .utility, attributes: .concurrent)
queue.async {
AppUtility().run(X: self.BitCount)
}
Here is the function that is called:
public func run(X: UILabel) {
var placeHolder = 0
while placeHolder == 0{
if globalValues.bitsPerSecond != 0 {
globalValues.Bits = globalValues.Bits + 1
//globalValues.bitsPerSecond
print("Ran")
}
UserDefaults.standard.set(globalValues.Bits, forKey: "bits")
X.text = "\(globalValues.Bits)"
sleep(1)
}
}
This code will update a label everysecond through a counter while the user is looking at the screen. From what I have read I believe my code to be correct however I have no Idea where to put it so it can always run in the background. Any help?
I have no Idea where to put it so it can always run in the background
In iOS, code doesn't run in the background. When your app is backgrounded, it is suspended.
If the idea is that the label should have the right value when the app comes back into the foreground, as if the counting had gone on while in the background, then just use the activation event as a signal to calculate how long we were backgrounded and adjust the label value accordingly.
Currently when i create a NSUserNotification using Alert style it won't hide unless i manually close it.
Is there a way i can auto close/hide it say after 2 sec?
NSUserNotification code is for reference :
let notification:NSUserNotification = NSUserNotification()
notification.title = "Title"
notification.subtitle = "Subtitle"
notification.informativeText = "Informative text"
notification.soundName = NSUserNotificationDefaultSoundName
notification.deliveryDate = NSDate(timeIntervalSinceNow: 10)
notification.hasActionButton = false
let notificationcenter:NSUserNotificationCenter = NSUserNotificationCenter.defaultUserNotificationCenter()
notificationcenter.scheduleNotification(notification)
It's actually very simple to do this, using NSObject's
performSelector:withObject:afterDelay: method.
Because you're scheduling the notification delivery after a certain time interval, you need to add the additional delay before dismissing, to the initial delay before delivering. Here, I've written them out as constants of 10 seconds before delivery, and 2 seconds before dismissal:
let delayBeforeDelivering: NSTimeInterval = 10
let delayBeforeDismissing: NSTimeInterval = 2
let notification = NSUserNotification()
notification.title = "Title"
notification.deliveryDate = NSDate(timeIntervalSinceNow: delayBeforeDelivering)
let notificationcenter = NSUserNotificationCenter.defaultUserNotificationCenter()
notificationcenter.scheduleNotification(notification)
notificationcenter.performSelector("removeDeliveredNotification:",
withObject: notification,
afterDelay: (delayBeforeDelivering + delayBeforeDismissing))
And for Swift 5 you can use the following:
let delayBeforeDelivering: TimeInterval = 10
let delayBeforeDismissing: TimeInterval = 2
let notification = NSUserNotification()
notification.title = "Title"
notification.deliveryDate = Date(timeIntervalSinceNow: delayBeforeDelivering)
let notificationcenter = NSUserNotificationCenter.default
notificationcenter.scheduleNotification(notification)
notificationcenter.perform(#selector(NSUserNotificationCenter.removeDeliveredNotification(_:)),
with: notification,
afterDelay: (delayBeforeDelivering + delayBeforeDismissing))
You can use removeDeliveredNotification: or removeAllDeliveredNotifications with timer
// Clear a delivered notification from the notification center. If the notification is not in the delivered list, nothing happens.
- (void)removeDeliveredNotification:(NSUserNotification *)notification;
// Clear all delivered notifications for this application from the notification center.
- (void)removeAllDeliveredNotifications;
OS X (10.8 and later)
Blockquote Is there a way i can auto close/hide it say after 2 sec?
No, you do not have any such option till OSX 10.11, may be in future Apple may provide.
There are three ways a user can customise the NSUserNotification also known as Growl notification:
None
Banner
Alert
You as a developer can not control over the system settings. This is upto the user to enable or disable and choose what kind of notification he likes.
If you want any alert to be shown to user you can create your own alert window and show it in that corner. You can set a timer to close, or provide action button to close it once you need.
Update 1:
Cocoa provides NSWindow & NSPanel(HUD and normal panel). You can either customize Window or panel according to your need. Check there are multiple options that would help you to form as per your requirement.
If you can't get, say you wanted a rounded corner then you need to customize the window/view etc.
I'm using:
var alarm = NSUserNotification()
var currentTime = NSDate()
alarmTime = currentTime.dateByAddingTimeInterval(60)
alarm.deliveryDate = alarmTime
NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification(alarm)
To get a notification that will fire an hour from the current time, the problem is I want the app to automatically set up another alarm after the first one finishes. NSTimer doesn't seem like it will work because once the app goes to the background it kills the timer. What can I do to achieve this? Can I piggy back another method onto a NSUserNotification
Edit: it also needs to be dynamic, I can't just set the repeat variable of the notification because I need to be able to switch how far out the alarm will be each time it resets.
You just have to set your deliveryRepeatInterval and deliveryTimeZone, as follow:
// set your deliveryTimeZone to localTimeZone
alarm.deliveryTimeZone = NSTimeZone.localTimeZone()
// The date components that specify how a notification is to be repeated.
// This value may be nil if the notification should not repeat.
// alarm.deliveryRepeatInterval = nil
// The date component values are relative to the date the notification was delivered.
// If the calendar value of the deliveryRepeatInterval is nil
// the current calendar will be used to calculate the repeat interval.
// alarm.deliveryRepeatInterval?.calendar = NSCalendar.currentCalendar()
// to repeat every day, set .deliveryRepeatInterval.day to 1.
alarm.deliveryRepeatInterval?.day = 1
// to repeat every hour, set .deliveryRepeatInterval.hour to 1.
alarm.deliveryRepeatInterval?.hour = 1
alarm.deliveryDate = NSDate().dateByAddingTimeInterval(60)
NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification(alarm)
I have a determinate progress indicator. It is working just like I would expect it to but it does not disappear after it reaches maxValue. I have set the progress indicator to not display when stopped in the main.nib file, I have also entered it into the awakeFromNib{} method.
I put a log at the end of the routine to make sure the [displayWhenStopped] setting was still set to NO and it is.
Here is my code :
-(void)getEvents:(NSURL *)mffFile{
NSMutableArray * eventTypeResults =[[NSMutableArray alloc]init];
EWaveformRecording *ptrToRcdFile = [EWaveformRecording openRecording:mffFile permission:readOnly user:nil convertFileFormat:NO openReadOnlyAnyway:NO];
NSArray *events = [ptrToRcdFile getEvents];
//get the size of events for the progressbar and instantiate a loop counter
NSInteger total = [events count];
int loop = 0;
//set progress bar params
[self->meter_ setUsesThreadedAnimation:YES];
[self->meter_ setControlSize:NSMiniControlSize];
[self->meter_ setMaxValue:(double)total];
for(EEvent* event in events){
loop ++;
if(![eventTypeResults containsObject:event.code]){
NSLog(#"check eventNames in getEvents %#", event.code);
[eventTypeResults addObject: event.code];
}//end if
//display loop increment in progress bar
[self->meter_ setDoubleValue:(1000*(double)loop)/1000];
}//end for
//send the eventTypesResults array to the EventExport class
[evtPtr setEventsAvailableList:eventTypeResults];
}
What I have tried:
with and without [setUsesThreadedAnimation] which I don't totally understand; it does slow down the progress bar which makes it look better but the docs say only indeterminate types should be effected by animation.
I have tried using [start & stop animation]
I have tried [setDisplayWhenStopped:NO] after my loop
Any help is greatly appreciated
MIke
This is what I learned.
I should not be allowing the progress bar to run on a different thread even though it looks like its working because the NSProgressIndicator can no longer respond to the settings in the main thread, so the proper thing to do is to not instantiate that method, however , that was not the solution to my problem; I was doing everything else right, but the main thread could not redraw the progress because it's busy with all the other calls in the UI. The solution was to implement NSRunLoop so that each iteration of the loop interrupts the main thread and redraws the progress meter , then returns control.