0

So guys, my problem is that i can't work with timers while i am using gui. My timer is in ViewController and code:

    DispatchQueue.main.async {

        Timer.scheduledTimer(timeInterval: 1, target: self.songView, selector: #selector(self.songView.update), userInfo: nil, repeats: true)
    }

I also tried in outside in dispatchqueue. However, there is a songview and it's update code looks like:

func update(){


    DispatchQueue.main.async(execute: {
        let theState = self.executeAppleScript(args: self.playerStateArgs, waitReturn: true)
        let songName = self.executeAppleScript(args: self.songNameArgs, waitReturn: true)
        let bandName = self.executeAppleScript(args: self.bandNameArgs, waitReturn: true)
        let artworkUrl = self.executeAppleScript(args: self.artworkArgs, waitReturn: true)

        self.songField.stringValue = songName
        self.bandField.stringValue = bandName

        let url: URL = URL.init(string: artworkUrl)!
        self.albumCoverView.image = NSImage.init(contentsOf: url)

        NSLog("\(songName)")
    })


}

I tried the code outside of the Dispatch queue as well. Non of the combination works for me. Timer works and update function prints the song name every second but when i open the app(menu bar app) gui, update function stops and no Log operation happens. I tried so many things and looked all of the issues here. Unfortunately non of them helped me. Thanks in advance

Edit: While gui is off:

enter image description here

While gui is on:

enter image description here

While off, timer is working. While on, it is not.

aliyasineser
  • 186
  • 3
  • 15
  • I edited the post. You can check again. I added a View as SongView and I linked to a new controller. I have one menu view and inside of it, another view. Both linked to controller. I can add extra info if you want. – aliyasineser Sep 11 '17 at 07:48
  • 1
    Running 4 AppleScripts can take much longer than 1 second. For performance reasons consider to run **one** AppleScript passing the parameters in an array and returning an array. Sending AppleEvents is pretty expensive. An alternative is to trigger an one-shot timer one second after all information has been returned. Rather than this permanent polling consider to get the duration of the current track and refresh the UI after the song has finished. – vadian Sep 11 '17 at 08:55
  • Or subscribe to the distributed notification `com.apple.iTunes.playerInfo` to get notified when a track changes. – vadian Sep 11 '17 at 09:01
  • 1
    you need to add your timer to the main runloop .commonModes https://stackoverflow.com/questions/27997485/nstimer-not-firing-when-nsmenu-is-open-in-swift/27997548#27997548 – Leo Dabus Sep 11 '17 at 09:02
  • @LeoDabus In this case the OP should use the *unscheduled* timer API. – vadian Sep 11 '17 at 09:05
  • @vadian look at OP's last statement "While off, timer is working. While on, it is not." – Leo Dabus Sep 11 '17 at 09:06
  • 1
    @LeoDabus I mean if the timer is added explicitly to the runloop the API `init(timeInterval ... )` rather than `scheduledTimer(timeInterval...` has to be used because the latter is scheduled implicitly on the current run loop. – vadian Sep 11 '17 at 09:10
  • 1
    Feel free to reopen the question if you would like to answer it. – Leo Dabus Sep 11 '17 at 09:11
  • 1
    @LeoDabus , it worked! Adding it to runloop solved the problem! How did you notice that? I really want to know the problem. – aliyasineser Sep 11 '17 at 09:30
  • @vadian You are right, i am gonna change it. However, i was thinking to create applescripts seperate and easy to maintain. I didn't know the performance will decrease so badly as you say. Is creating one applescript can solve the performance problem? – aliyasineser Sep 11 '17 at 09:30
  • Not necessarily. Even one AppleScript can take longer than one second. It depends on how many AppleEvents are sent. – vadian Sep 11 '17 at 09:36

0 Answers0