백그라운드에서 작동하는 Timer 만들기 질문

2 답변 글타래를 보이고 있습니다
  • 글쓴이
    • Dohyun Lee
      참가자
      • 글작성 : 2
      • 답글작성 : 3

      안녕하세요, 최근에 본격적으로 iOS 공부를 시작한 초보 개발자입니다.

      저만의 토이 프로젝트를 만들고 있는데,

      코드를 짜면서 느끼는 점이, 과연 이 방식으로 짰을 때 올바른(효율적인) 방법일까? 가 궁금하더라구요.

      스크린샷 2021-02-10 오후 11.18.08

      이번에는, 스톱워치를 만들어봤는데 가장 핵심으로 생각한 것은 백그라운드에서도 올바르게 작동하는지 였습니다.

      UIBackgroundTaskIdentifer 등을 찾아봤는데, 최대 작업 시간이 정해져 있는 등 여러가지 말이 많더라구요.

      그래서 생각한 방법은, 나간 시간과 들어온 시간을 알고 있다면 문제를 해결할 수 있지 않을까? (백그라운드에서 작업하는 것도 결국 리소스 낭비이니..) 라는 생각이었습니다.

      그래서 NotificationCenter를 이용하여, 시간 차를 계산하여 해당 문제를 해결하였습니다.

      그러고 나서 든 생각은, 저의 풀이법이 과연 이 문제를 푸는 올바른 방법인지가 너무 궁금하더라구요..

      만약 iOS개발자님들이 이런 앱을 개발해야 한다면, 어떤 식으로 개발을 하실 것 같은지가 궁금합니다!

      동영상과 마크다운 코드가 첨부 안되는 것 같아 제 블로그를 한 번 봐주시면 감사하겠습니다..!! (짧은 코드입니다..)

      import UIKit
      
      class TimeViewController: UIViewController {
      
          @IBOutlet weak var timerLabel: UILabel!
          @IBOutlet weak var timeButton: UIButton!
      
          var timer: Timer? = nil
          var isTimerOn = false
          var timeWhenGoBackground: Date?
          var timeSecond = 0 {
              willSet(newValue) {
                  var hours = String(newValue / 3600)
                  var minutes = String(newValue / 60)
                  var seconds = String(newValue % 60)
                  if hours.count == 1 { hours = "0"+hours }
                  if minutes.count == 1 { minutes = "0"+minutes }
                  if seconds.count == 1 { seconds = "0"+seconds }
                  timerLabel.text = "\(hours):\(minutes):\(seconds)"
              }
          }
      
          override func viewDidLoad() {
              super.viewDidLoad()
              let notificationCenter = NotificationCenter.default
              notificationCenter.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.willResignActiveNotification, object: nil)
              notificationCenter.addObserver(self, selector: #selector(appMovedToForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
          }
      
          @objc func appMovedToBackground() {
              print("App moved to background!")
              if isTimerOn {
                  timeWhenGoBackground = Date()
                  print("Save")
              }
          }
      
          @objc func appMovedToForeground() {
              print("App moved to foreground")
              if let backTime = timeWhenGoBackground {
                  let elapsed = Date().timeIntervalSince(backTime)
                  let duration = Int(elapsed)
                  timeSecond += duration
                  timeWhenGoBackground = nil
                  print("DURATION: \(duration)")
              }
          }
      
          @IBAction func timeBtnClicked(_ sender: Any) {
              if isTimerOn {
                  timer?.invalidate()
                  timeButton.setTitle("START", for: .normal)
              } else {
                  self.timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
                      self.timeSecond += 1
                      print("\(self.timeSecond)")
                  }
                  RunLoop.current.add(self.timer!, forMode: .common)
                  timeButton.setTitle("STOP", for: .normal)
              }
              isTimerOn = !isTimerOn
          }
      

      동영상
      https://walwal234.tistory.com/48?category=1178557

      • 이 게시글은 Dohyun Lee에 의해 3 years, 2 months 전에 수정됐습니다.
    • 야곰
      키 마스터
      • 글작성 : 37
      • 답글작성 : 580

      마크다운 문법대로 작성하면 바로 적용됩니다.

      • Dohyun Lee
        참가자
        • 글작성 : 2
        • 답글작성 : 3

        위지위그에 있는 문자가 마크다운을 의미하는지 몰랐네요..!!
        게시글을 수정하였습니다. 감사합니다.

    • cstlex
      참가자
      • 글작성 : 0
      • 답글작성 : 1

      처음 시작할때 시작 시간을 받아온후에 그 시간으로 타이머 계산을 하면 될꺼같네요.

      초당 += 1 하는거보다 시작시간을 받아오고 Date.timeIntervalSinceNow 이용해서 초 계산을 하면 백그라운드문제는 없을꺼같습니다.

2 답변 글타래를 보이고 있습니다
  • 답변은 로그인 후 가능합니다.

logo landscape small

사업자번호 : 743-81-02195
통신판매업 신고번호 : 제 2022-충북청주-1278 호
고객센터 : 카카오톡채널 @yagom