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
650
Zenn のウラガワ ~エンジニアのアウトプットを支える環境で Google Cloud が採用されているワケ~ #burikaigi #burikaigi_h
kongmingstrap
22
8.6k
AWS re:Invent 2024 ふりかえり
kongmingstrap
0
500
製造の課題に立ち向かう Manufacturing Data Engine と Manufacturing Connect の ご紹介
kongmingstrap
0
1.4k
Tellus の衛星データを見てみよう #mf_fukuoka
kongmingstrap
0
990
JAWS-UG 福岡 #16 re:Invent 現地に行った人のお話 #jawsugfuk #jawsug
kongmingstrap
0
790
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
使いこなすために知っておきたい Azure SRE Agent アンチパターン
torumakabe
2
380
私の推しは「聞いてから進む」AIです -AI-DLCに一人でアプリを作らせた話
yama3133
1
180
20260930_Gemma4_Hands-on
tsho
0
230
AI Made Us Faster at Solving the Wrong Problems
marceloancelmo
0
170
ログラスのマルチプロダクトを 支える認証基盤 〜テナントごとに異なる統制とどう向き合うか〜
dada4386
3
400
React Nativeでの OTA Updateって、 どう説明する?
ichiki1023
0
150
The seven pitfalls of AI (revised version)
ufried
0
270
OSC2026on_the-world-is-waiting-for-your-voice.pdf
naruoga
0
350
Datadog の学び方 - あるいは、オブザーバビリティを学ぶとは何か
mananyuki
1
490
大阪オフィスに Unitree Go2 がやってきたので Physical AI やってみた
dafujii
0
320
Lambda MicroVMsが分からなすぎたので使い所を1から考えてみた
tsukuboshi
2
410
FinTech 1-2 : Overview of FinTech
ks91
PRO
0
150
Featured
See All Featured
RailsConf 2023
tenderlove
30
1.6k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.4k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
300
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
For a Future-Friendly Web
brad_frost
183
10k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
270
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/