Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why NSTimer works just once in swift

Tags:

ios

swift

I have a http request, and if I receive the response correctly, then I want to start a timer that fires a function each second. That function is also a http request.

this is my code to fire the timer

    if let data = data {
        do{
            let resultJSON = try NSJSONSerialization.JSONObjectWithData(data, options: [])
            requestClient.id = resultJSON["id"] as! Double
            self.timerResponse = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "checkIfThereAreResponeses", userInfo: nil, repeats: true)
            self.timerResponse!.fire()
        }catch{
        }
    }

as you see, I'm calling a function called checkIfThereAreResponses

In that function, i have a print statement, and that print statement is being printed just once, though my timer supposed to work each 1 second

what missing i have?

And this is the function

 func checkIfThereAreResponeses(){
    if (requestClient!.id != nil) {
        let url = NSURL(string: "http://localhost:blablabla")
        let request = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "POST"

        let session = NSURLSession.sharedSession()

        task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
            if let error = error {
                print("error = \(error)")
            }



            if let data = data {
                do {
                    let resultJSONArray = try NSJSONSerialization.JSONObjectWithData(data, options: []) as! NSArray
        bla bla bla

                }catch {
                    print("no responses yet = \(error)")
                }
            }
        })
        task!.resume()
    }else {
        print("not yet ")
    }
}

the print that i receive JUST ONCE is the no response yet

like image 276
sarah Avatar asked Jan 17 '16 12:01

sarah


People also ask

Does NSTimer run in background?

Problem is, NSTimer requires an active run loop which is not always readily available on background queues. The main thread has an active run loop but this defeats the purpose of having our timer run in the background so its a definite no go. So, to get a dedicated background-queue-friendly timer, we use GCD.

What is NSTimer in Swift?

A timer that fires after a certain time interval has elapsed, sending a specified message to a target object.

How do you create a 60s countdown timer that prints out the seconds remaining every second Swift?

Underneath the timerLabel outlet create the following variables: var seconds = 60 //This variable will hold a starting value of seconds. It could be any amount above 0. var timer = Timer() var isTimerRunning = false //This will be used to make sure only one timer is created at a time.


1 Answers

If you have this code in completion handler, it is recommended NSTimer is running in the main thread so this could be the reason. You might need something like:

dispatch_async(dispatch_get_main_queue(), {
    // Your timer logic here
})

Apple docs say:

Timers work in conjunction with run loops. To use a timer effectively, you should be aware of how run loops operate—see NSRunLoop.

(NSTimer)

The NSRunLoop class is generally not considered to be thread-safe and its methods should only be called within the context of the current thread. You should never try to call the methods of an NSRunLoop object running in a different thread, as doing so might cause unexpected results.

(NSRunLoop)

like image 192
Martin Makarsky Avatar answered Sep 27 '22 17:09

Martin Makarsky