관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] RxSwift, RxCocoa로 ApplicationState 구독하여 사용하는 방법 본문

iOS 응용 (swift)

[iOS - swift] RxSwift, RxCocoa로 ApplicationState 구독하여 사용하는 방법

jake-kim 2022. 6. 20. 21:16

ApplicationState

  • ApplicationState는 크게 Not Running, Inactive, Active, Background, Suspended 상태가 존재
  • 앱에서 상태를 체크하여 처리하는 대표적인 케이스 - Active (foreground) 상태와 Background 상태를 구분하여 Active상태에서는 푸시메시지가 전송 안되게끔 막는 방법

https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle

RxSwift로 ApplicationState 처리 방법

  • ApplicationState는 아래처럼 코드로 접근이 가능
UIApplication.shared.applicationState
  • 코드로 확인할 수 있는 상태는 3가지만 존재
    // UIApplication.swift
    
    @available(iOS 4.0, *)
    public enum State : Int {

        case active = 0

        case inactive = 1

        case background = 2
    }
  • ApplicationState가 변경될때마다도 특정 처리를 하고싶은 경우 RxSwift로 구현
    • 사용할 RxSwift, RxCocoa 준비
  pod 'RxSwift'
  pod 'RxCocoa'
  • 모든 파일에서 접근이 가능해야하므로, 싱글톤으로 state 프로퍼티를 AppDelegate에 정의
// AppDelegate.swift

// 모든 코드에서 AppDelegate.shared.applicationState로 접근하기 위함
static var shared: Self { UIApplication.shared.delegate as! Self }

// BehaviorSubject를 사용
let applicationState = BehaviorSubject<UIApplication.State>(value: .inactive)
  • didFinishLaunchingWithOptions에서 NotificationCenter를 이용하여 각 이벤트를 addObserver로 등록
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
  
  [
    UIApplication.didBecomeActiveNotification,
    UIApplication.didEnterBackgroundNotification,
    UIApplication.willEnterForegroundNotification,
    UIApplication.didFinishLaunchingNotification,
    UIApplication.willResignActiveNotification,
    UIApplication.willTerminateNotification
  ].forEach {
    NotificationCenter.default.addObserver(forName: $0, object: nil, queue: nil) { _ in
      self.applicationState.onNext(UIApplication.shared.applicationState)
    }
  }
  
  return true
}
  • 사용하는 쪽에서는 AppDelegate.shared.applicationState로 접근해서 구독하여 사용
class ViewController: UIViewController {
  let disposeBag = DisposeBag()
  
  override func viewDidLoad() {
    super.viewDidLoad()

    AppDelegate.shared.applicationState
      .bind {
        switch $0 {
        case .active:
          print("active")
        case .background:
          print("background")
        case .inactive:
          print("inactive")
        default:
          print("default")
        }
      }
      .disposed(by: self.disposeBag)
  }
}

* 전체 코드: https://github.com/JK0369/ExApplicationState-Rx

* 참고

https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle

Comments