Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Property Wrappersがもたらす新しいSwiftプログラミング / New Swi...
Search
darquro
September 06, 2019
Technology
3
1.6k
Property Wrappersがもたらす新しいSwiftプログラミング / New Swift programming with Property Wrappers
iOSDC Japan 2019 day1(2019/8/6) Track A LT 16:15
darquro
September 06, 2019
Tweet
Share
More Decks by darquro
See All by darquro
技術的負債を解消してくための組織づくり
darquro
1
920
Jailbreakと向き合おう
darquro
0
2.1k
ラクマでのSwiftUI導入方針とTips / Rakuma SwiftUI Introduction Policy and Tips
darquro
2
4.9k
Half modal comparision in iOS15
darquro
2
1.8k
2 Years Challenge as Engineering Manager in Rakuma
darquro
0
100
iOS View Class Design Basic
darquro
3
730
Swift 5 Exclusivity Enforcement
darquro
4
760
SDK連携を用いたAdMob活用法
darquro
1
980
ContributingSwift
darquro
0
78
Other Decks in Technology
See All in Technology
Amazon Q Developerで.NET Frameworkプロジェクトをモダナイズしてみた
kenichirokimura
1
190
今から、 今だからこそ始める Terraform で Azure 管理 / Managing Azure with Terraform: The Perfect Time to Start
nnstt1
0
190
月間60万ユーザーを抱える 個人開発サービス「Walica」の 技術スタック変遷
miyachin
1
120
エンジニアリングマネージャー視点での、自律的なスケーリングを実現するFASTという選択肢 / RSGT2025
yoshikiiida
4
3.6k
RubyでKubernetesプログラミング
sat
PRO
4
150
ABWGのRe:Cap!
hm5ug
1
120
あなたの知らないクラフトビールの世界
miura55
0
120
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
6
54k
re:Invent2024 KeynoteのAmazon Q Developer考察
yusukeshimizu
1
130
デジタルアイデンティティ技術 認可・ID連携・認証 応用 / 20250114-OIDF-J-EduWG-TechSWG
oidfj
2
540
.NET AspireでAzure Functionsやクラウドリソースを統合する
tsubakimoto_s
0
180
ドメイン駆動設計の実践により事業の成長スピードと保守性を両立するショッピングクーポン
lycorptech_jp
PRO
7
760
Featured
See All Featured
Site-Speed That Sticks
csswizardry
2
260
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.6k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.5k
Designing for Performance
lara
604
68k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.4k
Unsuck your backbone
ammeep
669
57k
How GitHub (no longer) Works
holman
312
140k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
173
51k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
GitHub's CSS Performance
jonrohan
1030
460k
Transcript
Re:valua t ion https://fril.jp/ L ead & Delight User F
irst Ownership Fail Smart 1SPQFSUZ8SBQQFST͕ͨΒ͢ ৽͍͠4XJGUϓϩάϥϛϯά !J04%$+BQBO
J04&OHJOFFS 3BLVUFO JOD ϥΫϚ "CPVU.F EBSRVSP :VLJ,VSPEB
!EBSRVSP !EBSRVSP
1SPQFSUZ8SBQQFST
1SPQFSUZ8SBQQFST w "WBJMBCMF4XJGU w ϓϩύςΟΞΫηεʹԠͯ͡ڍಈΛXSBQ w ϓϩύςΟΠϯελϯε͝ͱʹσʔλΛอ࣋Մೳ w
ॳظԆ࣮ߦ
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) } } }
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 { … } }
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
6TFS%FGBVMUT&YBNQMF
4UBUF&YBNQMF struct LandmarkList: View { @State var showFavoriteOnly
= true var body: some View { NavigationView { List { Toggle(isOn: $showFavoriteOnly) { Text("Favorite Only") } … } … }
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 } }
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 } }
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}$" } } }
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" }) } }
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 = "
[email protected]
" foo.phoneNumber = "09012341234" foo.isValidAll // -> "true"
நԽ
நԽ w ܧঝ w 1SPUPDPM w &YUFOTJPOT w
1SPQFSUZ8SBQQFST
நԽ 1SPQFSZ8SBQQFST ࣮ίετ ந 1SPUPDPM &YUFOTJPOT ܧঝ
ల ΞʔΩςΫνϟ ϑϨʔϜϫʔΫ σβΠϯύλʔϯ 044ϥΠϒϥϦ
·ͱΊ
·ͱΊ 1SPQFSUZ8SBQQFST w ΑΓநతʹػೳΛϓϩύςΟͷΈʹఏڙͰ͖Δ w ϘΠϥʔϓϨʔτͷলུʹͳΔ w !YYY@YYYYYYͱ͍ͬͨಠࣗͷγϯλοΫε
4XJGU&WPMVUJPO1SPQPTBM IUUQTHJUIVCDPNBQQMFTXJGUFWPMVUJPOCMPCNBTUFSQSPQPTBMTQSPQFSUZXSBQQFSTNE
5IBOLZPV