본문 바로가기
iOS랑 친해지기

[iOS] 백그라운드일때 이벤트 발생 (NotificationCenter)

by 데브킹덕 2023. 8. 15.

 

- 등록된 옵저버에게 동시에 정보를 브로드 캐스트 할 수 있는 클래스

- NotificationCenter에 등록된 이벤트가 발생하면 이벤트에 대한 행동을 취함

- 백그라운드, 비동기 작업의 결과 등 현재 작업의 흐름과 다른 흐름의 작업으로부터 이벤트를 받을떄 사용함

 

 

옵저버 추가

addObserver(observer:selector:name:object:)

- observer:  옵저버가 될 객체

- selector: 이벤트가 발생했을때 호출될 메서드

- name: 등록하려는 이벤트 이름 (NSNotification.Name 타입)

- objcet: 발송자가 옵저버에게 보내려고 하는 객체

 

- NSNotification.Name: 이벤트의 이름을 나타내는 타입. 주로 문자열 상수로 사용되며, 이벤트 식별에 사용

extension Notification.Name{
	static let devKDuck = Notification.Name("devKDuck")
}

 

옵저버 삭제

removeObserver(observer:name:object:)

- observer: 제거하려는 옵저버

- name: 제거하려는 이벤트 이름 (NSNotification.Name 타입, nil일 경우 모든 이벤트)

- objcet: 제거하려는 이벤트를 발송할 객체(nil일 경우 모든 객체 대상)

 

 

이벤트 발송 - 등록된 옵저버들에게 이벤트를 알리고 데이터를 전달

NotificationCenter.default.post(name: <#T##NSNotification.Name#>, object: <#T##Any?#>)

 

- name: 일을 수행할 옵저버들 

- objcet: 이벤트를 발송한 객체

- userInfo: 이벤트와 관련된 추가 정보(딕셔너리[AnyHashable : Any]?)

 

 

문제 

- Play버튼을 눌러 영어 문장을 번역후 Translate로 번역문을 확인하는 로직

- Play 시간을 정확하게 측정하여 누적시간을 저장하고 싶었음

- Play도중 사용자가 다른 행동을 취해 Background로 갈경우 시간차를 구하고,

재개할때부터 번역할때까지 시간을 합산해 누적시간을 저장하고 싶었음

 

1. Play버튼을 눌렀을 경우

  • RESTful API에서 영어 문장 데이터를 받아와 라벨을 변경
  • 현재 날짜와 시간을 받아오는 Date 객체를 생성
  • Play버튼의 타이틀도 Translate로 변경

 

 

 

관련 코드)

var startTime: Date?

@objc func tapNextJokeButton(_ sender: UIButton) {
	switch sender.titleLabel?.text{
        case "Play":
        //1. API 데이터 받아오는 코드
        fetchData()
        
        //2. 현재 날짜, 시간을 나타내는 Date객체 생성 
        startTime = Date()
        
        //3. 버튼 타이틀 변경
        sender.setTitle("Translate", for: .normal)
        
        case "Translate":
        case "Continue":
	}
}

 

 

 

2.  백그라운드로 이동한 경우

  • Background로 이동할시 현재 시간을 가지는 Data 객체를 생성하여 Play를 누른 시작과의 시간차를 얻고 싶었다.
  • Translate에서 Continue로 버튼 타이틀을 변경해 게임이 멈춰졌음을 사용자에게 알리고 싶었다.

 

 

 

NotificationCenter에 addObserver를 이용해 이벤트를 추가

NotificationCenter.default.addObserver(self, selector: #selector(handleAppBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)

- observer:  현재 뷰

- selector: 이벤트가 발생했을때 호출될 메서드

- name: didEnterBackgroundNotification (앱이 백그라운드에 들어갈때 게시되는 알림)

- objcet: 이벤트를 발송할 객체

 

 var addTime: TimeInterval = 0.0

@objc func handleAppBackground(){
    if let startTime = startTime{
        let currentTime = Date()
        let elapsedTime = currentTime.timeIntervalSince(startTime)

        addTime = elapsedTime //Play 후 백그라운드로 이동할 경우 멈추고 Date 를 addTiem에 저장

        confirmTime(with: elapsedTime) //분 초 밀리초를 확인할 수 있는 함수 호출
        
        playButton.setTitle("Continue", for: .normal) //버튼 타이틀 Continue 변경
    }
}

- addTime: 시간차 자료형 객체를 생성

- handleAppBackground: Play버튼과 백그라운드 이동시 시간차를 확인,저장하고 버튼 타이틀을 변경하는 Selector

confirmTime 시간차 확인 함수
Play버튼과 백그라운드 이동시 시간차

 

3. 재시작과 종료시간의 차와 addTime을 합산해 누적시간을 저장하도록 함

 

실행