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
今なら言える、 クラスメソッドとSwiftの歴史 〜開発現場の光と闇〜
Search
Takaaki Tanaka
April 28, 2017
Technology
1.7k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
今なら言える、 クラスメソッドとSwiftの歴史 〜開発現場の光と闇〜
大阪オフィス開設1周年勉強会の資料です
http://dev.classmethod.jp/news/mobileteam-inosaka-vol-3/
Takaaki Tanaka
April 28, 2017
More Decks by Takaaki Tanaka
See All by Takaaki Tanaka
[デモです] NotebookLM で作ったスライドの例
kongmingstrap
0
610
Zenn のウラガワ ~エンジニアのアウトプットを支える環境で Google Cloud が採用されているワケ~ #burikaigi #burikaigi_h
kongmingstrap
22
8.5k
AWS re:Invent 2024 ふりかえり
kongmingstrap
0
480
製造の課題に立ち向かう Manufacturing Data Engine と Manufacturing Connect の ご紹介
kongmingstrap
0
1.4k
Tellus の衛星データを見てみよう #mf_fukuoka
kongmingstrap
0
970
JAWS-UG 福岡 #16 re:Invent 現地に行った人のお話 #jawsugfuk #jawsug
kongmingstrap
0
770
AppMod の開発のイマを知るために現地に潜入した私が見たものは・・・? #GoogleCloudNext
kongmingstrap
0
880
Kong Gateway から読みとく、 API統合・API連携サービスの最新情報 #devio2023
kongmingstrap
0
2.3k
Cloud Run に憧れて Google Cloud を推進している話 / CX事業本部で使われている技術
kongmingstrap
0
380
Other Decks in Technology
See All in Technology
「重なり」は迎える側がつくる ― 人もAIエージェントも歓迎するプロダクトエンジニアリング ―
go0517go
PRO
0
270
2026/09/10 Spring_Bootから_Jakarta_EE_MicroProfileへの移行
megascus
0
280
Amazon Quick on DesktopがIAM Identity Centerで動かない理由
yukiogawa
0
140
振り返りこそエンジニアの本領
negima
0
350
Where Is JetBrains AI Heading- — Central CLI, Air Alpha, and the Agentic Development Stack
x5gtrn
PRO
0
150
AI時代に、プロダクトの数だけ積み上がる所有コストをどうエンジニアリングするか / Engineering the Cost of Ownership
kzkmaeda
1
1.1k
SQL文一行も書けない人事がCortexもろもろを使って人事業務を楽にしてみる
ponponmikankan
1
200
AI時代だからこそ、スケールしないことをやろう
yutashigemura
1
120
Tab5をRubyで動くパソコンにする
kishima
2
280
AI時代におけるプロダクト横断勉強会の設計
zozotech
PRO
0
170
AIで仕事のやり方を変える
matsu7874
3
1k
作品が生態系になった ─ Mini Tokyo 3D から世界へ
nagix
0
150
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.3k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
Facilitating Awesome Meetings
lara
57
7.1k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
74
42k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Product Roadmaps are Hard
iamctodd
55
13k
We Have a Design System, Now What?
morganepeng
55
8.3k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Are puppies a ranking factor?
jonoalderson
2
3.9k
Side Projects
sachag
455
43k
Git: the NoSQL Database
bkeepers
PRO
432
67k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
4
610
Transcript
2017/04/28 ࠓͳΒݴ͑Δɺ ΫϥεϝιουͱSwiftͷྺ࢙ ʙ։ൃݱͷޫͱҋʙ େࡕΦϑΟε։ઃ1पษڧձ
About Me
• ాத ໌ (Takaaki Tanaka) • Ϋϥεϝιουגࣜձࣾ • ϞόΠϧόοΫΤϯυ •
@kongmingtrap • Swift / Objective-C / Scala / JavaScript … • GyazSquare / GitHub
None
None
ؓٳ
Introduction
Introduction •Objective-CͰͷiOSͷ։ൃྺ͕3 •Swiftɺ΄΅ະܦݧ •Ұ͔ΒSwiftͰ࡞ΒΕͨϓϩδΣΫτʹܞ ΘΓ͔ͨͬͨ •Ver 1ͷࠒͷSwift҆ఆ͍ͯ͠ͳ͔ͬͨͨ ΊɺσϦόϦʔ༏ઌͰObjective-C͕࠾༻ ͞Ε͍ͯͨ
Introduction •Objective-CͰͷiOSͷ։ൃྺ͕3 •Swiftɺ΄΅ະܦݧ •Ұ͔ΒSwiftͰ࡞ΒΕͨϓϩδΣΫτʹܞ ΘΓ͔ͨͬͨ •Ver 1ͷࠒͷSwift҆ఆ͍ͯ͠ͳ͔ͬͨͨ ΊɺσϦόϦʔ༏ઌͰObjective-C͕࠾༻ ͞Ε͍ͯͨ
Introduction •Objective-CͰͷiOSͷ։ൃྺ͕3 •Swiftɺ΄΅ະܦݧ •Ұ͔ΒSwiftͰ࡞ΒΕͨϓϩδΣΫτʹܞ ΘΓ͔ͨͬͨ •Ver 1ͷࠒͷSwift҆ఆ͍ͯ͠ͳ͔ͬͨͨ ΊɺσϦόϦʔ༏ઌͰObjective-C͕࠾༻ ͞Ε͍ͯͨ Ϋϥεϝιουస৬
Classmethod with Swift
http://dev.classmethod.jp/smartphone/swift/
None
http://amzn.asia/dnXD7zd ਡ๚ ༔ل
Introduction •ೖࣾॳ(201510݄)ͷ࣌ͰSwiftͷϓϩ δΣΫτ1ͭͷΈ •ͦͷϓϩδΣΫτΛ୲ͤͯ͞Βͬͨ •͍͔ͭ͘ͷػೳͷՃΛ୲ •લऀόοΫΤϯυ୲ͱͳ͍ͬͯͨʢPlay / Scalaʣ
Agenda
Agenda
Agenda •Contact with Architecture •Battle with Swift version •Delivery is
first priority •Battle with Swift version, second
Agenda •Contact with Architecture •Battle with Swift version •Delivery is
first priority •Battle with Swift version, second
Contact with Architecture
https://www.objc.io/issues/13-architecture/viper/ Architecting iOS Apps with VIPER
https://www.slideshare.net/UsrNameu1/viper-arch VIPER ΞʔΩςΫνϟʹΑΔ iOS ΞϓϦͷઃܭ
Contact with Architecture •σϦόϦʔ༏ઌͷ։ൃܦݧ͕ଟ͔ͬͨͨΊɺ ϚογϒViewControllerڐ༰͞Ε͕ͪͩͬͨ •ϨΠϠʔԽ͞ΕͨΫϦʔϯͳΞʔΩςΫνϟ ৽ͩͬͨ •ςετίʔυ͕ॆ࣮͍ͯͨ͠
Contact with Architecture •iOS 7αϙʔτ͍ͯͨͨ͠ΊɺҰ෦ͷϥΠϒϥ Ϧ͕CocoaPodsʹରԠ͍ͯ͠ͳ͔ͬͨ •CocoaPodsʹରԠ͍ͯ͠ͳ͔ͬͨϥΠϒϥϦ Submoduleܦ༝ͰΠϯϙʔτ͍ͯͨ͠ •ϑΝΠϧ͕ଟ͍ҝɺΞʔΩςΫνϟΛཧղ͠ ͳ͍ͱɺमਖ਼ʹ͕͔͔࣌ؒͬͨ
• CargoBay • CorePlot • MBProgressHUD • UICKeyChainStore • JASidePanels
• MagicalRecord • BlocksKit/UIKit • BlocksKit/MessageUI • Alamofire • SwiftyJSON • BrightFutures • OHHTTPStubs • Quick • Nimble
• CargoBay • CorePlot • MBProgressHUD • UICKeyChainStore • JASidePanels
• MagicalRecord • BlocksKit/UIKit • BlocksKit/MessageUI • Alamofire • SwiftyJSON • BrightFutures • OHHTTPStubs • Quick • Nimble
http://dev.classmethod.jp/smartphone/swift-brightfutures-1/
Future / Promise Future ฒྻʹ࣮ߦ͞ΕΔෳͷԋࢉΛऔΓѻ͏ͷʹศརͳ ํ๏Λఏڙ͢ΔɻͦΕޮతͰϊϯϒϩοΩϯάͳํ๏ͩɻ େ·͔ͳߟ͑ํγϯϓϧͳͷͰɺFuture ·ͩଘࡏ͠ͳ͍ ܭࢉ݁Ռʹର͢ΔϓϨʔεϗϧμͷΑ͏ͳͷͩɻ Ұൠత
ʹɺFuture ͷ݁Ռฒߦʹܭࢉ͞ΕޙͰूܭ͢Δ͜ͱ͕Ͱ͖ Δɻ ͜ͷΑ͏ʹฒߦͳλεΫΛ߹͢Δ͜ͱͰɺΑΓ͘ɺ ඇಉظͰɺϊϯϒϩοΩϯάͳฒྻίʔυͱͳΔ͜ͱ͕ଟ͍ɻ http://docs.scala-lang.org/ja/overviews/core/futures.html
http://docs.scala-lang.org/ja/overviews/core/futures.html
open func postWaveformWithLead( _ lead: Lead, subjectiveSymptoms: [Checkup.SubjectiveSymptom]?, createDate: Date,
saving: Bool, waveformData: Data) -> Future<Checkup, NSError> { let waveformUUID = UUID().uuidString return createLocalWaveformWithUuid( waveformUUID, lead: lead, subjectiveSymptoms: subjectiveSymptoms, createDate: createDate, waveformData: waveformData) .flatMap { [weak self] _ -> Future<JSON, NSError> in self?.uploadWaveformDatumWithLead( lead, subjectiveSymptoms: subjectiveSymptoms, createDate: createDate, saving: saving, waveformData: waveformData ) ?? Future(error: InteractorCancelError) } .flatMap { [weak self] json -> Future<Checkup, NSError> in self?.executeTaskAfterUploadWithJson(json, uuid: waveformUUID) ?? Future(error: InteractorCancelError) } }
open func postWaveformWithLead( _ lead: Lead, subjectiveSymptoms: [Checkup.SubjectiveSymptom]?, createDate: Date,
saving: Bool, waveformData: Data) -> Future<Checkup, NSError> { let waveformUUID = UUID().uuidString return createLocalWaveformWithUuid( waveformUUID, lead: lead, subjectiveSymptoms: subjectiveSymptoms, createDate: createDate, waveformData: waveformData) .flatMap { [weak self] _ -> Future<JSON, NSError> in self?.uploadWaveformDatumWithLead( lead, subjectiveSymptoms: subjectiveSymptoms, createDate: createDate, saving: saving, waveformData: waveformData ) ?? Future(error: InteractorCancelError) } .flatMap { [weak self] json -> Future<Checkup, NSError> in self?.executeTaskAfterUploadWithJson(json, uuid: waveformUUID) ?? Future(error: InteractorCancelError) } }
open func postWaveformWithLead( _ lead: Lead, subjectiveSymptoms: [Checkup.SubjectiveSymptom]?, createDate: Date,
saving: Bool, waveformData: Data) -> Future<Checkup, NSError> { let waveformUUID = UUID().uuidString return createLocalWaveformWithUuid( waveformUUID, lead: lead, subjectiveSymptoms: subjectiveSymptoms, createDate: createDate, waveformData: waveformData) .flatMap { [weak self] _ -> Future<JSON, NSError> in self?.uploadWaveformDatumWithLead( lead, subjectiveSymptoms: subjectiveSymptoms, createDate: createDate, saving: saving, waveformData: waveformData ) ?? Future(error: InteractorCancelError) } .flatMap { [weak self] json -> Future<Checkup, NSError> in self?.executeTaskAfterUploadWithJson(json, uuid: waveformUUID) ?? Future(error: InteractorCancelError) } }
open func postWaveformWithLead( _ lead: Lead, subjectiveSymptoms: [Checkup.SubjectiveSymptom]?, createDate: Date,
saving: Bool, waveformData: Data) -> Future<Checkup, NSError> { let waveformUUID = UUID().uuidString return createLocalWaveformWithUuid( waveformUUID, lead: lead, subjectiveSymptoms: subjectiveSymptoms, createDate: createDate, waveformData: waveformData) .flatMap { [weak self] _ -> Future<JSON, NSError> in self?.uploadWaveformDatumWithLead( lead, subjectiveSymptoms: subjectiveSymptoms, createDate: createDate, saving: saving, waveformData: waveformData ) ?? Future(error: InteractorCancelError) } .flatMap { [weak self] json -> Future<Checkup, NSError> in self?.executeTaskAfterUploadWithJson(json, uuid: waveformUUID) ?? Future(error: InteractorCancelError) } }
ͳΜͰ#PMUT͡Όͳ͍ΜͰ͢ ͔ʁ
ͳΜͰ#PMUT͡Όͳ͍ΜͰ͢ ͔ʁ ඇಉظॲཧ'VUVSFͰॻ͚ ඒ͍͠
ΞοϋΠ ඇಉظॲཧ'VUVSFͰॻ͚ ඒ͍͠
http://dev.classmethod.jp/server-side/scala-concurrent-future/
http://dev.classmethod.jp/server-side/scala-learn-flatmap/
ͳΜͰ3Y4XJGU͡Όͳ͍Μ Ͱ͔͢ʁ
ͳΜͰ3Y4XJGU͡Όͳ͍Μ Ͱ͔͢ʁ ඇಉظॲཧ'VUVSFͰॻ͚ ඒ͍͠
ͳΜͰ3Y4XJGU͡Όͳ͍Μ Ͱ͔͢ʁ ඇಉظॲཧ'VUVSFͰॻ͚ ඒ͍͠
Contact with Architecture •ར༻͢ΔϥΠϒϥϦνʔϜϝϯόʔͱϨ Ϗϡʔ͢Δ͜ͱඞਢ •ϚογϒViewControllerʹͳΒͳ͍Α͏ɺΞʔΩ ςΫνϟͷಋೖۃྗߦ͏ •ͲͷΞʔΩςΫνϟΛಋೖ͢Δ͔νʔϜͱσ ϦόϦʔͱ૬ஊ
Battle with Swift version
Swift 2.1 • Xcode 7 + iOS 9 SDKͰϏϧυ͕Մೳ •
Swift 2.x ܥͷAPIσβΠϯ • try / catch͕Ճ • Ұ෦ͷϓϩύςΟ͕Optionalʹͳͬͨ(SDK) • Dynamic LibraryରԠ(Xcode 7)
Migration • Xcode 7.1Ͱىಈͨ͠ࡍɺաڈͷSwift όʔ δϣϯͷ߹Convertը໘͕ىಈ͢Δ • ʮEdit > Convert
> To Current Swift Syntax.ʯ Ͱ࣮ߦՄೳ
None
Migration • Xcode 7.1Ͱىಈͨ͠ࡍɺաڈͷSwift όʔ δϣϯͷ߹Convertը໘͕ىಈ͢Δ • ʮEdit > Convert
> To Current Swift Syntax.ʯ Ͱ࣮ߦՄೳ • Swift 1.2 → Swift 2.1ͷ͍࣌ͷʹͳΒ ͳ͔ͬͨ ← New!
ಓͳमਖ਼࡞ۀ • BrightFuturesͷFutureͷܕ͕มߋʹͳͬͨ ͷͰमਖ਼
ಓͳमਖ਼࡞ۀ • Resultͷܕ͕มߋʹͳͬͨͷͰमਖ਼
ಓͳमਖ਼࡞ۀ • Dynamic LibraryରԠ • iOS 7Λαϙʔτ͔Βআ֎ͨ͠
ಓͳमਖ਼࡞ۀ • ϓϩύςΟͷOptionalରԠ
ಓͳमਖ਼࡞ۀ • ExceptionͷthrowରԠ
ಓͳमਖ਼࡞ۀ • map → forEachରԠ
iOS 9ରԠʢATSରԠʣ • S3ʹஔ͍ͨϑΝΠϧ͕औಘͰ͖ͳ͘ͳͬͨ • Preparing Your Apps for iOS
9Λࢀߟʹ Info.plistΛमਖ਼
Result
Battle with Swift version • iOS 7ͷαϙʔτͷ༗ແ͕ͦͷޙͷʹ େ͖ͳӨڹΛ༩͑ͨ • Τϥʔɾܯࠂͷ͕ଟͯ͘ରԠʹ͕࣌ؒ
͔͔ͬͨ • Ϗϧυͷ্͕͕ͬͨʢVer 1.2 : 12min → Ver 2.1 : 3minʣ
Delivery is first priority
Delivery is first priority
None
Battle with Swift version, second
Swift 3.0 • NS Prefix͔Βͷ٫ • ৽ͨͳΔAPIσβΠϯΨΠυϥΠϯ
Swift 3.0 • NS Prefix͔Βͷ٫ → Ұ෦Γ·ͨ͠ ʢNSNumberʣ • ৽ͨͳΔAPIσβΠϯΨΠυϥΠϯ
→ طଘ ͷϥΠϒϥϦͷϝιου໊มΘΓ͗͢ • ABI҆ఆԽ → Swift 4·ͰͬͯͶ
None
ʊਓਓਓਓਓਓਓਓਓʊ ʼɹࢼ͞ΕΔ৺ɹʻ ʉ:?:?:?:?:?:?:?:ʉ
Swift 2.3 • Xcode 8 + iOS 10 SDKͰϏϧυ͕Մೳ •
Swift 2.x ܥͷAPIσβΠϯ • ͱΓ͋͑ͣٸ͍ͰiOS 10ͰϏϧυ͢Δඞཁ ͕͋Δ߹
Swift 2.3 9DPEF3FMFBTF/PUFT • Xcode 8.2 ͕࠷ޙͷαϙʔτʹͳΔͨΊɺ Swift 3.0ͷରԠඞਢ
Migration to Swift 3.0
Swift 2.2ͷҠߦ • Xcode 7.2 + Swift 2.1 ͷ։ൃڥΛXcode 8.2
Ͱىಈͨ͠ࡍɺʮEdit > Convert > To Current Swift Syntax.ʯͷରʹTarget͕දࣔ ͞Εͳ͔ͬͨ • ͱΓ͋͑ͣɺXcode 7.3ͰSwift 2.1͔ΒSwift 2.2Ҡߦͨ͠
Migration • Xcode 8.2Ͱىಈͨ͠ࡍɺաڈͷSwift όʔδϣ ϯͷ߹Convertը໘͕ىಈ͢Δ • ʮEdit > Convert
> To Current Swift Syntax.ʯͰ ࣮ߦՄೳ • Swift 1.2 → Swift 2.1ͷ͍࣌ͷʹͳΒͳ ͔ͬͨ
None
None
ʊਓਓਓਓਓਓਓਓਓʊ ʼɹ$POWFSU'BJMFEɹʻ ʉ:?:?:?:?:?:?:?:?:?ʉ
Migration • Xcode 8.2Ͱىಈͨ͠ࡍɺաڈͷSwift όʔδϣ ϯͷ߹Convertը໘͕ىಈ͢Δ • ʮEdit > Convert
> To Current Swift Syntax.ʯͰ ࣮ߦՄೳ • Swift 1.2 → Swift 2.1ͷ͍࣌ͷʹͳΒͳ ͔ͬͨ • Swift 2.2 → Swift 3.0ͷ͍࣌ͷʹͳΒͳ ͔ͬͨ ← New!
ͦΕͰແ͍ΑΓϚγ • UIKitͷmethodͷม • Enumͷupper case → lower caseม •
NSPrefixͷϥΠϒϥϦͷม
ͻͨ͢Βಓͳ࡞ۀ • CurryԽͨ͠ϝιουͷमਖ਼ public static func log(level level: Level)(@autoclosure name:
() -> String) (@autoclosure message: () -> String) -> String { if level.rawValue <= Logger.currentLevel.rawValue { let full = "\(level.description): \(name()) - \(message())" print(full) return full } return "" }
ͻͨ͢Βಓͳ࡞ۀ • CurryԽͨ͠ϝιουͷमਖ਼ public static func log(level: Level) -> ((@escaping
() -> String) -> ((@escaping () -> String) -> String)) { return { (name: @escaping (() -> String)) in return { (message: @escaping (() -> String)) in if level.rawValue <= Logger.currentLevel.rawValue { let full = "\(level.description): \(name())) - \(message())" print(full) return full } return "" } } }
ͻͨ͢Βಓͳ࡞ۀ • closureʹ@escapingͷՃ
ͻͨ͢Βಓͳ࡞ۀ • Ҡߦπʔϧ͕มͨ͠Օॴͷमਖ਼ • Ωϟετ → Ωϟετ → Ωϟετ Date
as NSDate as Date String as NSString as String
ͻͨ͢Βಓͳ࡞ۀ • Unit Testͷमਖ਼
Result
Result
files additions deletions Ver 2.1 147 1268 1130 Ver 3.0
247 4314 4372 Pull Request Diff
Battle with Swift version, second • Ͱ͖ΕೋͱΓͨ͘ͳ͍ • ίϯϑϦΫτղফͷͨΊɺݽಠͳ࡞ۀͱ ͳΔ
• ৺Λࢼ͞ΕΔ
Recap
Recap •৽نϓϩδΣΫτશͯSwiftʹ •ΞʔΩςΫνϟʹ͍ͭͯ૬ஊͰ͖Δ ͕ܗ͞Εͨ •ΞʔϦʔΞμϓλʔͱͯ͠ɺ͖᪴ͳ͕Β ϊϋΛͨΊ͍͚ͯΔ
Recap •Swiftͷݴޠ༷ͷมԽʹ൱Ԡͳ͠ʹରԠ ΛഭΒΕΔ •બͨ͠ΞʔΩςΫνϟʹΑͬͯҭ ίετ͕ൃੜ͢Δ •σϦόϦʔΛ༏ઌ͠ͳ͚ΕͳΒͳ͍ঢ় گඞͣൃੜ͢Δ
None
Thank you!
One more thing…
ʲ େࡕΦϑΟε։ઃ1प!! ʳ Ϋϥεϝιουͷ։ൃΛΔʂશ7ճษڧ http://dev.classmethod.jp/news/mobileteam-inosaka/
ʲ େࡕΦϑΟε։ઃ1प!! ʳ Ϋϥεϝιουͷ։ൃΛΔʂશ7ճษڧ http://dev.classmethod.jp/news/mobileteam-inosaka/
We're hiring!!
https://classmethod.jp/recruit/
AWSࣄۀ෦ AWSΤϯδχΞʢAWSγεςϜڥͷߏஙࢧԉʣ AWSιϦϡʔγϣϯΞʔΩςΫτʢAWSγεςϜڥ ίϯαϧɾߏஙɾӡ༻ࢧԉʣ AWSΦϖϨʔγϣϯίϯαϧλϯτʢAWSγεςϜڥͷӡ༻ࣗಈԽࢧԉʣ AWSαʔϏεσϕϩούʔʢAWSΛ׆༻ͨ͠αʔϏε։ൃʣ ϞόΠϧΞϓϦαʔϏε෦ iOS / AndroidΞϓϦ։ൃΤϯδχΞ
― ౦ژ / ࡳຈ / େࡕ ϞόΠϧόοΫΤϯυΤϯδχΞ ― ౦ژ / ࡳຈ / େࡕ DevOpsΤϯδχΞ ― ౦ژ / ࡳຈ / େࡕ ϓϩδΣΫτϚωʔδϟʔʢϞόΠϧΞϓϦʣ ― ౦ژ / େࡕ ݱࡏืूதͷ৬छ https://classmethod.jp/recruit/jobs/