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
今なら言える、 クラスメソッドと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
870
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
設計の世代交代を乗り越える、14年続くAndroidアプリの開発戦略
sansantech
PRO
1
150
Bet AI Day 2026丨AIによって本質に戻るシステムリスク管理
layerx
PRO
0
1.2k
GoにおけるFFIのこれまでとこれから
goccy
1
230
Autonomous AI Databaseサービス・アップデート(FY27)/ adb-service-update-jp-fy27
oracle4engineer
PRO
0
130
AIで開発は速くなったのに、なぜ現場は楽にならないのか 〜あなたの組織のボトルネックを突き止めるワークショップ〜
jacopen
1
270
KAEN Company Deck
kaen
PRO
0
320
Sony-DroidKaigi2026
sony
1
320
AIとペアプロを始める。人とのペアプロをやめる。ペアプロの良さを改めて知る。もっと好きになった。 / Rediscovering Pair Programming
honyanya
1
280
Driving AI Adoption Using In-House GPUs to Serve Qwen
po3rin
2
460
Lakebase ワークショップ / Lakebase-workshop
databricksjapan
PRO
0
110
KPIだけでは評価できないプロダクトが考えるべき Evalsという第二の評価系 / Beyond KPIs: Evals as a Second Evaluation Framework for Products #PdEConf
aki_iinuma
4
3.7k
全員がプロダクトへ向き合う組織を持続成長させるために——組織づくりのフライホイールと4象限 / The Flywheel Model and Four Quadrants for Organizational Design
hiro_torii
3
880
Featured
See All Featured
Building an army of robots
kneath
306
46k
Abbi's Birthday
coloredviolet
3
9.8k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.8k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
710
Automating Front-end Workflow
addyosmani
1369
210k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
[RailsConf 2023] Rails as a piece of cake
palkan
59
7k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
520
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
420
Art, The Web, and Tiny UX
lynnandtonic
304
22k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.9k
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/