티스토리 뷰

혼자 만지작 거리고 있는 토이 프로젝트에서 해결 못하고 있던 문제가 있었지만 적극적으로 해결책을 찾지는 않았습니다.

그런데 오늘 Rx 공부하다가 그 해결책을 찾아서 공유해보려고 합니다.

일단 문제 상황부터 보고 가실까여.

아니지, 일단 커피 부터.

donaricano-btn

문제상황

사용자의 사진첩에 접근하려면 최초 접근 시도에서 저렇게 승인을 받아야 하죠.

그런데 왼쪽에서 승인을 해줘도 오른쪽 화면 처럼 바로 사진들이 뜨지 않습니다.

다시 사진첩을 눌러야 뜨더라구요. 이 문제를 (해결 방법 찾으니까 나오긴 하던데 왜 안찾아봤었지 키키) Rx로 해결해보려고 합니다.

원인

현재는 photos 변수에 사진들을 load 하지만 '승인' 과정을 거치고 reload 할 수 있는 방법이 없습니다.

그러면 reload가 가능하게 하면 되겠네요.

단-순-명-료

근데 이게 문제라는 건 알고 있었는데 어떻게 하는지 방법을 몰라뜸.... (해결책은 알지만 코드로 짜고 싶지 않다. 이런... 무책임한 개발자)

해결이 안대뉸 문제뉸 속이 아파요

해결

아래와 같은 플로우를 따르게 하면 되겠죠?

  1. 접근 권한이 있는가?
    1. [Yes] : load
    2. [No] : 승인 요청 → 결과 반환 → (load)
  2. 종료

저런 로직에 맞게 True/False 를 반환하는 Observable이 있다고 가정하고, reload 하는 코드를 먼저 짜봤습니다.
일단 승인하지 않았을 때의 경우는 우선 들어가있지 않아요!

// PhotosViewController

  override func viewDidLoad() {
    super.viewDidLoad()

    PHPhotoLibrary.authorized
      .skipWhile { !$0 } // true 값 나올 때까지 skip
      .take(1) // 처음 true값 받고 나면 종료
      .subscribe(
        onNext: { [weak self] _ in
          guard let self = self else { return }
          self.photos = PhotosViewController.loadPhotos()
          DispatchQueue.main.async {
            self.collectionView.reloadData()
          }
        })
      .disposed(by: disposeBag)
  }

 

이제 위에 코드에 나와 있는 authorized라는 static 변수를 만들면 되쥬 랄라.

PHPhotoLibrary를 extension 하게 파일을 만들고 코드 짜면 됨 랄라

import Foundation
import RxSwift
import Photos

extension PHPhotoLibrary {
  static var authorized: Observable<Bool> {
    
    return Observable.create { observer in
      
      DispatchQueue.main.async {
        switch authorizationStatus() {
        // CASE: 승인 이력 존재
        case .authorized:
          observer.onNext(true) // 더 할 것 없음. 바로 true emit
        // CASE: 승인 이력 없음
        case .notDetermined,
             .restricted,
             .denied,
             .limited:
          observer.onNext(false) // 일단 승인내역 없음을 알림.
          // 다시 권한 요청
          requestAuthorization { newStatus in
            observer.onNext(newStatus == .authorized)
            observer.onCompleted()
          }
        @unknown default:
          #warning("Deal with unkown case")
        }
      }
      return Disposables.create()
    }
    
  }
}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함