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
Playground駆動開発のすすめ / Playground driven developm...
Search
rockname
August 30, 2018
Programming
6.8k
10
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Playground駆動開発のすすめ / Playground driven development suggestion
rockname
August 30, 2018
More Decks by rockname
See All by rockname
AIを活用したレシート読み取り機能の開発から得られた実践知 / AI Receipt Scan Practice
rockname
2
4.8k
Unlock the Potential of Swift Code Generation
rockname
0
600
生成AIを活用したレシート読み取り機能のアプリ開発の裏側 / AI Receipt Scan App Development
rockname
0
150
ゼロから理解するDependency Injection / Understanding Dependency Injection from the Ground Up
rockname
2
4.5k
サブスクリプション機能制御の設計における勘所
rockname
0
1.3k
Anatomy of Dynamic color
rockname
1
1.3k
キャッシュによる状態管理のアーキテクチャ / Cache-based state management architecture
rockname
10
21k
Optimistic Updatesで UXを向上させる / Improve UX with Optimistic Updates
rockname
2
1.6k
モバイルアプリのリストUIにおける 理想的なState表示について / The ideal state display in a mobile app list UI
rockname
6
2.3k
Other Decks in Programming
See All in Programming
引き算の組織 ― アウトカムとAIに全振りするために辞めたこと ― / Organization by Subtraction
hirokiyamamoto14
PRO
0
310
ドリフトを絶対に許さない(?)CDK運用 / CDK Ops with Zero Tolerance for Drifts (?)
akihisaikeda
1
240
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
320
自動化したのに回らない テスト運用の壁―AI時代の品質責任と生産性
mfunaki
0
530
go-spidermonkeyでAIエージェントのCode Modeを実装する
syumai
3
1.3k
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
5
550
VibeCodingからAgenticWorkflowへ
starfish719
0
940
プロポーザルを書いてもらう
pvcresin
0
590
高専、大学編入、そして未踏へ〜プロダクト開発とキャリアの歩み - Technical College, University Transfer, and On to “Mitou” / My Journey in Product Development and Career
pkmiya
0
100
私のClaude Code活用法 (個人開発編) - PHPerKaigi mini #4(2026/08/24)
panda_program
1
190
Press start. Python's next generation.
willingc
PRO
3
260
Hono + Inertia + React で LP を構築した話
oukayuka
2
180
Featured
See All Featured
KATA
mclloyd
PRO
35
15k
Design in an AI World
tapps
1
290
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
390
Chasing Engaging Ingredients in Design
codingconduct
0
290
エンジニアに許された特別な時間の終わり
watany
108
250k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
480
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
220
ラッコキーワード サービス紹介資料
rakko
1
4.6M
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.5k
GraphQLとの向き合い方2022年版
quramy
50
15k
Producing Creativity
orderedlist
PRO
348
40k
Transcript
iOSDC Japan 2018 2018/08/30 גࣜձࣾϛΫγΟ/ΈͯͶࣄۀ෦ ؠ໊༐ً @rockname Playgroundۦಈ։ൃ ͷ͢͢Ί
@rockname גࣜձࣾϛΫγΟ / ΈͯͶࣄۀ෦ ΞϓϦ։ൃG 18৽ଔ iOS(Swift, objc), Android(Kotlin, Java),
Rails(ruby)…
UIͷ࣮Λ͏ iOSΞϓϦ։ൃϑϩʔ
1 ϩδοΫΛΉ 2 StoryboardͰϨΠΞτ 3 ಈ࡞֬ೝ w ͦΕͧΕͷΞʔΩςΫνϟʹԠͯ͡ϩδοΫ͔ΒΜͰ͍͘ w $MFBO"SDIJUFDUVSFͳΒ%PNBJO͔Β
w ςετॻ͘ w ΞχϝʔγϣϯͳͲಈతͳཁૉҎ֎ఆٛͯ͠͠·͏ w ࣮ػ4JNVMBUPSͰҙਤͨ͠ڍಈΛ͢Δ͔֬ೝ
1 ϩδοΫΛΉ 2 StoryboardͰϨΠΞτ 3 ಈ࡞֬ೝ w ͦΕͧΕͷΞʔΩςΫνϟʹԠͯ͡ϩδοΫ͔ΒΜͰ͍͘ w $MFBO"SDIJUFDUVSFͳΒ%PNBJO͔Β
w ςετॻ͘ w ΞχϝʔγϣϯͳͲಈతͳཁૉҎ֎ఆٛͯ͠͠·͏ w ࣮ػ4JNVMBUPSͰҙਤͨ͠ڍಈΛ͢Δ͔֬ೝ 4 σβΠϯௐ
1 ϩδοΫΛΉ 2 StoryboardͰϨΠΞτ 3 ಈ࡞֬ೝ w ͦΕͧΕͷΞʔΩςΫνϟʹԠͯ͡ϩδοΫ͔ΒΜͰ͍͘ w $MFBO"SDIJUFDUVSFͳΒ%PNBJO͔Β
w ςετॻ͘ w ΞχϝʔγϣϯͳͲಈతͳཁૉҎ֎ఆٛͯ͠͠·͏ w ࣮ػ4JNVMBUPSͰҙਤͨ͠ڍಈΛ͢Δ͔֬ೝ 4 σβΠϯௐ ͕݁͜͜ߏਏ͍…
• ෳղ૾ͰͷϨΠΞτ • ݅ʹΑͬͯมΘΔදࣔ༰ • ϩʔΧϥΠζͷจݴ…
Xcode Simulator /Device #VJME͕௨ΔͷΛͬͯ ϨΠΞτΛ֬ೝ ϨΠΞτΛௐͯ͠ ࠶Ϗϧυ • ෳղ૾ͰͷϨΠΞτ •
݅ʹΑͬͯมΘΔදࣔ༰ • ϩʔΧϥΠζͷจݴ…
UIͷௐΛͬͱૣ͍αΠΫϧͰճ͍ͨ͠…
– Playground driven development “Playgroundۦಈ։ൃ”
Playgroundۦಈ։ൃͱ • ViewͷΈΛ࣌ؒͰϏϧυͯ͠ରͷγʔϯΛ PlaygroundͰදࣔ͢Δ͜ͱͰσβΠϯௐͷϑ ϩʔΛૣ͘͢Δ։ൃख๏ • Kickstarter͕ఏএ (https://github.com/kickstarter/ios-oss)
Kickstarter͜Μͳײ͡
Kickstarter͜Μͳײ͡
Kickstarter͜Μͳײ͡
ಋೖखॱ
1. Cocoa Touch frameworkΛ λʔήοτʹՃ
1. Cocoa Touch frameworkΛ λʔήοτʹՃ
2. ࡞ͨ͠Frameworkʹ ViewΛՃ͍ͯ͘͠
3. (CarthageΛ༻ͨ͠߹ͷΈ) ViewͷදࣔʹඞཁͳϥΠϒϥϦΛՃ
4. PlaygroundΛ ϓϩδΣΫτʹՃ
5. PlaygroundͰViewΛදࣔ let vc = ViewController() PlaygroundPage.current.liveView = vc
5. PlaygroundͰViewΛදࣔ
5. PlaygroundͰViewΛදࣔ
͞ΒʹPlaygroundʹ৽ػೳ͕…
What’s new in Playground - WWDC 2018 Xcode10͔ΒPlaygroundͷஞ࣮࣍ߦ͕Մೳʹ…!! (https://developer.apple.com/videos/play/ wwdc2018/402/)
Alex Brown, Core OS Engineer • Running Step by Step NEW
What’s new in Playground - WWDC 2018 ҰʑίϝϯτΞτ͢Δඞཁ͕ͳ͘ ϑϩʔΛڞ௨Խ͘͢͠ͳͬͨ Alex
Brown, Core OS Engineer • Running Step by Step NEW
۩ମతʹͲΜͳखॱͰ σβΠϯௐ͢Δͷ
DEMO IUUQTHJUIVCDPNSPDLOBNF1MBZHSPVOE%SJWFO%FWFMPQNFOU
DEMOͷྲྀΕ • TwitterͷΑ͏ͳΞϓϦΛ࡞ͬͨʂ • σβΠϯ֬ೝ͢Δͧʂ ߘ͕ ͳ͍/͋Δ ͱ͖ͷදࣔਖ਼͍͠ʁ ͪΌΜͱ ϩʔΧϥΠζ
͞ΕͯΔʁ খ͍͞, େ͖͍Ͱ ϨΠΞτ ่Εͯͳ͍ʁ • मਖ਼ͯ͠ View͚ͩ ϏϧυͰ࠶֬ೝʂ
࣮આ໌
func display(device: Device, orientation: Orientation, language: Language) { let vc
= R.storyboard.twitter.instantiateInitialViewController()! let (parent, _) = playgroundControllers(device: device, orientation: .portrait, child: vc) AppEnvironment.language = language PlaygroundPage.current.liveView = parent vc.load(statuses) } 1SPKFDUQMBZHSPVOE5XJUUFSYDQMBZHSPVOEQBHF
func display(device: Device, orientation: Orientation, language: Language) { let vc
= R.storyboard.twitter.instantiateInitialViewController()! let (parent, _) = playgroundControllers(device: device, orientation: .portrait, child: vc) AppEnvironment.language = language PlaygroundPage.current.liveView = parent vc.load(statuses) } 1SPKFDUQMBZHSPVOE5XJUUFSYDQMBZHSPVOEQBHF
1SPKFDUQMBZHSPVOE5XJUUFSYDQMBZHSPVOEQBHF func display(device: Device, orientation: Orientation, language: Language) { let
vc = R.storyboard.twitter.instantiateInitialViewController()! let (parent, _) = playgroundControllers(device: device, orientation: .portrait, child: vc) AppEnvironment.language = language PlaygroundPage.current.liveView = parent vc.load(statuses) } simulatorͷsizeͳͲΛࢦఆ
public func playgroundControllers(device: Device = .phone4_7inch, orientation: Orientation, child: UIViewController,
additionalTraits: UITraitCollection) -> (parent: UIViewController, child: UIViewController) { let parent = UIViewController() parent.addChild(child) parent.view.addSubview(child.view) child.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] let traits: UITraitCollection switch (device, orientation) { case (.phone3_5inch, .portrait): parent.view.frame = .init(x: 0, y: 0, width: 320, height: 480) traits = .init(traitsFrom: [ .init(horizontalSizeClass: .compact), .init(verticalSizeClass: .regular), .init(userInterfaceIdiom: .phone) ]) ɾ ɾ ɾ simulatorͷsizeͳͲΛࢦఆ 1SPKFDUQMBZHSPVOE4PVSDFTEFWJDFTXJGU
public func playgroundControllers(device: Device = .phone4_7inch, orientation: Orientation, child: UIViewController,
additionalTraits: UITraitCollection) -> (parent: UIViewController, child: UIViewController) { let parent = UIViewController() parent.addChild(child) parent.view.addSubview(child.view) child.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] let traits: UITraitCollection switch (device, orientation) { case (.phone3_5inch, .portrait): parent.view.frame = .init(x: 0, y: 0, width: 320, height: 480) traits = .init(traitsFrom: [ .init(horizontalSizeClass: .compact), .init(verticalSizeClass: .regular), .init(userInterfaceIdiom: .phone) ]) 1SPKFDUQMBZHSPVOE4PVSDFTEFWJDFTXJGU ɾ ɾ ɾ simulatorͷsizeͳͲΛࢦఆ Device, OrientationʹԠͯ͡ sizeΛࢦఆ͢Δ
ɾ ɾ ɾ child.view.frame = parent.view.frame parent.preferredContentSize = parent.view.frame.size parent.view.backgroundColor
= .white child.view.backgroundColor = .white let allTraits = UITraitCollection.init(traitsFrom: [traits, additionalTraits]) parent.setOverrideTraitCollection(allTraits, forChild: child) return (parent, child) } simulatorͷsizeͳͲΛࢦఆ 1SPKFDUQMBZHSPVOE4PVSDFTEFWJDFTXJGU
ɾ ɾ ɾ child.view.frame = parent.view.frame parent.preferredContentSize = parent.view.frame.size parent.view.backgroundColor
= .white child.view.backgroundColor = .white let allTraits = UITraitCollection.init(traitsFrom: [traits, additionalTraits]) parent.setOverrideTraitCollection(allTraits, forChild: child) return (parent, child) } simulatorͷsizeͳͲΛࢦఆ 1SPKFDUQMBZHSPVOE4PVSDFTEFWJDFTXJGU preferredContentSizeΛࢦఆ͢Δ͜ͱͰ Playground্Ͱදࣔ͢ΔViewͷେ͖͞ΛมߋՄೳ
func display(device: Device, orientation: Orientation, language: Language) { let vc
= R.storyboard.twitter.instantiateInitialViewController()! let (parent, _) = playgroundControllers(device: device, orientation: .portrait, child: vc) AppEnvironment.language = language PlaygroundPage.current.liveView = parent vc.load(statuses) } 1SPKFDUQMBZHSPVOE5XJUUFSYDQMBZHSPVOEQBHF
func display(device: Device, orientation: Orientation, language: Language) { let vc
= R.storyboard.twitter.instantiateInitialViewController()! let (parent, _) = playgroundControllers(device: device, orientation: .portrait, child: vc) AppEnvironment.language = language PlaygroundPage.current.liveView = parent vc.load(statuses) } 1SPKFDUQMBZHSPVOE5XJUUFSYDQMBZHSPVOEQBHF LanguageΛࢦఆ
public struct AppEnvironment { public static var language: Language =
.ja public static var currentUser: String? = nil public var isLoggedIn: Bool { return AppEnvironment.currentUser != nil } } GlobalʹΞϓϦͷڥΛ͍࣋ͨͤͯΔ LanguageΛࢦఆ %PNBJO"QQ&OWJSPONFOUTXJGU
extension StringResourceType { func localized(language: Language = AppEnvironment.language) -> String
{ return NSLocalizedString(key, bundle: Bundle(path: stringsBundle.path(forResource: language.rawValue, ofType: "lproj") ?? "") ?? stringsBundle, comment: "") } } private class Pin {} public let stringsBundle = Bundle(for: Pin.self) LanguageΛࢦఆ 1SFTFOUBUJPOʜ4USJOH3FTPVSDF5ZQF MPDBMJ[FETXJGU
extension StringResourceType { func localized(language: Language = AppEnvironment.language) -> String
{ return NSLocalizedString(key, bundle: Bundle(path: stringsBundle.path(forResource: language.rawValue, ofType: "lproj") ?? "") ?? stringsBundle, comment: "") } } private class Pin {} public let stringsBundle = Bundle(for: Pin.self) 1SFTFOUBUJPOʜ4USJOH3FTPVSDF5ZQF MPDBMJ[FETXJGU NSLocalizedStringͷҾʹ LanguageʹԠͨ͡BundleΛ͢Α͏ʹ͢Δ LanguageΛࢦఆ
func display(device: Device, orientation: Orientation, language: Language) { let vc
= R.storyboard.twitter.instantiateInitialViewController()! let (parent, _) = playgroundControllers(device: device, orientation: .portrait, child: vc) AppEnvironment.language = language PlaygroundPage.current.liveView = parent vc.load(statuses) } 1SPKFDUQMBZHSPVOE5XJUUFSYDQMBZHSPVOEQBHF
func display(device: Device, orientation: Orientation, language: Language) { let vc
= R.storyboard.twitter.instantiateInitialViewController()! let (parent, _) = playgroundControllers(device: device, orientation: .portrait, child: vc) AppEnvironment.language = language PlaygroundPage.current.liveView = parent vc.load(statuses) } 1SPKFDUQMBZHSPVOE5XJUUFSYDQMBZHSPVOEQBHF Playground্ͰViewΛදࣔͯ͠ Cellʹදࣔ͢ΔߘΛಡΈࠐΉ
ViewΛදࣔ
ViewΛදࣔ
Α͠ɺΈͯͶͰಋೖʂ
Α͠ɺΈͯͶͰಋೖʂ
ಋೖ·ͰͷಓͷΓ Viewʹදࣔ͢ΔͷΛϞοΫͰ͖ΔΑ͏ʹઃܭ ଟݴޠରԠΛ͍ͯ͠ΔͷͰɺNSLocalizedStringͷ ॳظԽ࣌ʹBundleͷpathΛ͢ Embedded Frameworkͷಋೖ PlaygroundͷPageಋೖϑϩʔڞ௨Խɾڞ༗
৽نϓϩδΣΫτͳΒ ׂͱαΫοͱಋೖͰ͖ͦ͏
Playgroundۦಈ։ൃͰ രʹ։ൃ͠Α͏