Property Wrappersがもたらす新しいSwiftプログラミング / New Swift programming with Property Wrappers

B79e8f240b4b730fb692ab93ad42a89b?s=47 darquro
September 06, 2019

Property Wrappersがもたらす新しいSwiftプログラミング / New Swift programming with Property Wrappers

iOSDC Japan 2019 day1(2019/8/6) Track A LT 16:15

B79e8f240b4b730fb692ab93ad42a89b?s=128

darquro

September 06, 2019
Tweet

Transcript

  1. 1.

    Re:valua t ion https://fril.jp/ L ead & Delight User F

    irst Ownership Fail Smart 1SPQFSUZ8SBQQFST͕΋ͨΒ͢ ৽͍͠4XJGUϓϩάϥϛϯά !J04%$+BQBO
  2. 5.

      6TFS%FGBVMUT&YBNQMF @propertyWrapper struct UserDefault<T> { var wrappedValue: T

    { get { return UserDefaults.standard .object(forKey: key) as? T ?? defaultValue } set { UserDefaults.standard.set(newValue, forKey: key) } } }
  3. 6.

      6TFS%FGBVMUT&YBNQMF @propertyWrapper struct UserDefault<T> { let key: String

    let defaultValue: T init(_ key: String, defaultValue: T) { self.key = key self.defaultValue = defaultValue UserDefaults.standard .register(defaults: [key: defaultValue]) } var wrappedValue: T { … } }
  4. 7.

      6TFS%FGBVMUT&YBNQMF struct Foo { @UserDefault("IS_LOGGED_IN", defaultValue: false) static

    var isLoggedIn: Bool } Foo.isLoggedIn = true // UserDefaults.standard.object(forKey: "IS_LOGGED_IN") -> 1 Foo.isLoggedIn = false // UserDefaults.standard.object(forKey: "IS_LOGGED_IN") -> 0
  5. 9.

      4UBUF&YBNQMF struct LandmarkList: View { @State var showFavoriteOnly

    = true var body: some View { NavigationView { List { Toggle(isOn: $showFavoriteOnly) { Text("Favorite Only") } … } … }
  6. 10.

      4UBUF&YBNQMF @propertyWrapper public struct State<Value> : DynamicProperty, BindingConvertible

    { …… /// The current state value. public var wrappedValue: Value { get nonmutating set } …… /// Produces the binding referencing this state value public var projectedValue: Binding<Value> { get } }
  7. 11.

      7BMJEBUJPO&YBNQMF @propertyWrapper struct Validate<Value> { var wrappedValue: Value?

    var isValid: Bool { guard let value = wrappedValue else { return false } return validateion(value) } private let validateion: (Value) -> Bool private let messageClosure: (Value) -> String init(_ validation: @escaping (Value) -> Bool, message messageClosure: @escaping (Value) -> String) { self.validateion = validation self.messageClosure = messageClosure } }
  8. 12.

      7BMJEBUJPO&YBNQMF enum StringValidationType { case email case phoneNumber

    var regex: String { switch self { case .email: return #"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\.[A-Za- z]{2,64}"# case .phoneNumber: return "^[0-9]{6,14}$" } } }
  9. 13.

      7BMJEBUJPO&YBNQMF extension Validate where Value == String {

    init(_ type: StringValidationType) { self.init({ $0.range(of: type.regex, options: .regularExpression) != nil }, message: { "Error:\($0) does not match email" }) } }
  10. 14.

      7BMJEBUJPO&YBNQMF struct Foo { @Validate(.email) var email: String?

    @Validate(.phoneNumber) var phoneNumber: String? var isValidAll: Bool { _email.isValid && _phoneNumber.isValid } } var foo = Foo() foo.email = "abc@example.com" foo.phoneNumber = "09012341234" foo.isValidAll // -> "true"