관리 메뉴

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

[iOS - swift] 19. @propertyWrapper 이용하여 UserDefault쓰기 본문

iOS 실전 (swift)

[iOS - swift] 19. @propertyWrapper 이용하여 UserDefault쓰기

jake-kim 2020. 9. 19. 12:06

@propertyWrapper란?

  • @propertyWrapper: 프로퍼티를 한번 감쌓아서 get, set을 wrapping
  • 사용할땐 struct이름 어노테이션으로 접근

예시1) @propertyWrapper를 통해서 항상 10보다 작은 값을 유지하는 property 만드는 방법

TenOrLess라는 wrapper를 통해 10이하의 수만 리턴되도록 하는 변수 정의

@TenOrLess var value: Int

value = 12
print(value) // 10
  • 어노테이션으로 접근할 struct의 이름 위 @propertyWrapper 기입
@propertyWrapper
struct TenOrLess {
    // wrappedValue 정의
}
  • var wrappedValue라는 이름의 computed-property정의
    : 해당 어노테이션에 접근하는 경우 변수의 get, set을 이곳에서 정의된 방식으로 동작
@propertyWrapper
struct TenOrLess {

    private var number = 0

    var wrappedValue: Int {
        get {
            return number
        }
        set {
            number = min(newValue, 10)
        }
    }
}

예시2) @propertyWrapper를 통해서 UserDefault 만드는 방법

1) 프로퍼티 선언

(checkEventViewWillAppear라는 프로퍼티를 쓸건데, 이것을 UserDefaultWrapper라는 자료형에 정의할 예정)

- checkEventViewWillAppear라는 프로퍼티의 인수는 key, defaultValue를 갖음 / 로직은 @UserDefaultWrapper에 정의

*필수: 어노테이션 표기 / 인수 값 표시

struct UserDefaultsManager {
    @UserDefaultWrapper(key: "checkEvnetViewWillAppear", defaultValue: false)
    static var checkEventViewWillAppear
}

2) @UserDefaultWrapper에 로직 정의

*필수

- 어노테이션인, @propertyWrapper를 struct위에 기입

- "var wrappedValue"라는 이름으로 get/set정의

@propertyWrapper
fileprivate struct UserDefaultWrapper<E> {
    private let key: String
    private let defaultValue: E

    init(key: String, defaultValue: E) {
        self.key = key
        self.defaultValue = defaultValue
    }

    var wrappedValue: E {
        get {
            return UserDefaults.standard.object(forKey: key) as? E ?? defaultValue
        }
        set {
            UserDefaults.standard.set(newValue, forKey: key)
        }
    }
}

3) 사용

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        if UserDefaultsManager.checkEventViewWillAppear {
            print("이전에 발생")
        } else {
            print("처음")
            UserDefaultsManager.checkEventViewWillAppear = true
        }

    }

}
Comments