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
モバイルアプリで困らないエラーハンドリングとロギングのベストプラクティス
Search
Yoichi Tagaya
September 16, 2017
Programming
21
6.1k
モバイルアプリで困らないエラーハンドリングとロギングのベストプラクティス
iOSDC 2017 in Tokyo, September 16-17, 2017
https://iosdc.jp/2017/node/1482
Yoichi Tagaya
September 16, 2017
Tweet
Share
More Decks by Yoichi Tagaya
See All by Yoichi Tagaya
Dependency Injection
yoichitgy
0
130
Dependency Injection Pattern for iOS App
yoichitgy
1
250
Dependency Injection Pattern for iOS Apps
yoichitgy
2
380
Practical Structure to Configure Dependency Injection in Swift for iOS
yoichitgy
1
450
Architecture and ReactorKit
yoichitgy
1
570
GDPRについて
yoichitgy
2
1.3k
More about Crashlytics and Less about GDPR ;)
yoichitgy
2
290
How to contribute to try! Swift Tokyo 2018
yoichitgy
0
75
Dependency Injection in Practice (iOSCon)
yoichitgy
0
380
Other Decks in Programming
See All in Programming
Prepare for Jakarta EE 11 - Performance and Developer Productivity
ivargrimstad
0
270
株式会社ゼネテック
genetec
0
120
RustでAWS Lambda functionをいい感じに書く
taiki45
2
150
The Design of Everyday APIs - PyCon 2024
roguelynn
0
190
An adventure of Happy Eyeballs
coe401_
1
150
Exploring the Implementation of “t.Run”, “t.Parallel”, and “t.Cleanup”
akarin
1
160
TypeScript 関数型スタイルでバックエンド開発のリアル
naoya
49
16k
仕様と実装で学ぶOpenTelemetry
drumato
2
1.1k
Documentation testsの恩恵 / Documentation testing benefits
ssssota
1
560
一文字エイリアスのすすめ
fujimura
0
200
JS RPCを理解する
yusukebe
5
270
WinActorの勉強を継続する方法
tamai_63
0
130
Featured
See All Featured
Java REST API Framework Comparison - PWX 2021
mraible
PRO
18
7k
Fireside Chat
paigeccino
22
2.7k
What’s in a name? Adding method to the madness
productmarketing
PRO
17
2.7k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
34
8.9k
VelocityConf: Rendering Performance Case Studies
addyosmani
321
23k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
15
1.6k
Web development in the modern age
philhawksworth
203
10k
A better future with KSS
kneath
231
16k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
275
13k
How To Stay Up To Date on Web Technology
chriscoyier
782
250k
How to Ace a Technical Interview
jacobian
273
22k
Creatively Recalculating Your Daily Design Routine
revolveconf
211
11k
Transcript
!ZPJDIJUHZ ϞόΠϧΞϓϦͰࠔΒͳ͍ ΤϥʔϋϯυϦϯάͱ ϩΪϯάͷϕετϓϥΫςΟε ଟլ୩ ༸Ұ iOSDC JAPAN 2017
!ZPJDIJUHZ ࣗݾհ ʙ ଟլ୩ ༸Ұ • Swinject (Dependency Injection Framework)
ͷ࡞ऀ ‣ ଟͷϓϩμΫγϣϯ࠾༻ ‣ GitHubελʔ: ͏͙͢2000 • ϝϧΧϦͷiOSΤϯδχΞ ‣ ओʹΞϝϦΧ൛ΞϓϦΛ୲ ‣ 9/30 () Mercari Tech Conf 2017ͰDIͷΛ͠·͢ J04%$ͰlίʔυੜʹΑΔ੩తͳ%FQFOEFODZ*OKFDUJPOzCZ!JTILBXBPO4FQ
!ZPJDIJUHZ •ɹΤϯδχΞͷεΩϧ •ɹίʔυϨϏϡʔ •ɹϢχοτςετ •ɹ6*ࣗಈςετ •ɹखಈςετ •ɹΤϥʔϩά ࠓͷ ΞϓϦͷ্࣭ʹඞཁͳ͜ͱ
!ZPJDIJUHZ ͜Μͳͷݟͨ͜ͱ͋Γ·ͤΜ͔ʁ ΫϥογϡͰ1ˑϨϏϡʔͷཛྷ ࠶ݱ͠ͳ͍ Ͳ͏͢Ε͍͍͔͔Βͳ͍ ΞϓϦΛόʔδϣϯΞοϓͨ͠
!ZPJDIJUHZ Ϋϥογϡϩάͱ͍͑
!ZPJDIJUHZ Crashlytics IUUQTXXXGBCSJDJP $SBTIMZUJDTΛਂ͘୳ͬͯΈΑ͏
!ZPJDIJUHZ CrashlyticsͰҰ൪ॏཁͳ͜ͱ IUUQTEPDTGBCSJDJPBQQMFDSBTIMZUJDTUFTUDSBTIIUNMUSPVCMFTIPPUJOH func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
[UIApplicationLaunchOptionsKey: Any]? ) -> Bool { Fabric.with([Crashlytics.self]) return true } ϩάΫϥογϡޙʹΞϓϦ͕࠶ىಈͨ࣌͠ʹૹΒΕΔ application:didFinishLaunchingWithOptionsΛແࣄʹ௨ա͠ͳ͍ͱμϝ
!ZPJDIJUHZ ىಈ࣌ application:didFinishLaunchingWithOptionsͰͦ͠͏ͳ͜ͱ • ֤छϑϨʔϜϫʔΫͷॳظԽ •ɹ%BUBCBTFͷϚΠάϨʔγϣϯ •ɹΩϟογϡͷΫϦΞ ϝΠϯεϨουΛ࣌ؒࢭΊͳ͍
!ZPJDIJUHZ ಛʹґଘϥΠϒϥϦʹҙ IUUQTHJUIVCDPNQJOUFSFTU1*/3FNPUF*NBHFJTTVFT 1*/3FNPUF*NBHFࣗମ͍͍ϥΠϒϥϦͰ͢
!ZPJDIJUHZ ͦΕͰ
!ZPJDIJUHZ Crashlyticsͬͯ Πϯετʔϧ͢ΔҎ֎ʹ Կ͔ඞཁͳͷʁ
!ZPJDIJUHZ Crashlyticsʹ ศརͳՃใ͕͋Δ
!ZPJDIJUHZ ϢʔβใͷՃ γϯάϧτϯϝιου આ໌ TFU6TFS*EFOUJpFS @ 6TFS*EΛઃఆ͢Δ TFU6TFS&NBJM @ &NBJMΛઃఆ͢Δ
6TFS*E͕͋Εී௨ෆཁ TFU6TFS/BNF @ Ϣʔβͷ໊લΛઃఆ͢Δ 6TFS*E͕͋Εී௨ෆཁ ΧελϚʔαϙʔτͷใ͔ΒௐΔ࣌ʹศར &NBJMͱϢʔβͷ໊લ໌Β͔ͳݸਓใͳͷͰҙ
!ZPJDIJUHZ Key/ValueͷՃ γϯάϧτϯϝιου આ໌ TFU0CKFDU7BMVF @GPS,FZ 4USJOHͳͲΛ,FZʹରͯ͠ઃఆ͢Δ TFU#PPM7BMVF @GPS,FZ #PPMΛ,FZʹରͯ͠ઃఆ͢Δ
TFU*OU7BMVF @GPS,FZ *OUΛ,FZʹରͯ͠ઃఆ͢Δ TFU'MPBU7BMVF @GPS,FZ 'MPBUΛ,FZʹରͯ͠ઃఆ͢Δ 3FNPUF$POpH "#5FTU %PXOMPBEͨ͠Ϧιʔε+4ͷ7FSTJPOʹ ࠷େݸͷ,FZ·Ͱͭͷ,FZ7BMVF͕,#·Ͱ ,FZ͕ͨ͘͞ΜඞཁͳΒ+40/จࣈྻʹ͢Δ͜ͱݕ౼
!ZPJDIJUHZ ΧελϜϩάͷՃ ؔ આ໌ $-4-PHW @GPSNBU BSHT Ϋϥογϡൃੜલͷϩά͕Ϋϥογϡʹඥ͚ΒΕΔ ΫϥογϡͷݪҼʹͳΔલͷಈ࡞͕Θ͔Δ
ϩά࠷େ,# ߦจࣈ͘Β͍ͳΒߦ͘Β͍ ͋;ΕͨΒݹ͍ͷ͔Βফ͞ΕΔ Ϣʔβߦಈ Πϕϯτ ͷϩά"OTXFST'JSFCBTFͳͲΛ͏
!ZPJDIJUHZ ඇΫϥογϡͷϨϙʔτΛՃ γϯάϧτϯϝιου આ໌ SFDPSE&SSPS @ ॏେͳΤϥʔͰϩάΤϯτϦʔΛ࡞Δ Ϩϙʔτ/PO'BUBMTάϧʔϓʹ·ͱΊΒΕΔ ΞϓϦ࠶ىಈ࣌ʹ$SBTIMZUJDTʹૹ৴͞ΕΔ
Ϋϥογϡ͠ͳ͍͕ॏେͳΤϥʔΛ$SBTIMZUJDTͰ֬ೝͰ͖Δ ϩάʹΔͷΞϓϦ࠶ىಈ·Ͱͷ࠷େݸͷΤϥʔ·Ͱ $16ίετ͕͔͔ΔͷͰΦϒβʔόʔޮՌʹҙ %8"3' %FCVH8JUI"UUSJCVUFE3FDPSE'PSNBU VOXJOEJOH
!ZPJDIJUHZ CrashlyticsΛ OSLogͱΈ߹Θͤͯ ࣗ࡞ͷϩΨʔΛ࡞Γ·͢
!ZPJDIJUHZ OSLog/os_log var osLog = OSLog( subsystem: “com.my-company.LoggingSample", category: “ViewModel”
) os_log(“Hello world!”, log: osLog, type: .default) ͍ํ J04͔Β͑ΔΑ͏ʹͳͬͨϩάͷΈ
!ZPJDIJUHZ OSLogType IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOPTMPHHJOH ϩάϨϕϧ อଘઌ ಛ EFCVH ͳ͠ σόοά༻
JOGP ϝϞϦʔ όοϑΝʔ͕͍ͬͺ͍ʹͳͬͨΒফ͑Δ Τϥʔ͕ى͖ͨ߹อଘ͞ΕΔ EFGBVMU ετϨʔδ ࠷ॳόοϑΝʔʹอଘ͞ΕΔ ͍ͬͺ͍ʹͳͬͨΒετϨʔδʹҠ͞ΕΔ FSSPS ετϨʔδ ϓϩηεͷΤϥʔͰ͏ GBVMU ετϨʔδ ෳϓϩηε͕ؔΘΔΤϥʔͰ͏
!ZPJDIJUHZ Console App IUUQTEFWFMPQFSBQQMFDPNWJEFPTQMBZXXED IUUQTNFEJVNDPN!BCKVSBUPVOJpFEMPHHJOHBOEBDUJWJUZUSBDJOHBB⒎FGC • "DUJWJUZ5SBDJOHͱΈ߹ ΘͤΔͱศར • ෳϓϩηε͕ؔΘΔΞ
ϓϦͷσόοάͰศར w .BD"QQ w 8BUDI"QQ • ݱঢ়4XJGU͔Β ͑ͳ͍ w ͏ʹԼͷϦϯΫࢀর
!ZPJDIJUHZ ͔͠͠ͳ͕Β ࠓճγϯϓϧͳ༻๏ʹཹΊ·͢ # $SBTIMZUJDT͚ͩͰेڧྗ
!ZPJDIJUHZ ࣗ࡞ϩΨʔͷϩάϨϕϧ ϩάϨϕϧ ༻్ ॲཧ EFCVH %FCVH࣌ʹ͚ͩ ݟ͍ͨใ $POTPMFʹͷΈग़ྗ
JOGP "1*ίʔϧ τϨʔε $POTPMFͱ$-4-PHWͷग़ྗ FSSPS ϋϯυϦϯά ՄೳͳΤϥʔ $POTPMFͱ$-4-PHWͷग़ྗ $-4-PHWͷϝοηʔδݕࡧੑΛ্͛Δ GBUBM ఆ֎ͷΤϥʔ $POTPMFʹग़ྗ SFDPSE&SSPSͰ$SBTIMZUJDTͷϨϙʔτΤϯτϦʔΛ࡞Δ BTTFSUJPO'BJMVSFೖΕͯ%FCVHϏϧυͰམͪΔΑ͏ʹ͢Δ
!ZPJDIJUHZ LogΫϥε final class Log { static func debug(message: String)
{ os_log("⚒%@", type: .debug, message) } static func info(message: String) { os_log("ℹ%@", type: .debug, message) CLSLogv("%@", getVaList([message])) } static func error(message: String) { os_log("❗%@", type: .debug, message) CLSLogv("[Error] %@", getVaList([message])) } }
!ZPJDIJUHZ LogΫϥε final class Log { static func fatal( message:
String, file: String = #file, function: String = #function, line: Int = #line) { os_log("%@", log: .default, type: .debug, message) let fileName = file.components(separatedBy: "/").last ?? "" let error = NSError( domain: "\(fileName):\(function)", code: line, userInfo: ["message": message] ) Crashlytics.sharedInstance().recordError(error) assertionFailure(message) } }
!ZPJDIJUHZ final class Log { static func error(error: Error) {
let message = String(reflecting: error) os_log("❗%@", log: .default, type: .debug, message) CLSLogv("[Error] %@", getVaList([message])) } static func fatal(error: Error) { let message = String(reflecting: error) os_log("%@", log: .default, type: .debug, message) Crashlytics.sharedInstance() .recordError(error as NSError) assertionFailure(message) } } LogΫϥε
!ZPJDIJUHZ Demo -PHTXJGUIUUQTHJTUHJUIVCDPNZPJDIJUHZBEBBEFGFBBCB "QQ%FMFHBUFTXJGUIUUQTHJTUHJUIVCDPNZPJDIJUHZFEBGBCGFCFBCDF 7JFX$POUSPMMFSTXJGUIUUQTHJTUHJUIVCDPNZPJDIJUHZFCBFGEECBBD
!ZPJDIJUHZ Demoͨ͜͠ͱ
!ZPJDIJUHZ Demoͨ͜͠ͱ
!ZPJDIJUHZ guard let something = something else { // Swallow
return } guard !array.isEmpty else { // Swallow return } guard let something = something else { Log.fatal(message: "something is nil unexpectedly.") return } guard !array.isEmpty else { Log.fatal(message: "array is empty.") return } ࠷ޙʹ ෆਖ਼ͳঢ়ଶΛҿΈࠐΜͰ͍ͨΒ࠷ѱͰϩάΛૹ͓ͬͯ͜͏ ݱࡏͷ࣮Ͱ͋Γ͑ͳͯ͘কདྷͷόάΛݕ͢ΔͨΊ
!ZPJDIJUHZ %BUF 4QFBLFS 5JUMF !UFOOUFOO (PʹΑΔJ04ΞϓϦͷ։ൃ !DIVHBO[Z ϝϧΧϦͰ࣮ࢪͨ͠աڈ࠷େنͷ"#ςετʮυϩϫʔWTԼλϒʯͷཪ
!LJUBTVLF *OUSPEVDJOHQSPUPCVGJO4XJGU !KBSJOPTVLF 64൛.FSDBSJΛ·Δ͝ͱ͔Β࡞Γͨ͠ !NPUPLJFF ݁ࠗࣜΛࢧٕ͑ͨज़'JSFCBTFΛ׆༻ͨ͠αʔόϨεJ04ΞϓϦέʔγϣϯ։ൃ !EUWE ϝϧΧϦΞοςΛࢧ͑ΔΦʔτϚτϯ !KPMMZKPFTUFS པΉ͔Βϓογϡ௨ͷ͍ํΛ͓Ζ͔ͦʹ͠ͳ͍Ͱ͘Εʂ ʙϓογϡ௨ͷදݱɺྺ࢙ɺ࠷৽ಈ·Ͱʙ Thank you .PSFGSPN BUJ04%$