iOSアプリの開発速度を170%に向上させたデバッグノウハウ / Debugging knowhow that improved our development velocity to 170%

151a0b14f5914e786e2e104cfb3a9b2f?s=47 Kuniwak
September 02, 2018

iOSアプリの開発速度を170%に向上させたデバッグノウハウ / Debugging knowhow that improved our development velocity to 170%

開発時間に占めるデバッグ時間の割合は少なくないため、この時間の短縮は開発速度を上げるためにとても重要です。この発表では、実際の中規模なアプリ開発で70%増もの開発速度向上を支えたデバッグノウハウを初心者にもわかりやすく紹介します。

https://fortee.jp/iosdc-japan-2018/proposal/7286f755-e980-4f6f-b268-2c56a224b727

151a0b14f5914e786e2e104cfb3a9b2f?s=128

Kuniwak

September 02, 2018
Tweet

Transcript

  1. J04 ΞϓϦͷ։ൃ଎౓Λ
  ʹ޲্ͤͨ͞
 σόοάϊ΢ϋ΢ Kuniwak - DeNA Co.,Ltd. 2018.09.02

    iOSDC Japan 2018
  2. "CPVUNF

  3. ,VOJXBL w ॴଐˠ w HJUIVCDPN,VOJXBL w RJJUBDPN,VOJXBL w "QQ$PEF-PWFS

  4. ͜ͷൃදͰ։ൃ଎౓Λ
 ͋͛ΒΕΔਓ ͸͡Ίʹ

  5. ్த·Ͱ͏·͍͘͘ͷʹ
 కΊ੾Γʹؒʹ߹Θͳ͍

  6. కΊ੾Γ͕ഭͬͯ͘Δͱ
 ಈ࡞֬ೝΛ͖͠Εͳͯ͘
 େৎ෉ͩͱ৴͡Δ͔͠ͳ͍

  7. 4JNVMBUPSΆͪΆͪʹ
 ͕͔͔࣌ؒͬͯΠϥΠϥ͢Δ

  8. ͜Μͳ͓೰Έɺօ͞Μʹ΋͋Γ·ͤΜ͔ʁ ͜͏վળͨ͠Αʂͱ͍ͬͨମݧ͕͋Ε͹ɺ
 ͥͻUXFFU͍ͯͩ͘͠͞ʂ

  9. ͜ͷൃදͰ఻͍͑ͨ͜ͱ ͓೰Έͷ͋ͳͨ΁

  10. ΁ͷ։ൃ଎౓޲্Λࢧ͑ͨͭͷϊ΢ϋ΢ɿ --%#Λ࢖͍͜ͳ͢ σόοάͷλΠϛϯάΛมߋ௚ޙʹ͢Δ ෆ҆ۦಈͰηϧϑνΣοΫ͢Δ ಈ࡞֬ೝΛࣗಈԽ͢Δ ؒҧ͍ʹ͍͘ઃܭʹ͢Δ    

    
  11. ͜ͷൃදͷޙ൒͔Β͸ɺσόοάࣗମͷϊ΢ϋ΢ͷ
 આ໌ΑΓ΋ɺߴ౓ͳσόοάΛඞཁͱ͠ͳ͍ͨΊͷ
 ϊ΢ϋ΢ͷઆ໌͕ओʹͳ͍͖ͬͯ·͢ ͜͏ͨ͠ҙਤ͸ɺσόοά͸ඇޮ཰తͳ࡞ۀͰ͋Γɺ
 σόοάͷස౓ΛԼ͛Δ͜ͱ͕ͦ͜σόοάʹର͢Δ
 ༗ޮͳྟΈํͩͱ͍͏ࢲͷ৴೦͔Β͖͍ͯ·͢ ஫ҙॻ͖

  12. ϊ΢ϋ΢ͷ঺հ ։ൃ଎౓Λ޲্ͤ͞Δ

  13. --%#Λ࢖͍͜ͳ͢ Φεεϝ౓ʜ ϊ΢ϋ΢

  14. σόοάͷ࣌ؒͰϦϏϧυʹ
 ͔͔͍ͬͯΔ࣌ؒ͸গͳ͘ͳ͍ ϦϏϧυΛආ͚ΒΕΕ͹
 σόοά࣌ؒΛ୹ॖͰ͖Δ

  15. --%#ͱ͍͏σόοάπʔϧΛۦ࢖ͯ͠
 ࣍ͷͭͷํ๏ͰϦϏϧυΛආ͚ΒΕΔɿ ίʔϧελοΫΛḪΔ ϦϏϧυͳ͠Ͱ࠶࣮ߦ͢Δ ىಈͨ͠··ঢ়ଶΛมߋ͢Δ " # $

  16. ϊ΢ϋ΢ʵ" ίʔϧελοΫΛḪΔ CSFBLQPJOUΛ࢖͏໨తͷͭ͸ɺ͋Δ࣌఺ͷ
 ม਺ͳͲΛ֬ೝ͢Δ͜ͱ Կ͔͓͔͚͠Ε͹ɺ΋͏গ͠աڈʹḪͬͯ
 ม਺Λ֬ೝ͢Δ͜ͱʹͳΔ ͜ΕΛCSFBLQPJOUͷషΓ௚͠ͱ
 ϦϏϧυͰ΍Δͱ͕͔͔࣌ؒΔ

  17. ίʔϧελοΫʹ࢒͍ͬͯΔม਺ͳΒɺ
 ϦϏϧυ͠ͳ͍Ͱ΋֬ೝͰ͖Δ ࣮͸

  18. ίʔϧελοΫͱ͸ʜʁ

  19. func foo(_ fooArg: Int) { let fooVar = fooArg +

    5 bar(fooVar) } func bar(_ barArg: Int) { let barVar = barArg * 7 baz(barVar) } func baz(_ bazArg: Int) { let bazVar = "\(bazArg)" print(bazVar) } ᶃؔ਺Λ࣮ߦ ίʔϧελοΫ
  20. func foo(_ fooArg: Int) { let fooVar = fooArg +

    5 bar(fooVar) } func bar(_ barArg: Int) { let barVar = barArg * 7 baz(barVar) } func baz(_ bazArg: Int) { let bazVar = "\(bazArg)" print(bazVar) } ίʔϧελοΫ Ҿ਺ ϩʔΧϧม਺ GPP"SH GPP7BS GPPؔ਺ ؔ਺͕ݺͼग़͞ΕΔͱɺ
 ελοΫϑϨʔϜ͕࡞੒͞Εɺ
 ίʔϧελοΫʹੵ·ΕΔ
  21. func foo(_ fooArg: Int) { let fooVar = fooArg +

    5 bar(fooVar) } func bar(_ barArg: Int) { let barVar = barArg * 7 baz(barVar) } func baz(_ bazArg: Int) { let bazVar = "\(bazArg)" print(bazVar) } ᶄ಺෦Ͱؔ਺Λ࣮ߦ ίʔϧελοΫ Ҿ਺ ϩʔΧϧม਺ GPP"SH GPP7BS GPPؔ਺
  22. func foo(_ fooArg: Int) { let fooVar = fooArg +

    5 bar(fooVar) } func bar(_ barArg: Int) { let barVar = barArg * 7 baz(barVar) } func baz(_ bazArg: Int) { let bazVar = "\(bazArg)" print(bazVar) } ίʔϧελοΫ Ҿ਺ ϩʔΧϧม਺ GPP"SH GPP7BS GPPؔ਺ Ҿ਺ ϩʔΧϧม਺ CBS"SH CBS7BS CBSؔ਺ ݺͼग़͞Εͨؔ਺ͷதͰ
 ͞Βʹผͷؔ਺͕ݺ͹Εͯ΋
 ίʔϧελοΫʹੵ·ΕΔ
  23. func foo(_ fooArg: Int) { let fooVar = fooArg +

    5 bar(fooVar) } func bar(_ barArg: Int) { let barVar = barArg * 7 baz(barVar) } func baz(_ bazArg: Int) { let bazVar = "\(bazArg)" print(bazVar) } ᶅ͞Βʹ಺෦Ͱؔ਺Λ࣮ߦ ίʔϧελοΫ Ҿ਺ ϩʔΧϧม਺ GPP"SH GPP7BS GPPؔ਺ Ҿ਺ ϩʔΧϧม਺ CBS"SH CBS7BS CBSؔ਺
  24. func foo(_ fooArg: Int) { let fooVar = fooArg +

    5 bar(fooVar) } func bar(_ barArg: Int) { let barVar = barArg * 7 baz(barVar) } func baz(_ bazArg: Int) { let bazVar = "\(bazArg)" print(bazVar) } ίʔϧελοΫ Ҿ਺ ϩʔΧϧม਺ GPP"SH GPP7BS GPPؔ਺ Ҿ਺ ϩʔΧϧม਺ CBS"SH CBS7BS CBSؔ਺ Ҿ਺ ϩʔΧϧม਺ CB["SH CB[7BS CB[ؔ਺ ίʔϧελοΫʹੵ·ΕΔ
  25. func foo(_ fooArg: Int) { let fooVar = fooArg +

    5 bar(fooVar) } func bar(_ barArg: Int) { let barVar = barArg * 7 baz(barVar) } func baz(_ bazArg: Int) { let bazVar = "\(bazArg)" print(bazVar) } ᶆϒϨʔΫϙΠϯτͰࢭΊΔ ίʔϧελοΫ Ҿ਺ ϩʔΧϧม਺ GPP"SH GPP7BS GPPؔ਺ Ҿ਺ ϩʔΧϧม਺ CBS"SH CBS7BS CBSؔ਺ Ҿ਺ ϩʔΧϧม਺ CB["SH CB[7BS CB[ؔ਺
  26. func foo(_ fooArg: Int) { let fooVar = fooArg +

    5 bar(fooVar) } func bar(_ barArg: Int) { let barVar = barArg * 7 baz(barVar) } func baz(_ bazArg: Int) { let bazVar = "\(bazArg)" print(bazVar) } ίʔϧελοΫ Ҿ਺ ϩʔΧϧม਺ GPP"SH GPP7BS GPPؔ਺ Ҿ਺ ϩʔΧϧม਺ CBS"SH CBS7BS CBSؔ਺ Ҿ਺ ϩʔΧϧม਺ CB["SH CB[7BS CB[ؔ਺ ࢭ·ͬͨ࣌ʹݟ͍͑ͯΔ΋ͷ
  27. func foo(_ fooArg: Int) { let fooVar = fooArg +

    5 bar(fooVar) } func bar(_ barArg: Int) { let barVar = barArg * 7 baz(barVar) } func baz(_ bazArg: Int) { let bazVar = "\(bazArg)" print(bazVar) } ίʔϧελοΫ Ҿ਺ ϩʔΧϧม਺ GPP"SH GPP7BS GPPؔ਺ Ҿ਺ ϩʔΧϧม਺ CBS"SH CBS7BS CBSؔ਺ Ҿ਺ ϩʔΧϧม਺ CB["SH CB[7BS CB[ؔ਺ ࣮͸શ෦--%#͔ΒݟΒΕΔ
  28. 9DPEF "QQ$PEF ίʔϧελοΫͷḪΓํ ͕͜͜ίʔϧελοΫ

  29. 9DPEF "QQ$PEF ݟ͍ͨελοΫϑϨʔϜΛબ΂Δ ίʔϧελοΫͷḪΓํ

  30. 9DPEF "QQ$PEF ͦͷ࣌఺ͷม਺΍Ҿ਺ΛݟΒΕΔ ίʔϧελοΫͷḪΓํ

  31. ϊ΢ϋ΢ʵ# ϦϏϧυͳ͠Ͱ࠶࣮ߦ͢Δ ίʔϧελοΫΛḪΔํ๏Ͱ͸ɺ͢Ͱʹ
 ࣮ߦ͕ऴΘͬͯ͠·ͬͨؔ਺ͷม਺ΛݟΒΕͳ͍ ͦͷ৔߹͸࠶࣮ߦ͠ͳ͚Ε͹ͳΒͳ͍͕ɺίʔυʹ
 มߋΛՃ͍͑ͯͳ͚Ε͹ϦϏϧυ͠ͳ͍Ͱ
 ࠶࣮ߦͨ͠΄͏͕࣌ؒΛઅ໿Ͱ͖Δ

  32. 9DPEF ϦϏϧυͳ͠ͷ࠶࣮ߦͷ΍Γํ "QQ$PEF ᶃϏϧυઃఆฤू ᶄ࠶࣮ߦ͍ͨ͠
 ઃఆΛίϐʔ ᶅ#VJMEΛ࡟আ ᶆ࡞੒ͨ͠ઃఆΛ࣮ߦ ΞϓϦΛ࠶ىಈͯ͠
 "UUBDIUP1SPDFTTͰ΋


    ࣅͨΑ͏ͳ͜ͱΛͰ͖·͢ ผͷํ๏
  33. ϊ΢ϋ΢ʵ$ ىಈͨ͠··ঢ়ଶΛมߋ͢Δ ม਺ͷ಺༰Λॻ͖׵͑Δ͚ͩͳΒɺ
 ϦϏϧυͳ͠Ͱ΋Մೳ ίʔυม਺ͷ಺༰ΛҰ࣌తʹॻ͖׵͑ͯ
 ಈ࡞Λ͔֬Ί͍ͨ৔߹ʹศར σβΠφʔͱͷ࣮ػ֬ೝͳͲͰ
 Α͘ॏๅͨ͠ςΫχοΫ

  34. มߋΛ࢝ΊΔͨΊͷҰ࣌ఀࢭͷ΍Γํ 9DPEF "QQ$PEF

  35. --%#ͷೖྗΠϯλʔϑΣʔεΛ֬ೝ 9DPEF "QQ$PEF --%#ͷίϚϯυϥΠϯΠϯλʔϑΣʔε͕ىಈ͢Δ

  36. (lldb) help Debugger commands: apropos -- List debugger commands related

    to a breakpoint -- Commands for operating on breakpoint shorthand.) ... IFMQΛ࣮ߦ͢Δͱɺ࣮ߦͰ͖Δૢ࡞ͷҰཡ͕දࣔ͞ΕΔ
  37. (lldb) help po
 Evaluate an expression on the current
 thread.

    Displays any returned value
 with formatting controlled by the type's
 author. Expects 'raw' input (see 'help
 raw-input'.) ࠓճ͸--%#ܦ༝ͰίʔυΛ࣮ߦ͢ΔQPΛ࢖͏ ҙ༁: ݱࡏͷεϨουͰίʔυΛධՁ͠ɺ݁Ռͷ
 ஋ΛਓؒʹಡΈ΍͍͢ܗͰදࣔ͠·͢ɻ
  38. (lldb) po print("Hello, World") error: use of undeclared identifier 'print'

    QPίϚϯυͰ)FMMP 8PSMEΛදࣔͯ͠ΈΑ͏ "QQ$PEFͷਓ͸͜ͷΤϥʔ͕ग़ͳ͍͔΋
  39. ݱࡏͷελοΫϑϨʔϜΛ֬ೝ 9DPEF "QQ$PEF 4XJGUͷελοΫϑϨʔϜ΁Ҡಈ ࠷ॳ͔Β4XJGUͷελοΫϑϨʔϜΛ
 બ୒ͯ͘͠Ε͍ͯΔ͜ͱ͕ଟ͍

  40. (lldb) po print("Hello, World") Hello, World ΋͏Ұ౓QPίϚϯυͰ)FMMP 8PSMEΛදࣔͯ͠ΈΑ͏ ͏·࣮͘ߦͰ͖ͨ

  41. QPίϚϯυΛ࢖͏ͱɺىಈதͷΞϓϦͷ
 ద౰ͳ6*7JFXͷঢ়ଶΛม͑ΒΕΔ ͜ͷදࣔจࣈྻΛม͑ͯΈΑ͏

  42. (lldb) po UIApplication.shared.keyWindow!
 .value(forKey: "recursiveDescription")! <UIWindow: 0x7fbee05517b0; frame = (0

    0; 320 568); autoresize = W+H; g | <UIView: 0x7fbee0719bc0; frame = (0 0; 320 568); autoresize = W+H | | <UIView: 0x7fbee071daf0; frame = (31.5 247.5; 257 93); autor | | | <UIButton: 0x7fbee050de30; frame = (48.5 53; 160 40); o | | | | <UIButtonLabel: 0x7fbee0773930; frame = (4 6.5; 15 | | | <UILabel: 0x7fbee0610fe0; frame = (4 0; 250 37); text = | | | | <_UILabelContentLayer: 0x6040006336e0> (layer) ·ͣɺදࣔ͞Ε͍ͯΔ6*7JFXͷҰཡΛදࣔ
  43. (lldb) po UIApplication.shared.keyWindow!
 .value(forKey: "recursiveDescription")! <UIWindow: 0x7fbee05517b0; frame = (0

    0; 320 568); autoresize = W+H; g | <UIView: 0x7fbee0719bc0; frame = (0 0; 320 568); autoresize = W+H | | <UIView: 0x7fbee071daf0; frame = (31.5 247.5; 257 93); autor | | | <UIButton: 0x7fbee050de30; frame = (48.5 53; 160 40); o | | | | <UIButtonLabel: 0x7fbee0773930; frame = (4 6.5; 15 | | | <UILabel: 0x7fbee0610fe0; frame = (4 0; 250 37); text = | | | | <_UILabelContentLayer: 0x6040006336e0> (layer) දࣔ͞Ε͍ͯΔΫϥεͷܕ΍ϝϞϦΞυϨεΛೖखͰ͖Δ
  44. (lldb) po let $label = unsafeBitCast(0x7fbee0610fe0, to: UILabel.self) ܕͱϝϞϦΞυϨε͕Θ͔ΔͱɺunsafeBitCastͰ
 ΠϯελϯεΛऔಘͰ͖Δ

  45. (lldb) po let $label = unsafeBitCast(0x7fbee0610fe0, to: UILabel.self) ม਺΍ؔ਺ͳͲͷએݴΛ͢Δ৔߹͸ɺ໊લΛ͔Β࢝Ίͳ͍ͱແࢹ͞ΕΔͷͰ஫ҙ

  46. (lldb) po $label <UILabel: 0x7fbee0610fe0; frame = (4 0; 250

    37); text ΠϯελϯεΛऔಘͰ͖͔ͨͲ͏͔֬ೝͯ͠ΈΑ͏
  47. (lldb) po $label.text = "Hello, World!" $label ͷςΩετΛॻ͖׵͑ͯΈΑ͏

  48. ΞϓϦͷ࣮ߦΛ࠶։͢Δ΍Γํ 9DPEF "QQ$PEF

  49. UILabelͷද͕ࣔมΘͬͨʂ

  50. 5*14 ελοΫϑϨʔϜΛม͑ΔҎ֎ͷํ๏ ઌ΄Ͳ͸ελοΫϑϨʔϜΛ4XJGUͷ΋ͷʹ
 ߹Θͤͳ͍ͱΤϥʔʹͳ͍ͬͯͨ ࣮͸ɺԼͷΑ͏ʹ࣮ߦ͢ΔͱɺελοΫϑϨʔϜΛ
 ม͑ͳͯ͘΋Τϥʔ͸ൃੜ͠ͳ͍ ҙຯ͸help expr Ͱௐ΂ͯΈΑ͏ (lldb)

    expr -l swift -o -- print("Hello, World") ൃ ද Ͱ ͸ ׂ Ѫ
  51. ݟͨ໨ͷมߋΛ΋ͬͱ؆୯ʹ 3FWFBMͱ͍͏ΞϓϦʢ༗ྉʣ͕ͱͯ΋ศར
 'SFF5SJBM͕͋ΔͷͰɺࢼͯ͠ΈΔͱ͍͍͔΋ʁ ྫ͑͹6*-BCFMͷ
 ςΩετΛม͑ΒΕΔ ಛʹ"VUP-BZPVUͷ
 σόοάʹॏๅ͢Δ https://revealapp.com 5*14 ൃ

    ද Ͱ ͸ ׂ Ѫ
  52. ϊ΢ϋ΢ͷ·ͱΊ σόοΨΛ࢖͏ͱͭͷํ๏Ͱ
 ϦϏϧυΛආ͚ΒΕΔɿ ίʔϧελοΫΛḪΔ ϦϏϧυͳ͠Ͱ࠶࣮ߦ͢Δ ىಈͨ͠··ঢ়ଶΛมߋ͢Δ " # $

  53. σόοάͷλΠϛϯάΛ
 มߋ௚ޙʹ͢Δ ϊ΢ϋ΢ Φεεϝ౓ʜ

  54. ݪҼͷજΉൣғΛߜΓࠐΉͷ΋
 σόοά࣌୹ͷ༗ޮͳςΫχοΫ

  55. GVODDMBTTTUSVDUFOVNͱ͍ͬͨ
 খ͞ͳ୯Ґͷ࣮૷௚ޙʹσόοάΛ
 ͢Ε͹ɺݪҼ͸௚લͷൣғʹߜΒΕΔ ۩ମతʹ͸

  56. ॏཁͳͷ͸ɺมߋͱ֬ೝͷαΠΫϧΛ
 ͳΔ΂͘୹ִ͍ؒͰճͤΔΑ͏ʹอͭ͜ͱ ίʔυͷ
 มߋ ಈ࡞֬ೝ

  57. struct Example { static func intToString(_ i: Int?) -> String

    { let x: Int! = i return "\(x)" } } ྫ͑͹ɺ੔਺Λਐ਺දهͷจࣈྻ΁
 ม׵͢ΔίʔυΛ࣮૷ͨ͠ͱ͢Δ ྫ͑͹ɺΛҾ਺ʹ͢Ε͹ɺਐ਺
 จࣈྻͰ͋Δ͕ฦ͖ͬͯͯ΄͍͠
  58. ผͷίʔυͰ࢖͏લʹ--%#Ͱಈ࡞Λ֬ೝ͠Α͏ ʢ--%#͸ΞϓϦͷҰ࣌ఀࢭͰىಈͰ͖Δʣ (lldb) po Example.intToString(42)

  59. (lldb) po Example.intToString(42) "Optional(42)" 

  60. struct Example { static func intToString(_ i: Int?) -> String

    { let x: Int! = i return "\(x)" } } όάΛݟ͚ͭͨΒ௚લͷ࣮૷Օॴʹ໭Ζ͏
  61. struct Example { static func intToString(_ i: Int?) -> String

    { let x: Int = i! return "\(x)" } } Int!ΛจࣈྻԽ͢Δͱ"Optional(...)"ʹ
 ͳͬͯ͠·͏ͷͰɺIntʹͳΔΑ͏मਖ਼͢Δ
  62. struct Example { static func intToString(_ i: Int?) -> String

    { let x: Int! = i return "\(x)" } } ࣮૷௚ޙʹσόοάͨ͠ͷͰɺ
 ݪҼՕॴ͕͙ۙ͘͢ʹݟ͔ͭͬͨ
  63. मਖ਼ͨ͠Βɺ·͙ͨ͢ʹಈ࡞֬ೝ͠Α͏ (lldb) po Example.intToString(42) "42" ࠓ౓͸େৎ෉ͦ͏ͩ

  64. 5*14 --%#ͰCSFBLQPJOUΛޮ͔ͤΔํ๏ --%#ͷpo΍exprʹΑΔ࣮ߦͰCSFBLQPJOU͕
 ޮ͔ͳͯ͘ࠔΔ͜ͱ͕͋Δ ͦ͜Ͱɺexprͷ-iΦϓγϣϯΛfalseʹ͢Δͱɺ
 --%#͔Βͷ࣮ߦͰ΋CSFBLQPJOU͕ޮ͘Α͏ʹͳΔ (lldb) expr -l swift

    -o -i false -- Example.intToString(42) ൃ ද Ͱ ͸ ׂ Ѫ
  65. ϊ΢ϋ΢ͷ·ͱΊ ͳΔ΂͘୹͘ૉૣ͘ճ͢ ίʔυͷ
 มߋ ಈ࡞֬ೝ

  66. ෆ҆ۦಈͰηϧϑνΣοΫ͢Δ ϊ΢ϋ΢ Φεεϝ౓ʜ

  67. Α͋͘Δ։ൃ଎౓௿ԼͷݪҼ͸ख໭Γ ࣗ෼ͷಈ࡞֬ೝ͕ෆ׬શͩͬͨΓɺ
 ࢥ͍΋͔ͭͳ͍όά͕͋ͬͨΓ͢Δͱ
 σόοά·Ͱख໭Γͯ͠͠·͏

  68.  ͕࣌ؒܦͭ΄ͲݪҼ͕Θ͔Βͳ͘ͳΔ  ༨ܭͳίϛϡχέʔγϣϯ͕૿͑Δ  కΊ੾Γ௒աͷ࠷ޙͷҰԡ͠͸͍͍ͩͨख໭Γ ख໭ΓʹΑͬͯੜ͡Δ໰୊

  69. ͕࣌ؒܦͭ΄ͲݪҼ͕Θ͔Βͳ͘ͳΔ ͜ΕมͳͷͰݟͯ΋Β͑·͢ʁ ઌि࣮૷ͨ͠΍͚ͭͩͲ
 ͲΜͳײ͡ʹ͚ͨͬ͠ʜʁ ಈ࡞֬ೝ୲౰ ࣮૷ऀ

  70. ༨ܭͳίϛϡχέʔγϣϯ͕૿͑Δ ͜Εόάͬͯ·ͤΜ͔ʁ खॱΛڭ͑ͯ΋Β͑·͔͢ʁ ͑ʔͱɺ"Λ#͔ͯ͠Βʜ ಈ࡞֬ೝ୲౰ ࣮૷ऀ

  71. కΊ੾Γ௒աͷ࠷ޙͷҰԡ͠͸͍͍ͩͨख໭Γ ࣮૷ ࣮૷ ࣮૷ ϨϏϡʔ ϨϏϡʔ ϨϏϡʔ ಈ࡞֬ೝ ख໭ΓରԠ ಈ࡞֬ೝ

    ਓ਺Ͱεέʔϧ͠ͳ͍ $͞Μ ,VOJXBL "͞Μ #͞Μ
  72. ͳΔ΂ࣗ͘෼ͰόάΛݟ͚ͭͯɺ
 ख໭ΓΛݮΒ͍ͯ͘͜͠ͱ͕ॏཁ ଟগ͕͔͔࣌ؒͬͨͱͯ͠΋ɺ
 ͋ͱͰݟ͔ͭΔΑ͏ͳόάͰ
 ख໭Γ͠ͳ͚Ε͹શମతͳ
 ࣌ؒ͸Ή͠ΖݮΔ ͭ·Γ

  73. Ͳ͜·ͰΛηϧϑνΣοΫ͢Δ͔ ͱ͸͍͑

  74. ͜ͷ··ಥ͖ਐΉͱɺ͢΂ͯͷόάΛ
 શ෦ࣗ෼Ͱݟ͚ͭΔ͜ͱʹͳͬͯ
 ͠·Θͳ͍ͩΖ͏͔ʁ ͦΕ͸ਖ਼͍͠ํ਑ͳͷͩΖ͏͔ʁ

  75. ࣗ෼ͰશͯΛݟ͚ͭΔ ख໭Γ࠷খ

  76. ಈ࡞֬ೝ୲౰ͷਓͷ࣌ؒΛ
 ༗ޮ׆༻Ͱ͖ͳ͍ ख໭Γ࠷খ ෼ۀ࠷খ 

  77. ࣮૷͚ͩʹઐ೦͢Δ ख໭Γ࠷খ ෼ۀ࠷খ  ෼ۀ࠷େ

  78. ։ൃ͕࣌ؒ৳ͼΔ ख໭Γ࠷খ ෼ۀ࠷খ  ෼ۀ࠷େ ख໭Γ࠷େ 

  79. ख໭Γ࠷খ ෼ۀ࠷খ  ෼ۀ࠷େ ख໭Γ࠷େ  ͲͪΒ΋ۃ୺ʹ͢Ε͹͕࣌ؒ૿͑ͯ͠·͏

  80. Ͳ͔͜ͷଥڠ఺Λ
 બ͹ͳ͍ͱ͍͚ͳ͍ ͱ͍͏͜ͱ͸

  81. ීวతʹ࠷దͳ
 ଥڠ఺͸ଘࡏ͠ͳ͍ ͔͠͠

  82. ͢΂ͯͷෆ҆ͳߦΛҰ౓͸
 ௨ա͢Δఔ౓Λ໨҆ʹͨ͠ ͦ͜ͰɺࢲͷࣄྫͰ͸

  83. ෆ҆ͳίʔυͷྫ struct Example { static func intToString(_ i: Int?) ->

    String { let x: Int! = i return "\(x)" } } ͨͱ͑͹ɺઌ΄Ͳͷ୹͍ίʔυͷதʹ΋
 ෆ҆ͳ৔ॴ͕͋ͬͨ ࢲͷෆ҆ϙΠϯτ
  84. "\(x)"͸ͱ͖Ͳ͖৴༻ͷͳΒͳ͍ڍಈΛ͢Δ Int?ͩͱμϝʹͳΔͷ͸༗໊ͳͷͰ
 ஌͍͕ͬͯͨɺInt!Ͱ΋ಉ͡Α͏ʹ
 μϝͳͷ͔Ͳ͏͔֬৴Λ΋ͯͳ͔ͬͨ ͦ͏͍͏࣌͸ɺ--%#ͳͲͰ
 ࣮ࡍʹಈ͔͔ͯ֬͠ΊΑ͏ --%#Ҏ֎ͷํ๏͸ϊ΢ϋ΢Ͱ΋঺հ

  85. w සൟʹ௨ա͢Δ෼ذʢ͜͜ʹόά͕͋Δͱਃ͠༁ͳ͍ʣ if (x < 0)ͷ෼ذͰxʹͲΜͳ΋ͷ͕དྷΔ͔
 Θ͔Βͳ͍ͳΒɺগͳ͘ͱ΋ਖ਼ͱෛͷ྆ํΛࢼ͢ w ෼ذ৚݅ͷڥ໨ x

    < 0ͳΒڥ໨͸ɺ഑ྻ͸ۭͷͱ͖ʹڥ໨ʹͳΓ΍͍͢
 DoubleͳΒ+0 -0 +infinity -infinity nanͳͲ w ཧղͰ͖͍ͯͳ͍ίϯϙʔωϯτͷར༻ ྫ͑͹ɺඪ४ϥΠϒϥϦͷ6*5BCMF7JFX͸࢖͍ํ͕
 ͱͯ΋ෳࡶͳͷͰ͍ͭ΋ؒҧ͑ͯ͠·͏ ࢲͷ࠷ۙͷෆ҆ϙΠϯτ ൃ ද Ͱ ͸ ׂ Ѫ
  86. ։ൃऀͷෆ҆͸ɺաڈʹࣗ਎͕౿Μͩ
 όάͷܦݧΛ൓ө͍ͯ͠Δ͔Β ͔͠͠ɺͳͥෆ҆ͱ͍͏ج४ͳͷ͔ʁ

  87. ෆ҆ΛΞοϓσʔτ͠ଓ͚Δ͜ͱͰ
 ͦͷݱ৔ʹదͨ͠ଥڠ఺΁͍͍͚ۙͮͯΔ ෆ͕࣮҆ࡍͷόάͷ܏޲ʹ
 ݁ͼͭ͘Α͏ʹײ֮Λ
 ߋ৽͠ଓ͚Α͏

  88. ϊ΢ϋ΢ͷ·ͱΊ ෆ͕҆ͳ͘ͳΔ·Ͱ
 ηϧϑνΣοΫ͠Α͏ ෆ҆ͷਫ਼౓Λ্͍͛ͯ͜͏

  89. ಈ࡞֬ೝΛࣗಈԽ͢Δ ϊ΢ϋ΢ Φεεϝ౓ʜ

  90. ϊ΢ϋ΢Λଥڠͤͣʹ
 ࣮ફ͢Δͷ͸͔ͳΓ೉͍͠ ͳͥͳΒɺෆ҆Λײ͡ΔՕॴ͸
 ࢥͬͨΑΓଟ͍͔Β ͢Δͱ్தͰଥڠ͕ͪ͠ʹͳΓɺ
 ख໭Γ͕ࢥͬͨΑΓ
 ݮΒͳ͘ͳΔ

  91. Ͳ͜·Ͱ֬ೝ͢Ε͹҆৺Ͱ͖ΔͩΖ͏ʁ ཧ૝తͳൣғΛ૝૾ͯ͠ΈΑ͏

  92. ࢲʹͱͬͯͷཧ૝తͳಈ࡞֬ೝ Өڹ͞ΕΔίϯϙʔωϯτ
 ͢΂ͯͬͯແཧͰ͸ʜʁ ͜Ε͸Ͱ͖ͦ͏ w ͦΕҎ֎ʹӨڹ͢Δίϯϙʔωϯτ΋
 ͢΂ͯ֬ೝ͠ͳ͍ͱຊདྷ͸·͍ͣ w ࣮૷मਖ਼ͨ͠ίϯϙʔωϯτΛ
 ֬৴Ͱ͖ΔϨϕϧ·Ͱ֬ೝ

  93. w ͕͔͔࣌ؒΓ͗͢Δ w Өڹ͢Δίϯϙʔωϯτͷಈ࡞֬ೝͷ
 ࢓ํΛ͍֮͑ͯΔ͸͕ͣͳ͍ Өڹ͢ΔίϯϙʔωϯτΛ͢΂ͯ֬ೝ͢Δ
 ͱ͖ͷΑ͋͘Δ໰୊఺ɿ ͋Εʁ͜ͷڍಈͰ͋ͬͯΔΜ͚ͩͬʜʁ ਖ਼͍͠Ҿ਺ͬͯͲ͏΍ͬͯ࡞ΔΜ͚ͩͬʁ

  94. ಈ࡞֬ೝΛࣗಈԽ͠Α͏ ͦ͏͍͏ͱ͖͸

  95. ίʔυͷಈ࡞֬ೝΛࣗಈԽ͢Δར఺ɿ w ܁Γฦ࣮͠ߦ͢Δίετ͕௿͍ͷͰ
 ࣌ؒ͸ͦ͜·Ͱ͔͔Βͳ͘ͳΔ w ૢ࡞֬ೝͷखॱ͕ίʔυͱͯ͠
 ࢒͞ΕΔͷͰ΍ΓํΛ๨Εͳ͍

  96. ಈ࡞֬ೝΛࣗಈԽ͢Δͭͷํ๏ɿ ಈ࡞֬ೝͷͨΊͷඪ४ϥΠϒϥϦΛ
 ࢖ͬͯಈ࡞֬ೝ "QQ%FMFHBUFܦ༝Ͱಈ࡞֬ೝ " #

  97. ϊ΢ϋ΢ʵ" "QQ%FMFHBUFͰಈ࡞֬ೝ  ಈ࡞֬ೝͷίʔυΛॻ͘  ৽͍͠4DIFNFΛ࡞੒͢Δ  "QQ%FMFHBUFͰͷ
 4DIFNFͷͱ͖͚ͩΛ
 ࣮ߦ͢ΔΑ͏ʹ͢Δ

    ͨͩܽ͠఺͕ଟ͍ͷͰɺൃදͰ͸ׂѪ͠·͢
  98. #if DEBUG import Foundation let debugTargets: [String: () -> Void]

    = [ "intToString": { let string = Example.intToString(42) guard string == "48" else { fatalError("intToString(42) ͕ \"42\" Λฦ͞ͳ͔ͬͨ") } }, ] func debugAll() { let targets = Array(debugTargets.values) DispatchQueue.concurrentPerform(iterations: targets.count) { index in targets[index]() } } #endif ಈ࡞֬ೝͷίʔυΛ·ͱΊΔ%JDUJPOBSZΛ࡞੒͢Δ ൃ ද Ͱ ͸ ׂ Ѫ
  99. #if DEBUG import Foundation let debugTargets: [String: () -> Void]

    = [ "intToString": { let string = Example.intToString(42) guard string == "42" else { fatalError("intToString(42) ͕ \"42\" Λฦ͞ͳ͔ͬͨ") } }, ] func debugAll() { let targets = Array(debugTargets.values) DispatchQueue.concurrentPerform(iterations: targets.count) { index in targets[index]() } } #endif ಈ࡞֬ೝͷίʔυΛॻ͘ ͜ͷίʔυ͸ɺintToString(42)ͷ
 ݁Ռ͕"42"ʹͳΔ͜ͱΛ֬ೝ͍ͯ͠Δ ൃ ද Ͱ ͸ ׂ Ѫ
  100. #if DEBUG import Foundation let debugTargets: [String: () -> Void]

    = [ "intToString": { let string = Example.intToString(42) guard string == "48" else { fatalError("intToString(42) ͕ \"42\" Λฦ͞ͳ͔ͬͨ") } }, ] func debugAll() { let targets = Array(debugTargets.values) DispatchQueue.concurrentPerform(iterations: targets.count) { index in targets[index]() } } #endif ͢΂ͯͷಈ࡞֬ೝίʔυΛ࣮ߦ͢Δ
 EFCVH"MMؔ਺Λ࣮૷͢Δ ൃ ද Ͱ ͸ ׂ Ѫ
  101. ৽͍͠4DIFNFΛ࡞੒͢Δ΍Γํ 9DPEF ᶃ4DIFNFΛ࡞੒ ᶄద౰ͳ໊લΛ͚ͭΔ ൃ ද Ͱ ͸ ׂ Ѫ

  102. ৽͍͠4DIFNFΛ࡞੒͢Δ΍Γํ ᶃϏϧυઃఆΛ։͘ ᶆద౰ͳ໊લΛ͚ͭΔ "QQ$PEF ᶅ"QQMJDBUJPOΛࢦఆ ᶄ4DIFNFΛ࡞੒ ൃ ද Ͱ ͸

    ׂ Ѫ
  103. ؀ڥม਺Λ௥Ճ͢Δ΍Γํ 9DPEF ᶃ4DIFNFΛฤू ᶄ؀ڥม਺Λ௥Ճ "QQ$PEF ᶃ؀ڥม਺Λฤू ᶄ؀ڥม਺Λ௥Ճ ൃ ද Ͱ

    ͸ ׂ Ѫ
  104. ؀ڥઃఆͷ஋Λઃఆ͢Δ΍Γํ 9DPEF ᶃAUTO_DEBUG=1Λઃఆ "QQ$PEF ᶃAUTO_DEBUG=1Λઃఆ ൃ ද Ͱ ͸ ׂ

    Ѫ
  105. @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func

    application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: #if DEBUG if ProcessInfo.processInfo.environment["AUTO_DEBUG"] == "1" { debugAll() return true } #endif // ... return true } } "QQ%FMFHBUFʹ؀ڥม਺ͷ෼ذΛ௥Ճ AUTO_DEBUG=1ͷͱ͖ͷΈɺ
 ઌ΄ͲͷdebugAllΛ࣮ߦ ൃ ද Ͱ ͸ ׂ Ѫ
  106. ΞϓϦΛ࣮ߦͯ͠ΈΑ͏ ͦΕͰ͸ ൃ ද Ͱ ͸ ׂ Ѫ

  107. ΞϓϦΛ࣮ߦ͢Δͱಈ࡞֬ೝͰ͖Δ 9DPEF Ͳ͜Ͱࣦഊ͔ͨ͠Θ͔Δ ࣦഊͨ͠ཧ༝͕Θ͔Δ ൃ ද Ͱ ͸ ׂ Ѫ

  108. ΞϓϦΛ࣮ߦ͢Δͱಈ࡞֬ೝͰ͖Δ "QQ$PEF Ͳ͜Ͱࣦഊ͔ͨ͠Θ͔Δ ࣦഊͨ͠ཧ༝͕Θ͔Δ ൃ ද Ͱ ͸ ׂ Ѫ

  109. 5*14 ࢦఆͨ͠ίʔυ͚ͩಈ࡞֬ೝ ݸผͷಈ࡞֬ೝ͚ͩΛ࣮ߦ͍ͨ͜͠ͱ͸Α͋͘Δ ͦ͏͍͏৔߹͸ɺ--%#͔Β໊લΛࢦఆͯ͠ݸผʹ
 ಈ࡞֬ೝΛ࣮ߦͰ͖Δ ಈ࡞֬ೝͷίʔυΛ഑ྻͰ͸ͳ͘%JDUJPOBSZʹ
 ֨ೲͨ͠ͷ͸͜Ε͕໨త (lldb) po debugTargets["intToString"]!()

    Fatal error: intToString(42) ͕ "42" Λฦ͞ͳ͔ͬͨ: ൃ ද Ͱ ͸ ׂ Ѫ
  110. "QQ%FMFHBUFͷํ๏ͷ໰୊఺ɿ w ෳ਺ͷಈ࡞֬ೝ͕ࣦഊ͢Δͱɺઌʹ
 ࣮ߦ͞Εͨํ͔͠೺ѲͰ͖ͳ͍ w fatalErrorΛprint΁ม͑Ε͹
 ෳ਺ͷࣦഊΛ೺ѲͰ͖ΔΑ͏ʹ
 ͳΔ͕ɺࠓ౓͸ࣦഊͨ͠ࡍʹ*%&͕
 δϟϯϓͯ͘͠Εͳ͍ͷͰෆศ ͜ΕΒͷ໰୊͸ඪ४ϥΠϒϥϦͰղܾͰ͖·͢

  111. ϊ΢ϋ΢ʵ# ඪ४ϥΠϒϥϦͰಈ࡞֬ೝ  ৽͍͠5BSHFUΛ࡞੒͢Δ  ಈ࡞֬ೝͷίʔυΛॻ͘  ಈ࡞֬ೝͷίʔυͷ5BSHFUΛ
 ઌ΄Ͳ࡞੒ͨ͠΋ͷʹ͢Δ J04ʹ͸ಈ࡞֬ೝ༻ͷඪ४ϥΠϒϥϦʮ9$5FTUʯ͕


    ༻ҙ͞Ε͍ͯΔ ͜ΕͰ"QQ%FMFHBUFʹ͋ͬͨෳ਺ࣦഊͨ͠ͱ͖ͷ
 ໰୊ΛղܾͰ͖Δ͕ɺ࣍ͷΑ͏ͳϏϧυઃఆ͕ඞཁɿ
  112. Ϗϧυઃఆͷ΍Γํ 9DPEF ᶃ5BSHFUΛ৽ن࡞੒ ᶅඞཁ߲໨Λهೖ ᶄJ046OJU5FTUJOH#VOEMFΛબ୒ ൃ ද Ͱ ͸ ׂ

    Ѫ
  113. ᶃ1SPKFDU4FUUJOHTΛ։͘ ᶄ5BSHFUΛ௥Ճ ᶅJ046OJU5FTUJOH#VOEMFΛબ୒ Ϗϧυઃఆͷ΍Γํ "QQ$PEF ൃ ද Ͱ ͸ ׂ

    Ѫ
  114. Ϗϧυઃఆͷ΍Γํ 9DPEF ᶆ5FTUJOHΛ࣮ߦ ᶇ5FTU4VDDFFEFE͕දࣔ͞ΕΕ͹0, ൃ ද Ͱ ͸ ׂ Ѫ

  115. ᶇϏϧυઃఆΛฤू ᶈ4DIFNFΛ௥Ճ ᶆඞཁ߲໨Λهೖ Ϗϧυઃఆͷ΍Γํ "QQ$PEF ൃ ද Ͱ ͸ ׂ

    Ѫ
  116. ᶌ"MM5FTUT1BTTFEͱදࣔ͞ΕΕ͹0, ᶉ9$5FTUΛબ୒ ᶊద౰ͳ໊લΛ͚ͭΔ ᶋ࡞੒ͨ͠4DIFNFΛ࣮ߦ Ϗϧυઃఆͷ΍Γํ "QQ$PEF ൃ ද Ͱ ͸

    ׂ Ѫ
  117. ͜ΕͰಈ࡞֬ೝ༻ͷ5BSHFUΛ࡞੒Ͱ͖ͨ

  118. import XCTest @testable import IOSDC2018Debugging class ExampleTest: XCTestCase { func

    testIntToString() { let str = Example.intToString(42) XCTAssertEqual(str, "42") } } ඪ४ϥΠϒϥϦΛ࢖͏৔߹ͷ
 ಈ࡞֬ೝͷίʔυ͸͜͏ͳΔ
  119. import XCTest @testable import IOSDC2018Debugging class ExampleTest: XCTestCase { func

    testIntToString() { let str = Example.intToString(42) XCTAssertEqual(str, "42") } } ಈ࡞֬ೝͷίʔυͷUBSHFU͸
 ઌ΄Ͳ࡞੒ͨ͠UBSHFUʹ͢Δ
  120. 9DPEF ᶃ࡞੒ͨ͠5BSHFUΛબ୒ "QQ$PEF ൃ ද Ͱ ͸ ׂ Ѫ ᶃ.BOBHF5BSHFUTΛબ୒

    ᶄ࡞੒ͨ͠5BSHFUΛબ୒ 5BSHFUͷࢦఆͷ΍Γํ
  121. import XCTest @testable import IOSDC2018Debugging class ExampleTest: XCTestCase { func

    testIntToString() { let str = Example.intToString(42) XCTAssertEqual(str, "42") } } ඪ४ϥΠϒϥϦ9$5FTUΛಡΈࠐΉ ΞϓϦͷίʔυ͸ผͷ5BSHFUͳͷͰ
 ࢖͏ࡍʹ͸import͕ඞཁ ී௨ʹimport͢Δͱpublicͷ΋ͷ͔͠
 ݟ͑ͳ͘ͳͬͯ͠·͏͕ɺ@testableΛͭ ͚Δͱinternal·Ͱݟ͑ΔΑ͏ʹͳΔ
  122. import XCTest @testable import IOSDC2018Debugging class ExampleTest: XCTestCase { func

    testIntToString() { let str = Example.intToString(42) XCTAssertEqual(str, "42") } } ಈ࡞֬ೝͷίʔυ͸XCTestCaseͱ͍͏
 ΫϥεͰάϧʔϐϯάͰ͖ΔΑ͏ʹͳ͍ͬͯΔ ಈ࡞֬ೝͷίʔυΛॻ͘৔߹ʹ͸ɺ֬ೝର৅ͷ
 Ϋϥε΍ؔ਺୯ҐͰXCTestCaseΛ෼͚Δͱ
 ಈ࡞֬ೝͷ݁Ռ͕Θ͔Γ΍͘͢ͳΔ
  123. import XCTest @testable import IOSDC2018Debugging class ExampleTest: XCTestCase { func

    testIntToString() { let str = Example.intToString(42) XCTAssertEqual(str, "42") } } ࣮ࡍͷಈ࡞֬ೝͷίʔυ͸ɺΠϯελϯεϝιουͱ࣮ͯ͠૷͢Δ ͜ͷϝιουͷ໊લ͸ઌ಄ʹtestͱ͚ͭͳ͍ͱ࣮ߦ͞Εͳ͍ͷͰ஫ҙ
  124. import XCTest @testable import IOSDC2018Debugging class ExampleTest: XCTestCase { func

    testIntToString() { let str = Example.intToString(42) XCTAssertEqual(str, "42") } } ಈ࡞֬ೝͷର৅Λ࣮ࡍʹ࣮ߦ͢Δ
  125. import XCTest @testable import IOSDC2018Debugging class ExampleTest: XCTestCase { func

    testIntToString() { let str = Example.intToString(42) XCTAssertEqual(str, "42") } } ਖ਼ޡ൑ఆ͸XCTAssertEqualͳͲͷؔ਺Λ࢖͏ ͜ͷؔ਺͸ɺͭͷҾ਺͕౳͘͠ͳ͍ͱɺ
 ಈ࡞֬ೝΛࣦഊͱΈͳ͢Α͏ʹͳ͍ͬͯΔ
  126. ඪ४ϥΠϒϥϦΛ࢖ͬͨ݁Ռը໘ 9DPEF Ͳ͜Ͱࣦഊ͔ͨ͠Θ͔Δ ࣦഊͨ͠ཧ༝΋Θ͔Δ ෳ਺ͷࣦഊ͕
 ҰཡͰݟΒΕΔ

  127. "QQ$PEF Ͳ͜Ͱࣦഊ͔ͨ͠Θ͔Δ ෳ਺ͷࣦഊ͕
 ҰཡͰݟΒΕΔ ࣦഊͨ͠ཧ༝΋Θ͔Δ ඪ४ϥΠϒϥϦΛ࢖ͬͨ݁Ռը໘ ൃ ද Ͱ ͸

    ׂ Ѫ
  128. ඪ४ϥΠϒϥϦͷํ๏ͷ໰୊఺ɿ w Ϗϧυઃఆ͕յΕ͍ͯΔͱɺ௚͢·Ͱ
 ಈ࡞֬ೝͷίʔυΛ࣮ߦͰ͖ͳ͍ w ઃఆΛ͙͢ʹ͸௚ͤͳͦ͞͏ͳΒɺ
 "QQ%FMFHBUFͷํ๏ΛҰ࣌తʹ
 ࢖͏ͷ΋༗ޮͳखஈ ͋Γ͕ͪͳͷ͕
 Կ͔ͷϥΠϒϥϦͷ


    4FBSDI1BUITͷ
 ઃఆ΋Ε
  129. ϊ΢ϋ΢ͷ·ͱΊ ಈ࡞֬ೝΛࣗಈԽ͢Δͭͷํ๏ɿ ಈ࡞֬ೝͷͨΊͷඪ४ϥΠϒϥϦΛ
 ࢖ͬͯಈ࡞֬ೝ "QQ%FMFHBUFܦ༝Ͱಈ࡞֬ೝ " # #ͷํ͕Φεεϝ͕ͩɺ͙͢ʹ͸೉ͦ͠͏ͳΒҰ࣌తʹ"Ͱ΋0,ʂ

  130. ؒҧ͍ʹ͍͘ઃܭʹ͢Δ ϊ΢ϋ΢ ൃ ද Ͱ ͸ ׂ Ѫ Φεεϝ౓ʜ

  131. σόοάΛͦ΋ͦ΋͍Βͳ͍Α͏ʹͰ͖ΔͳΒ
 ͦΕ͕Ұ൪࣌ؒΛ୹ॖͰ͖Δ ྫͱͯ࣍͠ͷΑ͏ͳ޻෉Λ঺հ͢Δɿ Կ͔ͷ*%Λ௚઀ͷ*OU΍4USJOHʹ͠ͳ͍ ίʔυΛࣗಈੜ੒͢Δ " # ൃ ද Ͱ

    ͸ ׂ Ѫ
  132. ϊ΢ϋ΢ʵ" *%ΛݸผͷTUSVDUʹ͢Δ ΞϓϦΛ࡞੒͍ͯ͠Δͱෳ਺ͷछྨͷ*%Λ
 औΓѻ͏͜ͱ͕ଟ͍ʢ6TFS*%΍$PNNFOU*%ͳͲʣ ͜ͷ*%ΛऔΓҧ͑ͯॲཧͯ͠͠·ͬͨΓ͢Δͱɺ
 ݪҼಛఆ͕େมͳ໘౗ͳόάΛੜΈग़͠΍͍͢ ͜͏͍͏࣌͸ɺࢥ͍੾ͬͯݸผͷ
 TUSVDU΁෼͚ͯ͠·͓͏ ൃ ද

    Ͱ ͸ ׂ Ѫ
  133. *%ΛݸผͷTUSVDU΁෼͚ͨྫ // BAD: औΓҧ͑ͯ΋ؾ͖ͮͮΒ͍ let userID: Int = 1234 let

    productID: Int = 5678 // GOOD: औΓҧ͑ΔͱίϯύΠϧΤϥʔʹͳΔ let userID = UserID(number: 1234) let productID = ProductID(number: 5678) ൃ ද Ͱ ͸ ׂ Ѫ
  134. ϊ΢ϋ΢ʵ# ίʔυΛࣗಈੜ੒͢Δ Α͋͘ΔόάͷݪҼʹ6*4UPSZCPBSE΍6*/JCͷ
 ໊લࢦఆͷϛε΍ϦωʔϜ๨Ε͕͋Δ ͜ΕΒͷίʔυΛࣗಈੜ੒ͯ͘͠ΕΔπʔϧ͕
 ͍͔ͭ͋͘ΔͷͰɺͲΕ͔Λ࢖͑͹͜ͷछͷόάΛ
 ࣄલʹ༧๷Ͱ͖Δɿ w HJUIVCDPNNBDDBJO3TXJGU w

    HJUIVCDPN4XJGU(FO4XJGU(FO ൃ ද Ͱ ͸ ׂ Ѫ
  135. ϊ΢ϋ΢ͷ·ͱΊ ͜ͷछͷςΫχοΫ͸ແ਺ʹ͋ΔͨΊɺ
 ঺հͨ͠ͷ͸͘͝Ұ෦ Կ͔ͷ*%Λ௚઀ͷ*OU΍
 4USJOHʹ͠ͳ͍ ίʔυΛࣗಈੜ੒͢Δ " # ൃ ද

    Ͱ ͸ ׂ Ѫ
  136. վળલͱͷൺֱ ײ͍ͯͩ͘͡͞

  137. ్த·Ͱ͏·͍͘͘ͷʹ
 కΊ੾Γʹؒʹ߹Θͳ͍

  138. ෆ҆ۦಈνΣοΫͰख໭Γ͕
 গͳ͘ͳͬͨͷͰɺ༧ఆ௨Γʹ
 ਐΉΑ͏ʹͳͬͨʂ

  139. కΊ੾Γ͕ഭͬͯ͘Δͱ
 ಈ࡞֬ೝΛ͖͠Εͳͯ͘
 େৎ෉ͩͱ৴͡Δ͔͠ͳ͍

  140. ಈ࡞֬ೝͷࣗಈԽͰɺӨڹൣғͷ
 ಈ࡞֬ೝ·ͰͰ͖ΔΑ͏ʹͳͬͨʂ

  141. 4JNVMBUPSΆͪΆͪʹ
 ͕͔͔࣌ؒͬͯΠϥΠϥ͢Δ

  142. ಈ࡞֬ೝͷࣗಈԽͰ
 ΆͪΆ͍ͪΒͳ͘ͳͬͨʂ

  143. ͜͏͍͏खॱ·Ͱ͍࣋ͬͯͬͨ݁Ռɺ
 ։ൃ଎౓͕ʹͳͬͯ·ͨ͠ څྉ্͕͕ͬͨ
 ,VOJXBL ࢲͷࣄྫͰ͸

  144. ࣮ࡍ͸͜Μͳʹ
 ͢ΜͳΓ͍͔ͳ͍ Τ ο ʂ ʁ

  145. ࣗಈԽͷ୩໰୊ ཱͪ͸͔ͩΔ

  146. ϊ΢ϋ΢dͷ࣮ફ͕ͱͯ΋೉͍͠ ͜ͷ͋ͱྫΛग़͕͢ɺࣗಈͰͷ
 ಈ࡞֬ೝ͸༧૝֎ʹͰ͖ͳ͍΋ͷ ࣮͸ʜ

  147. import UIKit class ExampleViewController: UIViewController { @IBOutlet weak var label:

    UILabel! @IBAction func buttonTapped(_ sender: Any) { APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, error) in guard let `self` = self else { return } if let error = error { dump(error) let alertViewController = UIAlertController( title: "Τϥʔ͕ൃੜ͠·ͨ͠", message: nil, preferredStyle: .alert ) alertViewController.addAction(UIAlertAction(title: "OK", style: .default)) self.present(alertViewController, animated: true) return } self.label.text = "Hello, \(user!.name)!" } } } ಈ࡞֬ೝͷࣗಈԽ͕͔ͳΓ೉͍͠ྫ
  148. ͜Μͳ୯७ͳ7JFX$POUSPMMFSͰ΋ɺ ಈ࡞֬ೝΛࣗಈԽ͢ΔͨΊͷ஌͕ࣝ
 ͔ͳΓଟ͍ͱ͍͏͜ͱΛײ͡Ͱ͍ͩ͘͞

  149. import UIKit class ExampleViewController: UIViewController { @IBOutlet weak var label:

    UILabel! @IBAction func buttonTapped(_ sender: Any) { APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, error) in guard let `self` = self else { return } if let error = error { dump(error) let alertViewController = UIAlertController( title: "Τϥʔ͕ൃੜ͠·ͨ͠", message: nil, preferredStyle: .alert ) alertViewController.addAction(UIAlertAction(title: "OK", style: .default)) self.present(alertViewController, animated: true) return } self.label.text = "Hello, \(user!.name)!" } } } Ϙλϯ͕λοϓ͞ΕͨΒ
 αʔόͱ௨৴Λ࢝ΊΔ ൃ ද Ͱ ͸ ׂ Ѫ
  150. import UIKit class ExampleViewController: UIViewController { @IBOutlet weak var label:

    UILabel! @IBAction func buttonTapped(_ sender: Any) { APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, error) in guard let `self` = self else { return } if let error = error { dump(error) let alertViewController = UIAlertController( title: "Τϥʔ͕ൃੜ͠·ͨ͠", message: nil, preferredStyle: .alert ) alertViewController.addAction(UIAlertAction(title: "OK", style: .default)) self.present(alertViewController, animated: true) return } self.label.text = "Hello, \(user!.name)!" } } } αʔόʔͱͷ௨৴͕
 Τϥʔʹͳͬͨ৔߹͸
 6*"MFSU$POUSPMMFSͰදࣔ ൃ ද Ͱ ͸ ׂ Ѫ
  151. import UIKit class ExampleViewController: UIViewController { @IBOutlet weak var label:

    UILabel! @IBAction func buttonTapped(_ sender: Any) { APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, error) in guard let `self` = self else { return } if let error = error { dump(error) let alertViewController = UIAlertController( title: "Τϥʔ͕ൃੜ͠·ͨ͠", message: nil, preferredStyle: .alert ) alertViewController.addAction(UIAlertAction(title: "OK", style: .default)) self.present(alertViewController, animated: true) return } self.label.text = "Hello, \(user!.name)!" } } } αʔόʔ͔ΒϢʔβʔ໊͕
 ਖ਼ৗʹฦ͖ͬͯͨΒදࣔ ൃ ද Ͱ ͸ ׂ Ѫ
  152. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let viewController = UIStoryboard( name: "ExampleViewController", bundle: Bundle(for: ExampleViewController.self) ).instantiateInitialViewController() as! ExampleViewController let dummySender = NSObject() viewController.buttonTapped(dummySender) XCTAssertTrue(viewController.label?.text?.contains("Kuniwak")) } } ͱΓ͋͑ͣಈ࡞֬ೝͷίʔυΛॻ͍ͯΈͨ ൃ ද Ͱ ͸ ׂ Ѫ
  153. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let viewController = UIStoryboard( name: "ExampleViewController", bundle: Bundle(for: ExampleViewController.self) ).instantiateInitialViewController() as! ExampleViewController let dummySender = NSObject() viewController.buttonTapped(dummySender) XCTAssertTrue(viewController.label!.text!.contains("Kuniwak")) } } 4UPSZCPBSE͔Β7JFX$POUSPMMFSΛॳظԽ ൃ ද Ͱ ͸ ׂ Ѫ
  154. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let viewController = UIStoryboard( name: "ExampleViewController", bundle: Bundle(for: ExampleViewController.self) ).instantiateInitialViewController() as! ExampleViewController let dummySender = NSObject() viewController.buttonTapped(dummySender) XCTAssertTrue(viewController.label!.text!.contains("Kuniwak")) } } @IBActionΛ࣮ߦͯ͠ϘλϯλοϓΛ࠶ݱ ൃ ද Ͱ ͸ ׂ Ѫ
  155. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let viewController = UIStoryboard( name: "ExampleViewController", bundle: Bundle(for: ExampleViewController.self) ).instantiateInitialViewController() as! ExampleViewController let dummySender = NSObject() viewController.buttonTapped(dummySender) XCTAssertTrue(viewController.label!.text!.contains("Kuniwak")) } } UILabel͕Ϣʔβʔ໊ʹมΘͬͨ͜ͱΛ֬ೝ ൃ ද Ͱ ͸ ׂ Ѫ
  156. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let viewController = UIStoryboard( name: "ExampleViewController", bundle: Bundle(for: ExampleViewController.self) ).instantiateInitialViewController() as! ExampleViewController let dummySender = NSObject() viewController.buttonTapped(dummySender) XCTAssertTrue(viewController.label!.text!.contains("Kuniwak")) } } viewController.label͕nil ൃ ද Ͱ ͸ ׂ Ѫ
  157. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let viewController = UIStoryboard( name: "ExampleViewController", bundle: Bundle(for: ExampleViewController.self) ).instantiateInitialViewController() as! ExampleViewController let dummySender = NSObject() viewController.buttonTapped(dummySender) XCTAssertTrue(viewController.label!.text!.contains("Kuniwak")) } } viewDidLoadΛ଴ͬͯͳ͍ͷͰɺ
 ·ͩUILabel͕ଘࡏ͍ͯ͠ͳ͍ ݪҼɿ ൃ ද Ͱ ͸ ׂ Ѫ
  158. class ExampleViewController: UIViewController { private var actions: ExampleViewsAction? @IBOutlet weak

    var label: UILabel! override func viewDidLoad() { super.viewDidLoad() self.actions = ExampleViewsAction( label: self.label ) } @IBAction func buttonTapped(_ sender: Any) { self.actions?.buttonDidTapped() } } मਖ਼ޙͷ7JFX$POUSPMMFS ൃ ද Ͱ ͸ ׂ Ѫ
  159. class ExampleViewController: UIViewController { private var actions: ExampleViewsAction? @IBOutlet weak

    var label: UILabel! override func viewDidLoad() { super.viewDidLoad() self.actions = ExampleViewsAction( label: self.label ) } @IBAction func buttonTapped(_ sender: Any) { self.actions?.buttonDidTapped() } } viewDidLoadҎ߱ͷॲཧΛผͷΫϥεʹ੾Γग़͢ ʢͳͥ͜͏͢Δͷ͔͸΋͏গ͠ޙͰΘ͔Γ·͢ʣ ॏཁͳͷ͸ɺviewDidLoadͰॳظԽ͞Εͨ
 UILabelΛ੾Γग़ͨ͠Ϋϥεʹ౉͓ͯ͘͜͠ͱ ൃ ද Ͱ ͸ ׂ Ѫ
  160. class ExampleViewController: UIViewController { private var actions: ExampleViewsAction? @IBOutlet weak

    var label: UILabel! override func viewDidLoad() { super.viewDidLoad() self.actions = ExampleViewsAction( label: self.label ) } @IBAction func buttonTapped(_ sender: Any) { self.actions?.buttonDidTapped() } } Ϙλϯͷλοϓॲཧ͸
 @IBActionΛԣྲྀ͢͠Ε͹0, ൃ ද Ͱ ͸ ׂ Ѫ
  161. import UIKit class ExampleViewsAction { private let label: UILabel init(label:

    UILabel) { self.label = label } func buttonDidTapped() { APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, error) in guard let `self` = self else { return } if let error = error { // লུ self.present(alertViewController, animated: true) return } self.label.text = "Hello, \(user!.name)!" } } } 7JFX$POUSPMMFS͔Β෼཭͞Εͨίʔυ ൃ ද Ͱ ͸ ׂ Ѫ
  162. import UIKit class ExampleViewsAction { private let label: UILabel init(label:

    UILabel) { self.label = label } func buttonDidTapped() { APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, error) in guard let `self` = self else { return } if let error = error { // লུ self.present(alertViewController, animated: true) return } self.label.text = "Hello, \(user!.name)!" } } } ஫ɿ͜ͷ໊લ͸ద౰ͳͷͰɺ࣮ࡍ͸֤ʑͷ
 ΞʔΩςΫνϟʹԊ໋໊ͬͨʹ͍ͯͩ͘͠͞ ൃ ද Ͱ ͸ ׂ Ѫ
  163. import UIKit class ExampleViewsAction { private let label: UILabel init(label:

    UILabel) { self.label = label } func buttonDidTapped() { APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, error) in guard let `self` = self else { return } if let error = error { // লུ self.present(alertViewController, animated: true) return } self.label.text = "Hello, \(user!.name)!" } } } 7JFX$POUSPMMFS͔Β౉͞ΕͨUILabel ൃ ද Ͱ ͸ ׂ Ѫ
  164. import UIKit class ExampleViewsAction { private let label: UILabel init(label:

    UILabel) { self.label = label } func buttonDidTapped() { APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, error) in guard let `self` = self else { return } if let error = error { // লུ self.present(alertViewController, animated: true) return } self.label.text = "Hello, \(user!.name)!" } } } 7JFX$POUSPMMFSͷॲཧΛͦͷ··Ҡಈ ൃ ද Ͱ ͸ ׂ Ѫ
  165. import UIKit class ExampleViewsAction { private let label: UILabel init(label:

    UILabel) { self.label = label } func buttonDidTapped() { APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, error) in guard let `self` = self else { return } if let error = error { // লུ self.present(alertViewController, animated: true) return } self.label.text = "Hello, \(user!.name)!" } } } self.present͕ଘࡏ͠ͳ͍ ʢ͜Ε͸গ͠ޙͰमਖ਼͢Δʣ ൃ ද Ͱ ͸ ׂ Ѫ
  166. मਖ਼ޙͷಈ࡞֬ೝίʔυ import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest:

    XCTestCase { func testMyNameIsVisible() { let label = UILabel() let actions = ExampleViewsAction(label: label) actions.buttonDidTapped() XCTAssertTrue(label.text?.contains("Kuniwak")) } } ൃ ද Ͱ ͸ ׂ Ѫ
  167. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let label = UILabel() let actions = ExampleViewsAction(label: label) actions.buttonDidTapped() XCTAssertTrue(label.text?.contains("Kuniwak")) } } 7JFX$POUSPMMFSͰ͸ͳ͘ɺ
 ੾Γग़ͨ͠ΫϥεͷํΛ
 ಈ࡞֬ೝ͢ΔΑ͏ʹ͢Δ ൃ ද Ͱ ͸ ׂ Ѫ
  168. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let label = UILabel() let actions = ExampleViewsAction(label: label) actions.buttonDidTapped() XCTAssertTrue(label.text?.contains("Kuniwak")) } } 7JFX$POUSPMMFS͔ΒUILabel͕౉͞ΕΔͷΛ࠶ݱ ൃ ද Ͱ ͸ ׂ Ѫ
  169. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let label = UILabel() let actions = ExampleViewsAction(label: label) actions.buttonDidTapped() XCTAssertTrue(label.text?.contains("Kuniwak")) } } @IBActionͰλοϓΛ࠶ݱ͢Δ෦෼͸ ੾Γग़ͨ͠Ϋϥεͷํͷϝιουͷ࣮ߦͰ୅ସ ൃ ද Ͱ ͸ ׂ Ѫ
  170. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let label = UILabel() let actions = ExampleViewsAction(label: label) actions.buttonDidTapped() XCTAssertTrue(label.text?.contains("Kuniwak")) } } ઌ΄Ͳ౉ͨ͠UILabelͷ಺༰͕
 มΘ͍ͬͯΔ͔͔֬ΊΒΕ͍ͯΔ ͜͏͢Δ͜ͱͰUILabel͕·ͩ
 ଘࡏ͠ͳ͍໰୊ΛղܾͰ͖Δ ൃ ද Ͱ ͸ ׂ Ѫ
  171. import UIKit class ExampleViewsAction { private let label: UILabel init(label:

    UILabel) { self.label = label } func buttonDidTapped() { APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, error) in guard let `self` = self else { return } if let error = error { // লུ self.present(alertViewController, animated: true) return } self.label.text = "Hello, \(user!.name)!" } } } self.present͕ଘࡏ͠ͳ͍ͷͰ
 ·ͩϏϧυ͕௨Βͳ͍ 7JFX$POUSPMMFS͔Β෼཭͞Εͨίʔυ ൃ ද Ͱ ͸ ׂ Ѫ
  172. import UIKit class ModalPresenter { private weak var viewController: UIViewController?

    init(willPresentOn viewController: UIViewController) { self.viewController = viewController } func present(_ viewController: UIViewController, animated: Bool) { self.viewController?.present(viewController, animated: animated) } } self.present͕ଘࡏ͠ͳ͍໰୊ͷղܾ ൃ ද Ͱ ͸ ׂ Ѫ
  173. import UIKit class ModalPresenter { private weak var viewController: UIViewController?

    init(willPresentOn viewController: UIViewController) { self.viewController = viewController } func present(_ viewController: UIViewController, animated: Bool) { self.viewController?.present(viewController, animated: animated) } } 7JFX$POUSPMMFSͷpresentΛ
 ผͷΫϥεͰ΋ୟ͚ΔΑ͏ʹ͢ΔΫϥε ൃ ද Ͱ ͸ ׂ Ѫ
  174. import UIKit class ModalPresenter { private weak var viewController: UIViewController?

    init(willPresentOn viewController: UIViewController) { self.viewController = viewController } func present(_ viewController: UIViewController, animated: Bool) { self.viewController?.present(viewController, animated: animated) } } presentʹ࢖͏7JFX$POUSPMMFSΛ಺෦ʹอ࣋͢Δ
 ʢϝϞϦϦʔΫΛආ͚ΔͨΊʹweakʹ͢Δʣ ൃ ද Ͱ ͸ ׂ Ѫ
  175. import UIKit class ModalPresenter { private weak var viewController: UIViewController?

    init(willPresentOn viewController: UIViewController) { self.viewController = viewController } func present(_ viewController: UIViewController, animated: Bool) { self.viewController?.present(viewController, animated: animated) } } ͜ͷΫϥεͷpresentΛ࣮ߦ͢Δͱɺอ͍࣋ͯͨ͠
 7JFX$POUSPMMFSͷpresent͕࣮ߦ͞ΕΔ ൃ ද Ͱ ͸ ׂ Ѫ
  176. import UIKit class ExampleViewsAction { private let label: UILabel private

    let modalPresenter: ModalPresenter init(label: UILabel, modalPresenter: ModalPresenter) { self.label = label self.modalPresenter = modalPresenter } func buttonDidTapped() { APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, error) in guard let `self` = self else { return } if let error = error { // লུ self.modalPresenter.present(alertViewController, animated: true) return } self.label.text = "Hello, \(user!.name)!" } } } मਖ਼ޙͷ7JFX$POUSPMMFS͔Β෼཭͞Εͨίʔυ ൃ ද Ͱ ͸ ׂ Ѫ
  177. import UIKit class ExampleViewsAction { private let label: UILabel private

    let modalPresenter: ModalPresenter init(label: UILabel, modalPresenter: ModalPresenter) { self.label = label self.modalPresenter = modalPresenter } func buttonDidTapped() { APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, error) in guard let `self` = self else { return } if let error = error { // লུ self.modalPresenter.present(alertViewController, animated: true) return } self.label.text = "Hello, \(user!.name)!" } } } 7JFX$POUSPMMFS͔ΒUILabelͱҰॹʹ
 ઌ΄ͲͷModalPresenterΛड͚औΔ ൃ ද Ͱ ͸ ׂ Ѫ
  178. import UIKit class ExampleViewsAction { private let label: UILabel private

    let modalPresenter: ModalPresenter init(label: UILabel, modalPresenter: ModalPresenter) { self.label = label self.modalPresenter = modalPresenter } func buttonDidTapped() { APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, error) in guard let `self` = self else { return } if let error = error { // লུ self.modalPresenter.present(alertViewController, animated: true) return } self.label.text = "Hello, \(user!.name)!" } } } self.presentΛModalPresenterͷ
 presentͷݺͼग़͠΁ม͑Δ ൃ ද Ͱ ͸ ׂ Ѫ
  179. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter( willPresentOn: UIViewController() ) let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter ) actions.buttonDidTapped() XCTAssertTrue(label.text?.contains("Kuniwak")) } } मਖ਼ޙͷಈ࡞֬ೝίʔυ ൃ ද Ͱ ͸ ׂ Ѫ
  180. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter( willPresentOn: UIViewController() ) let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter ) actions.buttonDidTapped() XCTAssertTrue(label.text?.contains("Kuniwak")) } } Ϗϧυ͕௨Γ͑͢͞Ε͹͍͍ͷͰɺ
 ద౰ͳModalPresenterΛ࡞੒͢Δ ൃ ද Ͱ ͸ ׂ Ѫ
  181. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter( willPresentOn: UIViewController() ) let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter ) actions.buttonDidTapped() XCTAssertTrue(label.text?.contains("Kuniwak")) } } 7JFX$POUSPMMFS͔Β
 ੾Γग़ͨ͠Ϋϥε΁౉͢ ൃ ද Ͱ ͸ ׂ Ѫ
  182. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter( willPresentOn: UIViewController() ) let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter ) actions.buttonDidTapped() XCTAssertTrue(label.text?.contains("Kuniwak")) } } Ϗϧυ͕௨ΔΑ͏ʹͳͬͨ ൃ ද Ͱ ͸ ׂ Ѫ
  183. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter( willPresentOn: UIViewController() ) let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter ) actions.buttonDidTapped() XCTAssertTrue(label.text?.contains("Kuniwak")) } } XCTAssertEqual failed: ("nil") is
 not equal to ("Optional(true)") ൃ ද Ͱ ͸ ׂ Ѫ
  184. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter( willPresentOn: UIViewController() ) let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter ) actions.buttonDidTapped() XCTAssertTrue(label.text?.contains("Kuniwak")) } } ͜ͷ࣌ͷlabel.textΛݟΔͱ
 ॳظ஋ͷ··ʹͳ͍ͬͯͨ Ϣʔβʔ໊͕·ͩදࣔ͞Ε͍ͯͳ͍Α͏ͩ ൃ ද Ͱ ͸ ׂ Ѫ
  185. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter( willPresentOn: UIViewController() ) let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter ) actions.buttonDidTapped() XCTAssertTrue(label.text?.contains("Kuniwak")) } } ݪҼɿ αʔόʔ͔Βͷฦ৴͕·ͩ
 ฦ͖͍ͬͯͯͳ͍ͷͰɺ
 UILabelΛߋ৽Ͱ͖͍ͯͳ͍ ൃ ද Ͱ ͸ ׂ Ѫ
  186. Ұൠతʹɺ"1*͕ฦ͖ͬͯͨޙͷ7JFXͷ
 ߋ৽ͷ׬ྃΛݕ஌͢Δͷ͸೉͍͠ ྫ͑͹ɺ࣍ͷίʔυͰ7JFXͷߋ৽͕
 ׬ྃ͢Δͷ͸"ͱ#ͷͲͪΒʁ if isAdminMode { callAdminAPI { [weak

    self] (admin, error) in guard let `self` = self else { return } self.label.color = admin != nil ? .red : .blue } } callUserAPI { [weak self] (user, error) in guard let `self` = self else { return } self.label.text = user.name } " # ൃ ද Ͱ ͸ ׂ Ѫ
  187. ਖ਼ղ͸ɺʮ"ͱ#ͷͲͪΒ΋͋Γ͑Δʯ ͭͷ"1*ͷฦͬͯ͘ΔλΠϛϯάʹΑͬͯ
 "ͷͱ͖΋͋Ε͹#ͷͱ͖΋͋Δ if isAdminMode { callAdminAPI { [weak self]

    (admin, error) in guard let `self` = self else { return } self.label.color = admin != nil ? .red : .blue } } callUserAPI { [weak self] (user, error) in guard let `self` = self else { return } self.label.text = user.name } callAdminAPI͕
 ޙʹ׬ྃ͢Ε͹" callUserAPI͕
 ޙʹ׬ྃ͢Ε͹# ൃ ද Ͱ ͸ ׂ Ѫ
  188. ݟͨ໨ͷߋ৽Λ"1*ͳͲͷཪଆͷࣄ৘͔Β੾Γ཭͢ͱղܾͰ͖Δ  ݟͨ໨Λ࢘ΔίϯϙʔωϯτʹදࣔΛ
 ҰׅͰ൓ө͢Δ͚ͩͷϝιουΛੜ΍͢  "1*ݺͼग़͠౳Ͱ͢΂ͯͷ৘ใ͕ἧͬͨΒ
 ϝιουΛݺͼग़͢ઃܭن໿ʹ͢Δ ͜͏͍͏ͱ͖͸ func apply(userName:

    String, isAdmin: Bool) { self.label.text = userName self.label.backgroundColor = isAdmin ? .red : .black } // API ͷ྆ํ͕ฦ͖͔ͬͯͯΒදࣔΛ൓ө͢Δ myView.apply(userName: "Kuniwak", isAdmin: false) ൃ ද Ͱ ͸ ׂ Ѫ
  189. ݟͨ໨ͱཪଆͷ෼཭ͷͨΊͷ४උ protocol ExampleModelDelegate: class { func apply(state: ExampleModelState) } enum

    ExampleModelState: Equatable { case success(userName: String) case failure(error: ExampleModelUpdateError) } enum ExampleModelUpdateError: Error, Equatable { case unspecified(debugInfo: String) } ൃ ද Ͱ ͸ ׂ Ѫ
  190. protocol ExampleModelDelegate: class { func apply(state: ExampleModelState) } enum ExampleModelState:

    Equatable { case success(userName: String) case failure(error: ExampleModelUpdateError) } enum ExampleModelUpdateError: Error, Equatable { case unspecified(debugInfo: String) } ཪଆͷ࢓ࣄͷ४උ͕੔ͬͨͱ͖ʹୟ͍ͯ΋Β͏
 ݟͨ໨ͷҰׅ൓өϝιου ൃ ද Ͱ ͸ ׂ Ѫ
  191. protocol ExampleModelDelegate: class { func apply(state: ExampleModelState) } enum ExampleModelState:

    Equatable { case success(userName: String) case failure(error: ExampleModelUpdateError) } enum ExampleModelUpdateError: Error, Equatable { case unspecified(debugInfo: String) } ཪଆͷ࠷ऴతͳ݁Ռ͸ɺ w ੒ޭͯ͠userName w ࣦഊͯ͠error ͷͲͪΒ͔ͳͷͰɺFOVNͰදݱ ൃ ද Ͱ ͸ ׂ Ѫ
  192. protocol ExampleModelDelegate: class { func apply(state: ExampleModelState) } enum ExampleModelState:

    Equatable { case success(userName: String) case failure(error: ExampleModelUpdateError) } enum ExampleModelUpdateError: Error, Equatable { case unspecified(debugInfo: String) } ཪଆͷ࢓ࣄͷ݁Ռ͕Equatableͩͱ
 ޙͰศརʹͳΔͷͰɺEquatableͳ
 ΤϥʔͷܕΛ࡞੒͓ͯ͘͠ ൃ ද Ͱ ͸ ׂ Ѫ
  193. ཪଆͷ࢓ࣄΛ͓͜ͳ͏Ϋϥε class ExampleModel { weak var delegate: ExampleModelDelegate? func update()

    { APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, erro guard let `self` = self else { return } if let error = error { self.delegate?.apply(state: .failure(error: .unspecified(debugInfo: "\(error)") } else if let user = user { self.delegate?.apply(state: .success(userName: user.name)) } } } } ൃ ද Ͱ ͸ ׂ Ѫ
  194. class ExampleModel { weak var delegate: ExampleModelDelegate? func update() {

    APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, erro guard let `self` = self else { return } if let error = error { self.delegate?.apply(state: .failure(error: .unspecified(debugInfo: "\(error)") } else if let user = user { self.delegate?.apply(state: .success(userName: user.name)) } } } } ஫ɿ͜ͷ໊લ͸ద౰ͳͷͰɺ࣮ࡍ͸֤ʑͷ
 ΞʔΩςΫνϟʹԊ໋໊ͬͨʹ͍ͯͩ͘͠͞ ൃ ද Ͱ ͸ ׂ Ѫ
  195. class ExampleModel { weak var delegate: ExampleModelDelegate? func update() {

    APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, erro guard let `self` = self else { return } if let error = error { self.delegate?.apply(state: .failure(error: .unspecified(debugInfo: "\(error)") } else if let user = user { self.delegate?.apply(state: .success(userName: user.name)) } } } } ཪଆͷ४උ͕੔ͬͨΒ௨஌͢Δઌͷ%FMFHBUF ͜ͷྫͰ͸ɺ7JFX$POUSPMMFS͔Β੾Γग़ͨ͠
 Ϋϥε͕͜ͷ%FMFHBUFΛ࣮૷͢Δ͜ͱʹͳΔ ൃ ද Ͱ ͸ ׂ Ѫ
  196. class ExampleModel { weak var delegate: ExampleModelDelegate? func update() {

    APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, erro guard let `self` = self else { return } if let error = error { self.delegate?.apply(state: .failure(error: .unspecified(debugInfo: "\(error)") } else if let user = user { self.delegate?.apply(state: .success(userName: user.name)) } } } } "1*ͷݺͼग़͠͸ɺ͜ͷΫϥεͷ
 updateϝιουͷ࣮ߦͰ͸͡ΊΔ ൃ ද Ͱ ͸ ׂ Ѫ
  197. class ExampleModel { weak var delegate: ExampleModelDelegate? func update() {

    APIClient.shared.get(type: User.self, url: URLs.getSomething) { [weak self] (user, erro guard let `self` = self else { return } if let error = error { self.delegate?.apply(state: .failure(error: .unspecified(debugInfo: "\(error)") } else if let user = user { self.delegate?.apply(state: .success(userName: user.name)) } } } } "1*ͷ݁Ռ͕ࣦഊͷΑ͏ͳΒ.failure Λ %FMFHBUF΁௨஌͠ɺ੒ޭ͍ͯ͠ΔΑ͏
 ͳΒ .successΛ%FMFHBUF΁௨஌͢Δ ൃ ද Ͱ ͸ ׂ Ѫ
  198. 7JFX$POUSPMMFS͔Β෼཭ͨ͠ΫϥεͷFYUFOTJPO extension ExampleViewsAction: ExampleModelDelegate { func apply(state: ExampleModelState) { switch

    state { case .failure(let error): dump(error) let alertViewController = UIAlertController( title: "Τϥʔ͕ൃੜ͠·ͨ͠", message: nil, preferredStyle: .alert ) alertViewController.addAction(UIAlertAction(title: "OK", style: .default)) self.modalPresenter.present(alertViewController, animated: true) case .success(let userName): self.label.text = "Hello, \(userName)!" } } } ൃ ද Ͱ ͸ ׂ Ѫ
  199. extension ExampleViewsAction: ExampleModelDelegate { func apply(state: ExampleModelState) { switch state

    { case .failure(let error): dump(error) let alertViewController = UIAlertController( title: "Τϥʔ͕ൃੜ͠·ͨ͠", message: nil, preferredStyle: .alert ) alertViewController.addAction(UIAlertAction(title: "OK", style: .default)) self.modalPresenter.present(alertViewController, animated: true) case .success(let userName): self.label.text = "Hello, \(userName)!" } } } ઌ΄Ͳͷ%FMFHBUFΛ࣮૷ͤ͞Δ ൃ ද Ͱ ͸ ׂ Ѫ
  200. extension ExampleViewsAction: ExampleModelDelegate { func apply(state: ExampleModelState) { switch state

    { case .failure(let error): dump(error) let alertViewController = UIAlertController( title: "Τϥʔ͕ൃੜ͠·ͨ͠", message: nil, preferredStyle: .alert ) alertViewController.addAction(UIAlertAction(title: "OK", style: .default)) self.modalPresenter.present(alertViewController, animated: true) case .success(let userName): self.label.text = "Hello, \(userName)!" } } } දࣔͷҰׅߋ৽ϝιουΛ࣮૷
 ʢ಺༰͸मਖ਼લͱಉ͡ʣ ൃ ද Ͱ ͸ ׂ Ѫ
  201. class ExampleViewsAction { private let label: UILabel private let modalPresenter:

    ModalPresenter private let model: ExampleModel init(label: UILabel, modalPresenter: ModalPresenter, model: ExampleModel) { self.label = label self.modalPresenter = modalPresenter self.model = model } func buttonDidTapped() { self.model.update() } } 7JFX$POUSPMMFS͔Β෼཭ͨ͠Ϋϥε ൃ ද Ͱ ͸ ׂ Ѫ
  202. class ExampleViewsAction { private let label: UILabel private let modalPresenter:

    ModalPresenter private let model: ExampleModel init(label: UILabel, modalPresenter: ModalPresenter, model: ExampleModel) { self.label = label self.modalPresenter = modalPresenter self.model = model } func buttonDidTapped() { self.model.update() } } ཪଆͷ࢓ࣄΫϥεͷ࡞੒Λ͜ͷதͰ΍ͬͯ΋͍͍ ͕ɺ7JFX$POUSPMMFS͔Β౉ͯ͠΋Β͏ͱɺͷͪ ͷָͪʹͳΔ ൃ ද Ͱ ͸ ׂ Ѫ
  203. class ExampleViewsAction { private let label: UILabel private let modalPresenter:

    ModalPresenter private let model: ExampleModel init(label: UILabel, modalPresenter: ModalPresenter, model: ExampleModel) { self.label = label self.modalPresenter = modalPresenter self.model = model } func buttonDidTapped() { self.model.update() } } ϘλϯͷλοϓͰཪଆͷ࢓ࣄΛ࢝ΊΔ ൃ ද Ͱ ͸ ׂ Ѫ
  204. मਖ਼ޙͷ7JFX$POUSPMMFS import UIKit class ExampleViewController: UIViewController { // লུ override

    func viewDidLoad() { super.viewDidLoad() self.actions = ExampleViewsAction( label: self.label, modalPresenter: ModalPresenter(willPresentOn: self), model: ExampleModel() ) } } ൃ ද Ͱ ͸ ׂ Ѫ
  205. import UIKit class ExampleViewController: UIViewController { // লུ override func

    viewDidLoad() { super.viewDidLoad() self.actions = ExampleViewsAction( label: self.label, modalPresenter: ModalPresenter(willPresentOn: self), model: ExampleModel() ) } } UILabelͳͲΛ౉͍ͭ͢Ͱʹཪଆͷ
 ࢓ࣄΫϥε΋࡞੒ͯ͠౉͓ͯ͘͠ ൃ ද Ͱ ͸ ׂ Ѫ
  206. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter(willPresentOn: UIViewControlle let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter, model: ExampleModel() ) actions.apply(state: .success(userName: "Kuniwak")) XCTAssertTrue(label.text?.contains("Kuniwak")) } } मਖ਼ޙͷಈ࡞֬ೝίʔυ ൃ ද Ͱ ͸ ׂ Ѫ
  207. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter(willPresentOn: UIViewControlle let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter, model: ExampleModel() ) actions.apply(state: .success(userName: "Kuniwak")) XCTAssertTrue(label.text?.contains("Kuniwak")) } } Ϙλϯͷλοϓͷ࠶ݱͰ͸ͳ͘ɺ
 ௚઀ݟͨ໨ͷ൓өϝιουΛୟ͘ ൃ ද Ͱ ͸ ׂ Ѫ
  208. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter(willPresentOn: UIViewControlle let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter, model: ExampleModel() ) actions.apply(state: .success(userName: "Kuniwak")) XCTAssertTrue(label.text?.contains("Kuniwak")) } } ͔͠͠ɺ͜͏ͯ͠͠·͏ͱϘλϯΛλοϓͯ͠
 ද͕ࣔߋ৽͞ΕΔ͜ͱͷ֬ೝʹͳΒͳ͍ͷͰ͸ʁ
 ͱ͍͏ෆ҆͸࣍ͷͭͷํ๏Ͱ؇࿨Ͱ͖Δɿ w Ϙλϯ͕λοϓ͞ΕͨΒɺཪͷ࢓ࣄΫϥε͕
 ݺ͹ΕΔ͜ͱΛ֬ೝ͢ΔίʔυΛ௥Ճ w ཪͷ࢓ࣄΫϥε͕ݺ͹ΕͨΒɺඞͣ׬ྃ͢Δ
 ͜ͱΛ֬ೝ͢ΔίʔυΛ௥Ճ ͦΕͧΕͷৄࡉ͸εϥΠυͷຕ਺ͷࣄ৘ͰׂѪ͢Δ͕ɺ Ҏ߱ͷεϥΠυͷ஌͚ࣝͩͰ࣮૷Ͱ͖Δ ൃ ද Ͱ ͸ ׂ Ѫ
  209. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter(willPresentOn: UIViewControlle let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter, model: ExampleModel() ) actions.apply(state: .success(userName: "Kuniwak")) XCTAssertTrue(label.text?.contains("Kuniwak")) } } Ͱ͸ಈ࡞֬ೝΛ࣮ߦͯ͠ΈΑ͏ ൃ ද Ͱ ͸ ׂ Ѫ
  210. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter(willPresentOn: UIViewControlle let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter, model: ExampleModel() ) actions.apply(state: .success(userName: "Kuniwak")) XCTAssertTrue(label.text?.contains("Kuniwak")) } } ͜͜·Ͱ͖ͯ΍ͬͱ੒ޭ͠·͢ ൃ ද Ͱ ͸ ׂ Ѫ
  211. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter(willPresentOn: UIViewControlle let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter, model: ExampleModel() ) actions.apply(state: .success(userName: "Kuniwak")) XCTAssertTrue(label.text?.contains("Kuniwak")) } } ͔͠͠ɺ·ͩ"1*ݺͼग़͕͠Τϥʔʹ ͳͬͨ৔߹ͷಈ࡞֬ೝΛͰ͖͍ͯͳ͍ʜ ൃ ද Ͱ ͸ ׂ Ѫ
  212. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter(willPresentOn: UIViewControlle let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter, model: ExampleModel() ) actions.apply(state: .success(userName: "Kuniwak")) XCTAssertTrue(label.text?.contains("Kuniwak")) } } ͜Ε΋ίʔυͰಈ࡞֬ೝͰ͖Δ͕ɺ
 εϥΠυͷຕ਺ͷ౎߹ͰׂѪ͢Δ ͜ͷ࡞ۀͷώϯτΛॻ͍͓ͯ͘ɿ w "1*ͷ݁ՌΛಈ࡞֬ೝίʔυ͔Β
 ࢦఆͰ͖ΔΑ͏ʹ͢Δ ‎ *OQVU0CKFDU*OKFDUJPO w .PEBM1SFTFOUFSͷϝιουݺͼग़͠Λ
 ه࿥͢ΔِͷΦϒδΣΫτΛ࡞੒͢Δ ‎ 0VUQVU0CKFDU*OKFDUJPO ͦΕͧΕͷৄࡉ͸ɺεϥΠυͷޙํͰ
 ঺հ͢ΔʮJ04Ͱςετ༰қͳઃܭΛ
 ࣮ݱ͢ΔͨΊͷσβΠϯύλʔϯʯͰ
 αϯϓϧίʔυͱ߹Θͤͯղઆ͍ͯ͠Δ ൃ ද Ͱ ͸ ׂ Ѫ
  213. import XCTest import UIKit @testable import IOSDC2018Debugging class ExampleViewControllerTest: XCTestCase

    { func testMyNameIsVisible() { let dummyModalPresenter = ModalPresenter(willPresentOn: UIViewControlle let label = UILabel() let actions = ExampleViewsAction( label: label, modalPresenter: dummyModalPresenter, model: ExampleModel() ) actions.apply(state: .success(userName: "Kuniwak")) XCTAssertTrue(label.text?.contains("Kuniwak")) } } ͜Ε·Ͱͷ࡞ۀͰ΍ͬͨ͜ͱɿ w 7JFX$POUSPMMFSͷॲཧΛผ΁੾Γग़ͨ͠ w ผͷΫϥεͰUIViewController.presentΛ
 ࢖͑ΔΑ͏ʹͨ͠ w ݟͨ໨ͷҰׅ൓өΛίʔυ͔Β
 ࣮ߦͰ͖ΔΑ͏ʹͨ͠ ࣗಈͰͷಈ࡞֬ೝʹඞཁͳࡉ͔ͳ஌͕ࣝ
 ͱͯ΋ଟ͍͜ͱ͕Θ͔Δ ൃ ද Ͱ ͸ ׂ Ѫ
  214. ಈ࡞֬ೝͷࣗಈԽʹ͸ɺී௨ͷ
 ΞϓϦ࣮૷ͱ͸ҟͳΔ஌͕ࣝඞཁ ݴ͍͔ͨͬͨ͜ͱ͸

  215. ։ൃ଎౓ͷ૿Ճྔ ࣌ؒܦա        --%#ͷ


    ׆༻ มߋ௚ޙͷ
 σόοά ෆ҆ۦಈ
 νΣοΫ ಈ࡞֬ೝͷ
 ࣗಈԽ ؒҧ͑ʹ͍͘
 ઃܭ
  216. ։ൃ଎౓ͷ૿Ճྔ ͜͜·Ͱ͸͢ΜͳΓ͍͘ ࣌ؒܦա   --%#ͷ
 ׆༻ มߋ௚ޙͷ
 σόοά ෆ҆ۦಈ


    νΣοΫ ಈ࡞֬ೝͷ
 ࣗಈԽ ؒҧ͑ʹ͍͘
 ઃܭ
  217. ։ൃ଎౓ͷ૿Ճྔ ࣌ؒܦա --%#ͷ
 ׆༻ มߋ௚ޙͷ
 σόοά ෆ҆ۦಈ
 νΣοΫ ಈ࡞֬ೝͷ
 ࣗಈԽ

    ؒҧ͑ʹ͍͘
 ઃܭ ͋ΕʁࣗಈԽ͕೉͍ͧ͠ʜʁ
 Ͱ΋ηϧϑνΣοΫͪΌΜͱ
 ΍ͬͯΔ͔Β͕͔͔࣌ؒΔʜ  
  218. ։ൃ଎౓ͷ૿Ճྔ ࣌ؒܦա --%#ͷ
 ׆༻ มߋ௚ޙͷ
 σόοά ෆ҆ۦಈ
 νΣοΫ ಈ࡞֬ೝͷ
 ࣗಈԽ

    ؒҧ͑ʹ͍͘
 ઃܭ ΋͏ͪΐͬͱؤுͬͯΈ͚ͨͲɺ
 ͕͔͔࣌ؒΓ͗͢Δʜʜ  
  219. ։ൃ଎౓ͷ૿Ճྔ ࣌ؒܦա --%#ͷ
 ׆༻ มߋ௚ޙͷ
 σόοά ෆ҆ۦಈ
 νΣοΫ ಈ࡞֬ೝͷ
 ࣗಈԽ

    ؒҧ͑ʹ͍͘
 ઃܭ ͩΊͩɺࣗಈԽແཧͩʜ ͜Μͳঢ়گͰෆ҆ͳൣғ
 ͢΂ͯͷ֬ೝͳΜͯແཧʜ  
  220. ։ൃ଎౓ͷ૿Ճྔ ࣌ؒܦա   --%#ͷ
 ׆༻ มߋ௚ޙͷ
 σόοά ෆ҆ۦಈ
 νΣοΫ

    ಈ࡞֬ೝͷ
 ࣗಈԽ ؒҧ͑ʹ͍͘
 ઃܭ ΋͠ɺޮ཰తʹಈ࡞֬ೝΛ
 ࣗಈԽ͢ΔͨΊͷ஌ࣝΛ
 ͍࣋ͬͯͨΒʜ
  221. ։ൃ଎౓ͷ૿Ճྔ ࣌ؒܦա --%#ͷ
 ׆༻ มߋ௚ޙͷ
 σόοά ෆ҆ۦಈ
 νΣοΫ ಈ࡞֬ೝͷ
 ࣗಈԽ

    ؒҧ͑ʹ͍͘
 ઃܭ ΋͏ͪΐͬͱؤுͬͯΈ͚ͨͲɺ
 ͕͔͔࣌ؒΓ͗͢Δʜʜ  
  222. ։ൃ଎౓ͷ૿Ճྔ ࣌ؒܦա --%#ͷ
 ׆༻ มߋ௚ޙͷ
 σόοά ෆ҆ۦಈ
 νΣοΫ ಈ࡞֬ೝͷ
 ࣗಈԽ

    ؒҧ͑ʹ͍͘
 ઃܭ ͕͔͔͍࣌ؒͬͯΔͷ͸ɺ
 ͜ͷςΫχοΫ࢖͑͹
 গ͠ϚγʹͳΔ͸ͣʜ  
  223. ։ൃ଎౓ͷ૿Ճྔ ࣌ؒܦա --%#ͷ
 ׆༻ มߋ௚ޙͷ
 σόοά ෆ҆ۦಈ
 νΣοΫ ಈ࡞֬ೝͷ
 ࣗಈԽ

    ؒҧ͑ʹ͍͘
 ઃܭ ͋ɺͳΜָ͔ʹͳ͖ͬͯͨ  
  224. ։ൃ଎౓ͷ૿Ճྔ ࣌ؒܦա --%#ͷ
 ׆༻ มߋ௚ޙͷ
 σόοά ෆ҆ۦಈ
 νΣοΫ ಈ࡞֬ೝͷ
 ࣗಈԽ

    ؒҧ͑ʹ͍͘
 ઃܭ ΊͬͪΌָʹͳͬͨ  
  225. ։ൃ଎౓ͷ૿Ճྔ ࣌ؒܦա --%#ͷ
 ׆༻ มߋ௚ޙͷ
 σόοά ෆ҆ۦಈ
 νΣοΫ ಈ࡞֬ೝͷ
 ࣗಈԽ

    ؒҧ͑ʹ͍͘
 ઃܭ ͋ͱ͔ΒৼΓฦΔͱɺ
 ͜͜ʹͭΒ͍࣌ظ͕͋ͬͨ  
  226. ։ൃ଎౓ͷ૿Ճྔ ࣌ؒܦա --%#ͷ
 ׆༻ มߋ௚ޙͷ
 σόοά ෆ҆ۦಈ
 νΣοΫ ಈ࡞֬ೝͷ
 ࣗಈԽ

    ؒҧ͑ʹ͍͘
 ઃܭ ࣗಈԽͷ୩  
  227. ։ൃ଎౓ͷ૿Ճྔ ࣌ؒܦա --%#ͷ
 ׆༻ มߋ௚ޙͷ
 σόοά ෆ҆ۦಈ
 νΣοΫ ಈ࡞֬ೝͷ
 ࣗಈԽ

    ؒҧ͑ʹ͍͘
 ઃܭ   ࣗಈԽͷ୩Λӽ͑ΔͨΊʹ͸ɺ
 ͏·͘੾Γൈ͚ΔͨΊͷ஌͕ࣝ
 ͱͯ΋େࣄͩͱ͍͏͜ͱ
  228. ࢲͷྫͰ͸ɺݩ͔Βಈ࡞֬ೝΛ
 ಘҙͱ͍ͯͨ͠,VOJXBL͕ओಋͨ͠ ͭ·Γɺ୩Λ৐Γӽ͑Δ஌ࣝΛ΋͍ͬͯͯ
 ڧͯ͘χϡʔήʔϜʹͳ͍ͬͯΔ

  229. ࣗಈԽͷ୩Λʮ͍ͭʯ
 ৐Γӽ͑Δ͔ ܦݧऀ͕ޠΔ

  230. ίʔυ͕ߴྸͳ΄ͲɺࣗಈԽͷ୩͸
 Ͳ͜·Ͱ΋ਂ͘ͳΓɺ͔ͭ௕͘ͳΔ ߴྸͳίʔυͰ͍͖ͳΓࣗಈԽͷ୩ӽ͑Λ
 ໨ࢦ͢ͷ͸ແ஡Λӽ͑ͯແ๳ ٯʹɺίʔυ͕ए͚Ε͹·ͩࣗಈԽͷ୩Λ
 ӽ͑ΒΕΔνϟϯε͕͋Δ ࢲͷࣄྫͰ͸ϑϧεΫϥονʹ
 ్த͔ΒࢀՃͯ࢝͠Ί͍ͯΔ

  231. ৽ػೳ࣮૷΍ϦχϡʔΞϧͳͲͰ
 ৽͍͠ίʔυΛ͜Ε͔Βॻ͘ਓ͸ɺ ࠓ͕νϟϯεͩʂ

  232. ୩ΛҰ౓Ͱ΋ӽ͑ΔܦݧΛͨ͠ਓ͸
 ͔࣍Βڧͯ͘χϡʔήʔϜͰ͖Δ िؒͰ΋͍͍ͷͰɺখ͍͞࿅श༻ΞϓϦͰ
 ࣗಈԽΛମݧ͓ͯ͘͜͠ͱ͕Φεεϝ ࠓλΠϛϯά͕ѱͯ͘΋ ࢲͷࣗಈԽͷ࿅शΞϓϦ HJUIVCDPN,VOJXBL5FTUBCMF%FTJHO&YBNQMF

  233. ࣗಈԽͷ୩ΛʮͲ͏ʯ
 ৐Γӽ͑Δ͔ ܦݧऀ͕ޠΔ

  234. ࣗಈԽͷ୩Λ౿ഁ͢ΔͨΊʹ͸ɺҎԼͷ
 ஌͕ࣝ໾ʹཱͭɿ w ޮ཰తͳಈ࡞֬ೝίʔυͷॻ͖ํ w ಈ࡞֬ೝ͠΍͍͢ຊମΞϓϦͷॻ͖ํ w ຊମΞϓϦͷม͍͖͑ͯํ ͜ΕΒͷτϐοΫ͸ʮςετʯͱ͍͏
 ΧςΰϦͰޠΒΕΔ͜ͱ͕ଟ͍Ͱ͢

  235. ࣗಈԽͷ୩ӽ͑ͷͨΊͷࢿྉ ྫ͑͹ʜ

  236. ʮJ04Ͱςετ༰қͳઃܭΛ
 ࣮ݱ͢ΔͨΊͷσβΠϯύλʔϯʯ https://speakerdeck.com/orgachem/ios-detesutorong- yi-nashe-ji-wo-shi-xian-surutamefalsedezainpatan ൃ ද Ͱ ͸ ׂ Ѫ

  237. ʮ4XJGUͷ)551ϥΠϒϥϦͰۤ͠·ͳ͍ͨΊͷ
 ࣗ࡞"1*ΫϥΠΞϯτઃܭʯ https://qiita.com/Kuniwak/items/a972ff2ade643799d1fe ൃ ද Ͱ ͸ ׂ Ѫ

  238. ʮ4XJGUͰॻ͍͓ͯ΅͑Δ5%%ʯ μϯϘʔాத / @ktanaka117 ฤ ஶ
 https://danbo-house.booth.pm/items/837289 ൃ ද Ͱ

    ͸ ׂ Ѫ
  239. ಠֶͷݶքΛײͨ͡Β ͍͔ͭ๚ΕΔ

  240. ʮJ045FTU/JHIUʯ https://testnight.connpass.com/ PS݄ʹ౦ژͰ։࠵༧ఆ

  241. %JTDPSETXJGUEFWFMPQFSTKBQBOUFTUJOH https://discordapp.com/invite/4Scjz4J ΦϯϥΠϯνϟοτͰ΋૬ஊͰ͖Δ৔ॴ͕͋Δ

  242. ͜ͷൃදͰ఻͖͑Εͳ͔ͬͨ
 ৄࡉͳ࣮૷ύλʔϯʹ͍ͭͯ͸ʜ ͦͯ͠ʜ

  243. ຊΛॻ͖·͢

  244. ٕज़ॻΫϥ΢υϑΝϯσΟϯά1&",4Ͱ
 ϓϩδΣΫτΛެ։༧ఆʢ݄ʣ https://peaks.cc $0. */(
 400/

  245. ୩ӽ͑ͷ৺ߏ͑ λΠϛϯά͕੔ͬͨͱ͖ͷ

  246. λΠϛϯά͕ສશͰ΋
 ୩͸ඞͣଘࡏ͢Δ ୩ఈʹԿ͕જΈɺ
 Ͳ͏৐Γӽ͑Δ͔Λ஌Ζ͏

  247. ৐Γӽ͑ΔͨΊͷ஌ࣝ͸ଟ͘ɺ
 ࠷ॳ͸೉͘͠ײ͡Δ͔΋͠Εͳ͍ ͦΕͰ΋ɺ֮ͭ͑Δ͝ͱʹ
 ୩͔Β͸গͮͭ͠཭Ε͍ͯΔ

  248. ཱͪࢭ·ͬͯ΋
 ݱࡏ஍͸มΘΒͳ͍ ਐΊΔ࣌ʹਐΉ͙Β͍Ͱ
 ͪΐ͏Ͳ͍͍

  249. ·ͱΊ ΁ͷ։ൃ଎౓޲্Λࢧ͑ͨ ͭͷϊ΢ϋ΢ɿ --%#Λ࢖͍͜ͳ͢ σόοάͷλΠϛϯάΛมߋ௚ޙʹ͢Δ ෆ҆ۦಈͰηϧϑνΣοΫ͢Δ ಈ࡞֬ೝΛࣗಈԽ͢Δ ؒҧ͍ʹ͍͘ઃܭʹ͢Δ  

      
  250. ,VOJXBL͔Βͷϝοηʔδ ։ൃ଎౓ୡ੒ͷલʹ͸
 ࣗಈԽͷ୩͕ଘࡏ͢Δ ৐Γӽ͑ΔͨΊͷ஌ࣝΛ
 ͍֮ͭͣͭ͑ͯ͜͏ ཱͪࢭ·ͬͯ΋ޙ໭Γ͸͠ͳ͍͔Βɺ
 ਐΊΔ࣌ʹਐΉ͙Β͍Ͱͪΐ͏Ͳ͍͍

  251. ݸਓతʹ͸ɺJ04%$Ͱ΋΋ͬͱ
 ࣗಈతͳಈ࡞֬ೝʢςετʣͷ
 ϊ΢ϋ΢ͷൃද͕͋ͬͯ΋͍͍ͱࢥ͏ʜ