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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Yoichi Tagaya
September 16, 2017
Programming
21
6.7k
モバイルアプリで困らないエラーハンドリングとロギングのベストプラクティス
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
190
Dependency Injection Pattern for iOS App
yoichitgy
1
300
Dependency Injection Pattern for iOS Apps
yoichitgy
2
410
Practical Structure to Configure Dependency Injection in Swift for iOS
yoichitgy
1
540
Architecture and ReactorKit
yoichitgy
1
680
GDPRについて
yoichitgy
2
1.5k
More about Crashlytics and Less about GDPR ;)
yoichitgy
2
310
How to contribute to try! Swift Tokyo 2018
yoichitgy
0
94
Dependency Injection in Practice (iOSCon)
yoichitgy
0
490
Other Decks in Programming
See All in Programming
OCaml 5でモダンな並列プログラミングを Enjoyしよう!
haochenx
0
140
Spinner 軸ズレ現象を調べたらレンダリング深淵に飲まれた #レバテックMeetup
bengo4com
1
230
IFSによる形状設計/デモシーンの魅力 @ 慶應大学SFC
gam0022
1
300
0→1 フロントエンド開発 Tips🚀 #レバテックMeetup
bengo4com
0
560
20260127_試行錯誤の結晶を1冊に。著者が解説 先輩データサイエンティストからの指南書 / author's_commentary_ds_instructions_guide
nash_efp
1
950
Automatic Grammar Agreementと Markdown Extended Attributes について
kishikawakatsumi
0
180
CSC307 Lecture 06
javiergs
PRO
0
680
HTTPプロトコル正しく理解していますか? 〜かわいい猫と共に学ぼう。ฅ^•ω•^ฅ ニャ〜
hekuchan
2
680
CSC307 Lecture 08
javiergs
PRO
0
670
AIで開発はどれくらい加速したのか?AIエージェントによるコード生成を、現場の評価と研究開発の評価の両面からdeep diveしてみる
daisuketakeda
1
2.4k
登壇資料を作る時に意識していること #登壇資料_findy
konifar
4
1.1k
Unicodeどうしてる? PHPから見たUnicode対応と他言語での対応についてのお伺い
youkidearitai
PRO
1
2.5k
Featured
See All Featured
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
The SEO Collaboration Effect
kristinabergwall1
0
350
Believing is Seeing
oripsolob
1
54
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
140
For a Future-Friendly Web
brad_frost
182
10k
Color Theory Basics | Prateek | Gurzu
gurzu
0
200
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
75
Automating Front-end Workflow
addyosmani
1371
200k
Rails Girls Zürich Keynote
gr2m
96
14k
How to Talk to Developers About Accessibility
jct
2
130
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
1
99
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
1.8k
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%$