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
現場に降りてきたAI フィジカルAIの技術スタックと実案件デモ #devio2026
kongmingstrap
0
280
[デモです] NotebookLM で作ったスライドの例
kongmingstrap
0
690
Zenn のウラガワ ~エンジニアのアウトプットを支える環境で Google Cloud が採用されているワケ~ #burikaigi #burikaigi_h
kongmingstrap
22
8.6k
AWS re:Invent 2024 ふりかえり
kongmingstrap
0
520
製造の課題に立ち向かう Manufacturing Data Engine と Manufacturing Connect の ご紹介
kongmingstrap
0
1.4k
Tellus の衛星データを見てみよう #mf_fukuoka
kongmingstrap
0
1k
JAWS-UG 福岡 #16 re:Invent 現地に行った人のお話 #jawsugfuk #jawsug
kongmingstrap
0
810
AppMod の開発のイマを知るために現地に潜入した私が見たものは・・・? #GoogleCloudNext
kongmingstrap
0
900
Kong Gateway から読みとく、 API統合・API連携サービスの最新情報 #devio2023
kongmingstrap
0
2.3k
Other Decks in Technology
See All in Technology
新米を「売り越さない」、Aurora DSQLで作る在庫ゼロ死守の限定ドロップEC
yama3133
0
190
re:Invent2026 事前勉強会 歴史と愉しみ方10分LT編
toshi_atsumi
0
170
Agent Harnessはどう作る?事例から学ぶAI Agentの設計思想
sergicalsix
0
220
大江戸Ruby会議でデータベース クライアントの話をするのは 間違っているだろうか
yahonda
1
100
Metadata - Section 3 : Dublin Core Standard · DC
mohab1
0
120
属人化したISMS運用をGitHubとAIで仕組み化した1年間の記録
sioncojp
4
1.7k
Kiro Crew 入門 (手を離しても進む仕事) | 目指せ Kiro マスター 11
inariku
PRO
4
650
プロダクションコードにおける encoding/json から encoding/json/v2 へのスムーズな移行
sansantech
PRO
1
220
Kiro IDE 入門 (画面の各部から、頼み方、任せ方、戻し方まで) | 目指せ Kiro マスター 02
inariku
PRO
4
170
AI Agent 時代のデータ基盤: ClickHouse で実現する 超高速分析とコスト削減の両立
jozono
0
220
セキュリティ専任チームなしで攻撃を先回りするSREが実践したSIEM on Amazon OpenSearch Service
cscengineer
PRO
1
710
超⼩型・多⾔語検索モデル Bekko Embedding
hotchpotch
1
140
Featured
See All Featured
A better future with KSS
kneath
240
18k
The agentic SEO stack - context over prompts
schlessera
0
1k
What's in a price? How to price your products and services
michaelherold
247
13k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
560
Building Flexible Design Systems
yeseniaperezcruz
330
41k
30 Presentation Tips
portentint
PRO
1
460
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
480
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
2
390
Rails Girls Zürich Keynote
gr2m
96
14k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
33
5.7k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
8.2k
Scaling GitHub
holman
464
140k
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/