Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
モバイルアプリで困らないエラーハンドリングとロギングのベストプラクティス
Search
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
290
Dependency Injection Pattern for iOS Apps
yoichitgy
2
410
Practical Structure to Configure Dependency Injection in Swift for iOS
yoichitgy
1
520
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
480
Other Decks in Programming
See All in Programming
フルサイクルエンジニアリングをAI Agentで全自動化したい 〜構想と現在地〜
kamina_zzz
0
310
生成AIを利用するだけでなく、投資できる組織へ
pospome
2
410
AIコーディングエージェント(NotebookLM)
kondai24
0
240
AI Agent Tool のためのバックエンドアーキテクチャを考える #encraft
izumin5210
4
1.3k
生成AI時代を勝ち抜くエンジニア組織マネジメント
coconala_engineer
0
24k
Go コードベースの構成と AI コンテキスト定義
andpad
0
140
これならできる!個人開発のすゝめ
tinykitten
PRO
0
130
メルカリのリーダビリティチームが取り組む、AI時代のスケーラブルな品質文化
cloverrose
2
390
HTTPプロトコル正しく理解していますか? 〜かわいい猫と共に学ぼう。ฅ^•ω•^ฅ ニャ〜
hekuchan
2
470
Denoのセキュリティに関する仕組みの紹介 (toranoana.deno #23)
uki00a
0
170
チームをチームにするEM
hitode909
0
390
Navigation 3: 적응형 UI를 위한 앱 탐색
fornewid
1
460
Featured
See All Featured
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
320
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
0
1k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Mind Mapping
helmedeiros
PRO
0
39
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
28
Agile that works and the tools we love
rasmusluckow
331
21k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
92
Reality Check: Gamification 10 Years Later
codingconduct
0
1.9k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
196
70k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
91
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.2k
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%$