[RxSwift] Rx 를 사용하여시스템 권한 요청받기 (카메라, 앨범, 알림)

2024. 11. 6. 14:42·iOS/RxSwift&Combine

 

다음과 같은 시스템 권한 얼럿을 RxSwift를 이용하여 띄워보자!

 

PermissionManager 라는 이름을 가진 싱글톤 클래스를 만들어 권한 확인 및 요청 관련 메서드를 관리

public final class PermissionManager {

  public static let shared = PermissionManager()
  private init() { }
  private let disposeBag = DisposeBag()

  ...
}

권한 요청

RxSwift를 사용하여 구현하려고 하기 때문에 Observable 타입을 리턴하도록 구현

리턴되는 Bool타입의 데이터는 해당 권한을 허용했는지 여부이다.

알림 권한 요청

알림 권한 얼럿의 메세지는 시스템 내부에 정해져있다.

알림에 대한 얼럿과 소리 뱃지 등의 옵션만 설정하면 얼럿 메세지가 만들어진다!

func requestNotificationPermission() -> Observable<Bool> {
  return Observable<Bool>.create { observable in
    UNUserNotificationCenter.current()
      .requestAuthorization(options: [.alert, .sound, .badge]) { isAllow, _ in
        observable.onNext(isAllow)
        observable.onCompleted()
      }
    return Disposables.create()
  }
}

사용 예시

특정 버튼을 탭했을 때 권한 요청

button.rx.tap
  .flatMap {
      PermissionManager().checkPermission(for: .camera)
  }
  .subscribe(with: self) { owner, status in
      // 권한 상태에 따라 적절한 액션 구현
  }
  .disposed(by: disposBag())

카메라, 앨범 권한 요청

info.plist에서 권한 메세지 설정이 필요

privacy - NSCameraUsageDescription

privacy - Photo Library Description

import AVFoundation
import Photos

// ...

func requestCameraPermission() -> Observable<Bool> {
  Observable<Bool>.create { observable in
    AVCaptureDevice.requestAccess(for: .video) { granted in
      observable.onNext(granted)
      observable.onCompleted()
    }
    return Disposables.create()
  }
}

func requestPhotoPermission() -> Observable<Bool> {
  Observable<Bool>.create { observable in
    PHPhotoLibrary.requestAuthorization(for: .addOnly) { state in
      if state == .authorized {
        observable.onNext(true)
        observable.onCompleted()
      } else {
        observable.onNext(false)
        observable.onCompleted()
      }
    }
    return Disposables.create()
  }
}

모든 권한 한 번에 요청하기

앱을 처음 진입했다면 처음에 필요한 권한을 모두 요청받는게 필요할 수 있다.

필요한 권한을 하나씩 요청하는 메서드를 구현해보자

func requestAllPermission() -> Observable<Void> {
  return requestNotificationPermission()
    .map { _ in Void() }
    .flatMap { _ in
      self.requestCameraPermission()
        .map { _ in Void()}
    }
    .flatMap {
      self.requestPhotoPermission()
        .map { _ in Void() }
    }
}

알림-카메라-앨범 순서로 권한 요청 얼럿을 띄울 수 있다.

권한 상태 확인

.notDetermined: 권한 요청 받은 적 없음을 의미

해당 경우라면 위에서 구현한 권한 요청 메서드를 호출하여 허용 여부를 불러올 수 있다.

 

알림권한

// 알림 권한
var notificationPermission: Observable<Bool> {
  return Observable<Bool>.create { observable in
    UNUserNotificationCenter.current().getNotificationSettings { settings in
      switch settings.authorizationStatus {
      case .notDetermined:
        self.requestNotificationPermission()
          .subscribe(onNext: { isAllowed in
            observable.onNext(isAllowed)
            observable.onCompleted()
          })
          .disposed(by: self.disposeBag)
      case .authorized:
        observable.onNext(true)
        observable.onCompleted()
      default:
        observable.onNext(false)
        observable.onCompleted()
      }
    }
    return Disposables.create()
  }
}

 

카메라 권한

var cameraPermission: Observable<Bool> {
  return Observable<Bool>.create { observable in
    let status = AVCaptureDevice.authorizationStatus(for: .video)
    switch status {
    case .notDetermined:
      self.requestCameraPermission()
        .subscribe { isAllowed in
          observable.onNext(isAllowed)
          observable.onCompleted()
        }
        .disposed(by: self.disposeBag)
    case .authorized:
      observable.onNext(true)
      observable.onCompleted()
    default:
      observable.onNext(false)
      observable.onCompleted()
    }

    return Disposables.create()
  }
}

 

앨범 권한

// 앨범 권한  
var photoPermission: Observable<Bool> {
  return Observable<Bool>.create { observable in
    let status = PHPhotoLibrary.authorizationStatus(for: .addOnly)
    switch status {
    case .notDetermined:
      self.requestPhotoPermission()
        .subscribe { isAllowed in
          observable.onNext(isAllowed)
          observable.onCompleted()
        }
        .disposed(by: self.disposeBag)
    case .authorized:
      observable.onNext(true)
      observable.onCompleted()
    default:
      observable.onNext(false)
      observable.onCompleted()
    }

    return Disposables.create()
  }
}

권한 상태 확인을 보다 깔끔하게 사용하기

각각의 다른 프로퍼티를 호출하여 사용하는 것 보다 하나의 메서드를 사용하는게 더 간단하고 가독성이 좋을 것 같다.

 

권한 타입 정의

enum PermissionType {
  case notification, camera, photo
}

 

권한 확인 메서드 구현

파라미터로 확인하고자 하는 권한 타입을 넣어 확인할 수 있다!

func checkPermission(for type: PermissionType) -> Observable<Bool> {
  switch type {
  case .notification:
    return notificationPermission
  case .camera:
    return cameraPermission
  case .photo:
    return photoPermission
  }
}

 

사용 예시

button.rx.tap
    .flatMap {
        PermissionManager().checkPermission(for: .camera)
    }
    .subscribe(with: self) { owner, status in
        ...
    }
    .disposed(by: disposBag)
저작자표시

'iOS > RxSwift&Combine' 카테고리의 다른 글

[iOS/ReactorKit] ReactorKit 알아보기  (0) 2024.02.28
RxSwift 왜 사용??  (0) 2023.12.28
[iOS/RxSwift] CombineLatest vs Observable.zip  (0) 2023.11.19
RxSwift 정리하기  (0) 2023.11.08
'iOS/RxSwift&Combine' 카테고리의 다른 글
  • [iOS/ReactorKit] ReactorKit 알아보기
  • RxSwift 왜 사용??
  • [iOS/RxSwift] CombineLatest vs Observable.zip
  • RxSwift 정리하기
김졀니
김졀니
🍎 iOS 개발
  • 김졀니
    졀니의 개발 공부✨
    김졀니
  • 전체
    오늘
    어제
    • 분류 전체보기
      • iOS
        • Swift
        • UIKit&SwiftUI
        • RxSwift&Combine
        • WWDC
      • Study
        • 🚨 TroubleShooting
        • 🌱 SeSAC
  • 블로그 메뉴

    • 홈
    • Github
  • 인기 글

  • 최근 글

  • 태그

    RxSwift
    Swift
    concurrency
    위치 권한
    Realm
    mapkit
    displayPriority
    OperationQueue
    mainactor
    traits
    동시성프로그래밍
    actor
    의존성 주입
    kingfisher header
    이미지 캐싱
    Sendable
    swiftdata
    ReactorKit
    clipstobounds
    FileManager
    Drawing Cycle
    observable
    @PropertyWrapper
    layoutIfNeeded
    pointfree
    인앱리뷰
    CLLocation
    swift concurrency
    ios
    wwdc23
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
김졀니
[RxSwift] Rx 를 사용하여시스템 권한 요청받기 (카메라, 앨범, 알림)
상단으로

티스토리툴바