알림 설정 상태를 실시간으로 가져와 UI에 반영시키는 with RxSwift
개요
通知設定がOFFになっています
같은 화면을 구현하는 것, 자주 있는 것이 아닐까요? 이번은 그 구현을 RxSwift를 이용해 만들고 싶습니다 이미지
샘플 리포지토리
환경
소개
pod install 'RxSwift'
pod install 'RxCocoa'
화면 만들기
ViewController
DisableNotificationCoverView
DisableNotificationCoverView를 맨 위 계층에 배치하고 isHidden = true로 둡니다.
일단 사용할 수 있도록 View를 잘라냅니다.
통지 상태를 좋은 느낌으로 취득해 주는 클래스의 작성
RxNotificationCenter.swiftimport RxSwift
import RxCocoa
import UserNotifications
class RxNotificationCenter {
static let shared = RxNotificationCenter()
let authorizationStatus = PublishRelay<UNAuthorizationStatus>()
private init() {}
func updateAuthorizationStatus() {
// 通知設定状態を取得し、オブザーバに流す
UNUserNotificationCenter.current().getNotificationSettings { [weak self] settings in
self?.authorizationStatus.accept(settings.authorizationStatus)
}
}
}
pod install 'RxSwift'
pod install 'RxCocoa'
ViewController
DisableNotificationCoverView
DisableNotificationCoverView를 맨 위 계층에 배치하고 isHidden = true로 둡니다.
일단 사용할 수 있도록 View를 잘라냅니다.
통지 상태를 좋은 느낌으로 취득해 주는 클래스의 작성
RxNotificationCenter.swiftimport RxSwift
import RxCocoa
import UserNotifications
class RxNotificationCenter {
static let shared = RxNotificationCenter()
let authorizationStatus = PublishRelay<UNAuthorizationStatus>()
private init() {}
func updateAuthorizationStatus() {
// 通知設定状態を取得し、オブザーバに流す
UNUserNotificationCenter.current().getNotificationSettings { [weak self] settings in
self?.authorizationStatus.accept(settings.authorizationStatus)
}
}
}
import RxSwift
import RxCocoa
import UserNotifications
class RxNotificationCenter {
static let shared = RxNotificationCenter()
let authorizationStatus = PublishRelay<UNAuthorizationStatus>()
private init() {}
func updateAuthorizationStatus() {
// 通知設定状態を取得し、オブザーバに流す
UNUserNotificationCenter.current().getNotificationSettings { [weak self] settings in
self?.authorizationStatus.accept(settings.authorizationStatus)
}
}
}
알림 꺼져요 표지보기 만들기
DisableNotificationCoverView.swiftclass DisableNotificationCoverView: UIView {
@IBOutlet weak var openNotificationSettingButton: UIButton!
private let disposeBag = DisposeBag()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
override func awakeFromNib() {
openNotificationSettingButton.rx.tap
.subscribe(onNext: { [weak self] in
// ボタンがタップするたびにここの処理が呼ばれる
if let url = URL(string: UIApplicationOpenSettingsURLString), UIApplication.shared.canOpenURL(url) {
// 本体設定のこのアプリの設定画面を開く処理
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
})
.disposed(by: disposeBag)
}
private func commonInit() {
let bundle = Bundle(for: type(of: self))
let nib = UINib.init(nibName: "DisableNotificationCoverView", bundle: bundle)
let view = nib.instantiate(withOwner: self, options: nil).first as! UIView
self.addSubview(view)
}
}
class DisableNotificationCoverView: UIView {
@IBOutlet weak var openNotificationSettingButton: UIButton!
private let disposeBag = DisposeBag()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
override func awakeFromNib() {
openNotificationSettingButton.rx.tap
.subscribe(onNext: { [weak self] in
// ボタンがタップするたびにここの処理が呼ばれる
if let url = URL(string: UIApplicationOpenSettingsURLString), UIApplication.shared.canOpenURL(url) {
// 本体設定のこのアプリの設定画面を開く処理
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
})
.disposed(by: disposeBag)
}
private func commonInit() {
let bundle = Bundle(for: type(of: self))
let nib = UINib.init(nibName: "DisableNotificationCoverView", bundle: bundle)
let view = nib.instantiate(withOwner: self, options: nil).first as! UIView
self.addSubview(view)
}
}
알림 설정 화면
ViewController.swift
import UIKit
import UserNotifications
import RxSwift
class ViewController: UIViewController {
@IBOutlet weak var disableNotificationCoverView: UIView!
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "通知設定"
setupViewController()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// 通知設定状態を取得させてオブザーバに流すように命令
RxNotificationCenter.shared.updateAuthorizationStatus()
}
private func setupViewController() {
// RxNotificationCenterの通知設定状態のオブザーバを監視、変更があったらUIを変更する
RxNotificationCenter.shared.authorizationStatus
.map { status -> Bool in
switch status {
case .authorized:
return true
case .denied, .notDetermined:
return false
}
}
.bind(to: disableNotificationCoverView.rx.isHidden)
.disposed(by: disposeBag)
// 通知設定状態を取得させてオブザーバに流すように命令
RxNotificationCenter.shared.updateAuthorizationStatus()
}
}
마지막으로 알림 설정 화면에서 앱으로 돌아올 때 알림 설정 상태를 얻습니다.
AppDelegate.swift
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func applicationWillEnterForeground(_ application: UIApplication) {
RxNotificationCenter.shared.updateAuthorizationStatus()
}
}
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func applicationWillEnterForeground(_ application: UIApplication) {
RxNotificationCenter.shared.updateAuthorizationStatus()
}
}
ViewController
의 viewWillAppear
, viewDidAppear
가 불리는 것이 아닐까 생각하기 쉽지만, 실은 불리지 않습니다. AppDelegate
의 applicationWillEnterForeground
가 불리기 때문에, 거기에 통지 취득 처리를 사이에 둔다 요약
bind
함으로써 거기까지 UI의 변화를 의식하지 않고 통지 설정 취득 처리를 작성할 수 있었다 AppDelegate の
applicationWillEnterForeground` Notes
Reference
이 문제에 관하여(알림 설정 상태를 실시간으로 가져와 UI에 반영시키는 with RxSwift), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/k0uhashi/items/f18cb06b8a16dbcda11a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)