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
210
AIを活用したレシート読み取り機能の開発から得られた実践知 / AI Receipt Scan Practice
rockname
2
4.9k
Unlock the Potential of Swift Code Generation
rockname
0
630
生成AIを活用したレシート読み取り機能のアプリ開発の裏側 / AI Receipt Scan App Development
rockname
0
160
ゼロから理解するDependency Injection / Understanding Dependency Injection from the Ground Up
rockname
2
4.6k
サブスクリプション機能制御の設計における勘所
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
Performance Optimization With LLMs
xleitix
0
200
最近”作らせてる” ローカルAIアプリの話
akit37
0
490
Seven New Principles of Software Engineering
yegor256
0
260
Simple Storage Service(S3) is not simple
iwatsukayura
0
320
月間100万人のサービス刷新で、 技術選定をHonoに振り切った話
yutobara
8
6.9k
ChromeでローカルLLM
ryu1013
0
160
No More NoSuchMethodError
exoego
1
110
Rでドレミ/Do-Re-Mi_with_R
florets1
0
130
AIで開発が速くなった先で、開発チームは何を目指すか
shihochan
1
1.8k
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
0
630
Web Framework Benchmark Battle 2026, Any%
a_matsuda
3
2.9k
AI-Powered Domain-Driven Design
ziobrando
0
290
Featured
See All Featured
Build your cross-platform service in a week with App Engine
jlugia
234
19k
The Cult of Friendly URLs
andyhume
79
7k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.8k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
How to build a perfect <img>
jonoalderson
1
6.2k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
580
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
12k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
Into the Great Unknown - MozCon
thekraken
41
2.8k
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ۦಈ։ൃͰ രʹ։ൃ͠Α͏