Slide 1

Slide 1 text

!ZPJDIJUHZ ϞόΠϧΞϓϦͰࠔΒͳ͍ ΤϥʔϋϯυϦϯάͱ ϩΪϯάͷϕετϓϥΫςΟε ଟլ୩ ༸Ұ iOSDC JAPAN 2017

Slide 2

Slide 2 text

!ZPJDIJUHZ ࣗݾ঺հ ʙ ଟլ୩ ༸Ұ • Swinject (Dependency Injection Framework) ͷ࡞ऀ ‣ ଟ਺ͷϓϩμΫγϣϯ࠾༻ ‣ GitHubελʔ਺: ΋͏͙͢2000 • ϝϧΧϦͷiOSΤϯδχΞ ‣ ओʹΞϝϦΧ൛ΞϓϦΛ୲౰ ‣ 9/30 (౔) Mercari Tech Conf 2017ͰDIͷ࿩Λ͠·͢ J04%$Ͱ͸lίʔυੜ੒ʹΑΔ੩తͳ%FQFOEFODZ*OKFDUJPOzCZ!JTILBXBPO4FQ

Slide 3

Slide 3 text

!ZPJDIJUHZ •ɹΤϯδχΞͷεΩϧ •ɹίʔυϨϏϡʔ •ɹϢχοτςετ •ɹ6*ࣗಈςετ •ɹखಈςετ •ɹΤϥʔϩά ࠓ೔ͷ࿩ ΞϓϦͷ඼࣭޲্ʹඞཁͳ͜ͱ

Slide 4

Slide 4 text

!ZPJDIJUHZ ͜Μͳͷݟͨ͜ͱ͋Γ·ͤΜ͔ʁ ΫϥογϡͰ1ˑϨϏϡʔͷཛྷ ࠶ݱ͠ͳ͍ Ͳ͏͢Ε͹͍͍͔෼͔Βͳ͍ ΞϓϦΛόʔδϣϯΞοϓͨ͠

Slide 5

Slide 5 text

!ZPJDIJUHZ Ϋϥογϡϩάͱ͍͑͹

Slide 6

Slide 6 text

!ZPJDIJUHZ Crashlytics IUUQTXXXGBCSJDJP $SBTIMZUJDTΛਂ͘୳ͬͯΈΑ͏

Slide 7

Slide 7 text

!ZPJDIJUHZ CrashlyticsͰҰ൪ॏཁͳ͜ͱ IUUQTEPDTGBCSJDJPBQQMFDSBTIMZUJDTUFTUDSBTIIUNMUSPVCMFTIPPUJOH func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? ) -> Bool { Fabric.with([Crashlytics.self]) return true } ϩά͸ΫϥογϡޙʹΞϓϦ͕࠶ىಈͨ࣌͠ʹૹΒΕΔ application:didFinishLaunchingWithOptionsΛແࣄʹ௨ա͠ͳ͍ͱμϝ

Slide 8

Slide 8 text

!ZPJDIJUHZ ىಈ࣌ application:didFinishLaunchingWithOptionsͰͦ͠͏ͳ͜ͱ • ֤छϑϨʔϜϫʔΫͷॳظԽ •ɹ%BUBCBTFͷϚΠάϨʔγϣϯ •ɹΩϟογϡͷΫϦΞ ϝΠϯεϨουΛ௕࣌ؒࢭΊͳ͍

Slide 9

Slide 9 text

!ZPJDIJUHZ ಛʹґଘϥΠϒϥϦʹ஫ҙ IUUQTHJUIVCDPNQJOUFSFTU1*/3FNPUF*NBHFJTTVFT 1*/3FNPUF*NBHFࣗମ͸͍͍ϥΠϒϥϦͰ͢

Slide 10

Slide 10 text

!ZPJDIJUHZ ͦΕͰ

Slide 11

Slide 11 text

!ZPJDIJUHZ Crashlyticsͬͯ Πϯετʔϧ͢ΔҎ֎ʹ Կ͔ඞཁͳͷʁ

Slide 12

Slide 12 text

!ZPJDIJUHZ Crashlyticsʹ͸ ศརͳ෇Ճ৘ใ͕͋Δ

Slide 13

Slide 13 text

!ZPJDIJUHZ Ϣʔβ৘ใͷ௥Ճ γϯάϧτϯϝιου આ໌ TFU6TFS*EFOUJpFS @ 6TFS*EΛઃఆ͢Δ TFU6TFS&NBJM @ &NBJMΛઃఆ͢Δ 6TFS*E͕͋Ε͹ී௨͸ෆཁ TFU6TFS/BNF @ Ϣʔβͷ໊લΛઃఆ͢Δ 6TFS*E͕͋Ε͹ී௨͸ෆཁ  ΧελϚʔαϙʔτͷ৘ใ͔Βௐ΂Δ࣌ʹศར  &NBJMͱϢʔβͷ໊લ͸໌Β͔ͳݸਓ৘ใͳͷͰ஫ҙ

Slide 14

Slide 14 text

!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/จࣈྻʹ͢Δ͜ͱ΋ݕ౼

Slide 15

Slide 15 text

!ZPJDIJUHZ ΧελϜϩάͷ௥Ճ ؔ਺ આ໌ $-4-PHW @GPSNBU BSHT Ϋϥογϡൃੜલͷϩά͕Ϋϥογϡʹඥ෇͚ΒΕΔ  ΫϥογϡͷݪҼʹͳΔ௚લͷಈ࡞͕Θ͔Δ  ϩά͸࠷େ,# ߦจࣈ͘Β͍ͳΒߦ͘Β͍   ͋;ΕͨΒݹ͍΋ͷ͔Βফ͞ΕΔ  Ϣʔβߦಈ Πϕϯτ ͷϩά͸"OTXFST΍'JSFCBTFͳͲΛ࢖͏

Slide 16

Slide 16 text

!ZPJDIJUHZ ඇΫϥογϡͷϨϙʔτΛ௥Ճ γϯάϧτϯϝιου આ໌ SFDPSE&SSPS @ ॏେͳΤϥʔͰϩάΤϯτϦʔΛ࡞Δ Ϩϙʔτ͸/PO'BUBMTάϧʔϓʹ·ͱΊΒΕΔ ΞϓϦ࠶ىಈ࣌ʹ$SBTIMZUJDTʹૹ৴͞ΕΔ  Ϋϥογϡ͠ͳ͍͕ॏେͳΤϥʔΛ$SBTIMZUJDTͰ֬ೝͰ͖Δ  ϩάʹ࢒Δͷ͸ΞϓϦ࠶ىಈ·Ͱͷ࠷େݸͷΤϥʔ·Ͱ  $16ίετ͕͔͔ΔͷͰΦϒβʔόʔޮՌʹ஫ҙ  %8"3' %FCVH8JUI"UUSJCVUFE3FDPSE'PSNBU VOXJOEJOH

Slide 17

Slide 17 text

!ZPJDIJUHZ CrashlyticsΛ OSLogͱ૊Έ߹Θͤͯ ࣗ࡞ͷϩΨʔΛ࡞Γ·͢

Slide 18

Slide 18 text

!ZPJDIJUHZ OSLog/os_log var osLog = OSLog( subsystem: “com.my-company.LoggingSample", category: “ViewModel” ) os_log(“Hello world!”, log: osLog, type: .default) ࢖͍ํ J04͔Β࢖͑ΔΑ͏ʹͳͬͨϩάͷ࢓૊Έ

Slide 19

Slide 19 text

!ZPJDIJUHZ OSLogType IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOPTMPHHJOH ϩάϨϕϧ อଘઌ ಛ௃ EFCVH ͳ͠  σόοά༻ JOGP ϝϞϦʔ  όοϑΝʔ͕͍ͬͺ͍ʹͳͬͨΒফ͑Δ  Τϥʔ͕ى͖ͨ৔߹͸อଘ͞ΕΔ EFGBVMU ετϨʔδ  ࠷ॳόοϑΝʔʹอଘ͞ΕΔ  ͍ͬͺ͍ʹͳͬͨΒετϨʔδʹҠ͞ΕΔ FSSPS ετϨʔδ  ϓϩηε಺ͷΤϥʔͰ࢖͏ GBVMU ετϨʔδ  ෳ਺ϓϩηε͕ؔΘΔΤϥʔͰ࢖͏

Slide 20

Slide 20 text

!ZPJDIJUHZ Console App IUUQTEFWFMPQFSBQQMFDPNWJEFPTQMBZXXED IUUQTNFEJVNDPN!BCKVSBUPVOJpFEMPHHJOHBOEBDUJWJUZUSBDJOHBB⒎FGC • "DUJWJUZ5SBDJOHͱ૊Έ߹ ΘͤΔͱศར • ෳ਺ϓϩηε͕ؔΘΔΞ ϓϦͷσόοάͰศར w .BD"QQ w 8BUDI"QQ • ݱঢ়͸4XJGU͔Β͸௚઀࢖ ͑ͳ͍ w ࢖͏ʹ͸ԼͷϦϯΫࢀর

Slide 21

Slide 21 text

!ZPJDIJUHZ ͔͠͠ͳ͕Β ࠓճ͸γϯϓϧͳ࢖༻๏ʹཹΊ·͢ # $SBTIMZUJDT͚ͩͰे෼ڧྗ

Slide 22

Slide 22 text

!ZPJDIJUHZ ࣗ࡞ϩΨʔͷϩάϨϕϧ ϩάϨϕϧ ༻్ ॲཧ EFCVH %FCVH࣌ʹ͚ͩ ݟ͍ͨ৘ใ  $POTPMFʹͷΈग़ྗ JOGP "1*ίʔϧ౳ τϨʔε  $POTPMFͱ$-4-PHWͷग़ྗ FSSPS ϋϯυϦϯά ՄೳͳΤϥʔ  $POTPMFͱ$-4-PHWͷग़ྗ  $-4-PHWͷϝοηʔδ͸ݕࡧੑΛ্͛Δ GBUBM ૝ఆ֎ͷΤϥʔ  $POTPMFʹग़ྗ  SFDPSE&SSPSͰ$SBTIMZUJDTͷϨϙʔτΤϯτϦʔΛ࡞Δ  BTTFSUJPO'BJMVSF΋ೖΕͯ%FCVHϏϧυͰམͪΔΑ͏ʹ͢Δ

Slide 23

Slide 23 text

!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])) } }

Slide 24

Slide 24 text

!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) } }

Slide 25

Slide 25 text

!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Ϋϥε

Slide 26

Slide 26 text

!ZPJDIJUHZ Demo  -PHTXJGUIUUQTHJTUHJUIVCDPNZPJDIJUHZBEBBEFGFBBCB  "QQ%FMFHBUFTXJGUIUUQTHJTUHJUIVCDPNZPJDIJUHZFEBGBCGFCFBCDF  7JFX$POUSPMMFSTXJGUIUUQTHJTUHJUIVCDPNZPJDIJUHZFCBFGEECBBD

Slide 27

Slide 27 text

!ZPJDIJUHZ Demoͨ͜͠ͱ

Slide 28

Slide 28 text

!ZPJDIJUHZ Demoͨ͜͠ͱ

Slide 29

Slide 29 text

!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 } ࠷ޙʹ ෆਖ਼ͳঢ়ଶΛҿΈࠐΜͰ͍ͨΒ࠷ѱͰ΋ϩάΛૹ͓ͬͯ͜͏ ݱࡏͷ࣮૷Ͱ͸͋Γ͑ͳͯ͘΋কདྷͷόάΛݕ஌͢ΔͨΊ

Slide 30

Slide 30 text

!ZPJDIJUHZ %BUF 4QFBLFS 5JUMF  !UFOOUFOO (PʹΑΔJ04ΞϓϦͷ։ൃ  !DIVHBO[Z ϝϧΧϦͰ࣮ࢪͨ͠աڈ࠷େن໛ͷ"#ςετʮυϩϫʔWTԼλϒʯͷ෣୆ཪ  !LJUBTVLF *OUSPEVDJOHQSPUPCVGJO4XJGU  !KBSJOPTVLF 64൛.FSDBSJΛ·Δ͝ͱ͔Β࡞Γ௚ͨ͠࿩  !NPUPLJFF ݁ࠗࣜΛࢧٕ͑ͨज़'JSFCBTFΛ׆༻ͨ͠αʔόϨεJ04ΞϓϦέʔγϣϯ։ൃ  !EUWE ϝϧΧϦΞοςΛࢧ͑ΔΦʔτϚτϯ  !KPMMZKPFTUFS པΉ͔Βϓογϡ௨஌ͷ࢖͍ํΛ͓Ζ͔ͦʹ͠ͳ͍Ͱ͘Εʂ ʙϓογϡ௨஌ͷදݱɺྺ࢙ɺ࠷৽ಈ޲·Ͱʙ Thank you .PSFGSPN BUJ04%$