Is it possible to refresh a timer in a Today Widget?
Asked Answered
I

2

9

I was wondering is it possible to update the text label of a timer in a today widget. I took a look around but nothing helped me.

Impressionist answered 18/1, 2015 at 17:4 Comment(1)
I think that the only way to do it is to pass the NSTimeInterval of the main view controller and create another timer in the today widget. I'll figure out a way :]Impressionist
U
13

Yes you can. I have just tested and it works. You just have to add your timer to the main run loop NSRunLoopCommonModes:

RunLoop.main.add(yourTimerName, forMode: .commonModes)

import NotificationCenter

class TodayViewController: UIViewController, NCWidgetProviding {

    @IBOutlet weak var strTimer: UILabel!

    var timer = Timer()

    func updateInfo() {
        strTimer.text = Date().description
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateInfo), userInfo: nil, repeats: true)
        RunLoop.main.add(timer, forMode: .commonModes)
    }
    func widgetPerformUpdate(completionHandler: @escaping (NCUpdateResult) -> Void) {
        completionHandler(.newData)
    }
}
Ultramodern answered 19/1, 2015 at 6:3 Comment(15)
thanks for your answer I have to put that in my code since my timer is running in the main view controller and I'm trying to pass that timer from the view controller to the todayviewcontroller using NSUserDefaults and groupsImpressionist
feel free to open another question with your code I will take a look at it for youUltramodern
the problem is that it is not possible to put timer objects into NSUserDefaults... just try to put the timer in the Main View Controller in your code and call it back to the today widget... :]Impressionist
Passing a timer object between the app and its extension doesn't make a lot of sense. Why can't the extension create its own timer object?Saez
@TomHarrington because I want to see the same timer in the main app and in the today widget and I cannot do that in anyway, I cannot pass either a NSTimer or NSTimerInterval. Why?Impressionist
@Impressionist as I said that's another question. Go ahead and open a new question.Ultramodern
@LeonardoSavioDabus I think I did it! At the moment I'll give a positive answer, thank you so much. I might open another question!Impressionist
@Impressionist as I said, passing the NSTimer doesn't make sense. An NSTimer only calls a method on an object, and objects can only exist in one process. Even if you could pass the NSTimer it would serve no purpose. It should be possible to save an NSTimeInterval to user defaults though, if you need to pass a value back and forth.Saez
@TomHarrington when I'll publish my app I'll show you why I need that. Thanks anywayImpressionist
It would be extremely interesting to hear why you think you need to pass an NSTimer object between two processes, and why using an NSTimeInterval is not sufficient.Saez
This is not true I don't even open my app and I can see the timer runningUltramodern
this solution works quite good, but the only problem is about the viewDidLoad() method, this method is called every time the user swipe to the "Today View Screen". So multiple timer was scheduled. One for each time u swipe to the "Today View Screen" ...Prelate
There is only one timer instance.You can simply invalidate() the timer to make sure you don't add it twice to the run loopUltramodern
Did this. No effect.Sized
@Oleksandr did you find a way to avoid multiple timers?Proconsulate
F
4

I know this is a Swift question, but I found it looking for Objective-C code and so others may too.

-(void) viewDidLoad
{
    [NSTimer scheduledTimerWithTimeInterval:1 // update more than once a second to appear in sync with the system clock
                                     target:self
                                   selector:@selector(updateUi:)
                                   userInfo:nil
                                    repeats:YES];

}


-(void) updateUi:(NSTimer *)timer 
{
   // Update Widget UI as required
}
Fastidious answered 20/9, 2015 at 19:18 Comment(3)
No need to increase the interval to make it appear in sync. You can schedule the timer to fire at the next even second.Ultramodern
how do you do that @LeoDabus?Fastidious
This shows how to do it without the seconds but you can easily change to sync the seconds. https://mcmap.net/q/1172763/-sync-multiple-time-labels-with-host-timeUltramodern

© 2022 - 2024 — McMap. All rights reserved.