Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Playground駆動開発のすすめ / Playground driven developm...
Search
rockname
August 30, 2018
Programming
6.9k
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
大喜利で理解するLLM as a Judge / Understanding LLM-as-a-Judge through Ogiri
rockname
0
190
AIを活用したレシート読み取り機能の開発から得られた実践知 / AI Receipt Scan Practice
rockname
2
4.9k
Unlock the Potential of Swift Code Generation
rockname
0
620
生成AIを活用したレシート読み取り機能のアプリ開発の裏側 / AI Receipt Scan App Development
rockname
0
160
ゼロから理解するDependency Injection / Understanding Dependency Injection from the Ground Up
rockname
2
4.5k
サブスクリプション機能制御の設計における勘所
rockname
0
1.4k
Anatomy of Dynamic color
rockname
1
1.4k
キャッシュによる状態管理のアーキテクチャ / Cache-based state management architecture
rockname
10
21k
Optimistic Updatesで UXを向上させる / Improve UX with Optimistic Updates
rockname
2
1.6k
Other Decks in Programming
See All in Programming
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
460
巨大モノリシックアプリ モダン化大作戦
ktcryomm
1
1.2k
Turning Architecture into Unit Tests in the AI Era (NSSpain XIV)
steliosf
PRO
1
120
Agents on Rails - Rails at Scale 2026
irinanazarova
0
310
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
0
380
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
390
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
290
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
380
Intent as Code
shoppingjaws
6
1.1k
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
1
2.1k
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
0
370
カツオ、ご期待ください
suneo3476
0
140
Featured
See All Featured
What's in a price? How to price your products and services
michaelherold
247
13k
Marketing to machines
jonoalderson
1
5.8k
Bash Introduction
62gerente
615
220k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
550
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
Ethics towards AI in product and experience design
skipperchong
2
410
How GitHub (no longer) Works
holman
316
150k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
430
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
2
2.2k
Into the Great Unknown - MozCon
thekraken
41
2.7k
The World Runs on Bad Software
bkeepers
PRO
72
12k
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ۦಈ։ൃͰ രʹ։ൃ͠Α͏