[iOS | Swift] UserDefaults 비동기 처리하는 2가지 방법

someng·2023년 1월 4일
0

iOS

목록 보기
27/33

CombineKVO(Key-Value Observing)를 각각 활용하여
key-value 쌍으로 디바이스에 데이터를 저장하는 기능을 제공하는 인터페이스인 UserDefaults의 특정 Key의 변화를 비동기적으로 반영하는 방법을 알아보자!

🍔 UserDefaults Extension

먼저, 사용하고자 하는 key의 이름(link)과 type(String)을 지정하여 Extension을 작성해준다.
(여기서 link는 UserDefaults의 key path로 쓰인다!)

extension UserDefaults {
    @objc var link: String {
        get {
            return string(forKey: "Link") ?? ""
        }
        set {
            set(newValue, forKey: "Link")
        }
    }
}

1. Combine 사용

🍔 publisher - subscriber 관계 만들기(feat. subscriptions)

앞서 만든 key path(\.link)를 publisher로 활용하여 구독 관계를 성립한다.
handleEvents 내부에 변화가 감지되었을 때 실행할 함수를 작성해주면 된다.

        UserDefaults.standard
            .publisher(for: \.link)
            .handleEvents(receiveOutput: { link in
                print("---> link = \(link)")
                self.updateErrorMessage(isError: false, message: "이메일 인증 완료!")
            })
            .sink { _ in }
            .store(in: &subscriptions)

🍔 UserDefaults 저장

let link = "[link 값]"
UserDefaults.standard.link = link

2. KVO(Key-Value Observing) 사용

🌱 KVO

  • 객체의 프로퍼티의 변경사항을 다른 객체에 알리기 위해 사용하는 코코아 프로그래밍 패턴
  • Model과 View와 같이 논리적으로 분리된 파트간의 변경사항을 전달하는데 유용하다.
  • NSObject를 상속한 클래스에서만 KVO를 사용할 수 있다.

🍔 observer 선언

변화된 UserDefaults value는
defaults를 changeHandler 클로저의 첫번째 파라미터로 선언한 경우,
defaults.[key path]로 접근할 수 있다.

var observer: NSKeyValueObservation?

init() {
	observer = UserDefaults.standard.observe(\.link, changeHandler: { defaults, value in
            let link = defaults.link
//            print("---> link: \(link)")
            if !link.isEmpty {
                self.updateErrorMessage(label: self.emailErrorLabel, isError: false, message: "이메일 인증 완료!")
                self.emailAuthCompleted = true
            } else {
                self.emailErrorLabel.text = ""
                self.emailAuthCompleted = false
            }
        })
}

🍔 observer 비활성화

class가 종료될 때, observer를 비활성화하여 메모리 누수를 방지해야 한다.

deinit {
	observer?.invalidate()
}

참고자료

profile
👩🏻‍💻 iOS Developer

0개의 댓글