Slide 1

Slide 1 text

ϥϯλΠϜσόοάͷεεϝ iOSDC2021 TrackA Day2 noppe / iOS app developer 1

Slide 2

Slide 2 text

noppe - noppefoxwolf • גࣜձࣾσΟʔɾΤψɾΤʔ • ιʔγϟϧϥΠϒPococha • ݸਓΞϓϦ։ൃ • όʔνϟϧࣗࡱΓΞϓϦvear 2

Slide 3

Slide 3 text

3

Slide 4

Slide 4 text

4

Slide 5

Slide 5 text

• ऩ࿥ͷ2िؒલʹࢠڙ͕࢈·Ε·ͨ͠ • ऩ࿥தʹٽ͖࢝ΊͨΒ΍Γ௚͠ʹͳΓ·͢ 5

Slide 6

Slide 6 text

6

Slide 7

Slide 7 text

7

Slide 8

Slide 8 text

ଘࡏ͠ͳ͍୯ޠͳͷͰ… ఆٛ ࣮ߦதͷΞϓϦͰɺσόοάΛ͢Δ͜ͱ1 ≒ ࣮ػςετ ͱ͠·͢ɻ 1 ͜ͷηογϣϯͷதͰͷఆٛ

Slide 9

Slide 9 text

ର৅ • ςελʔ • ΞϓϦΤϯδχΞ • QA୲౰ऀ • σβΠφʔ ...etc ※ ࣮ػσόοάΛਪ঑͢ΔηογϣϯͰ͸͋Γ·ͤΜɻ ࣮ػσόοάͤ͟Δಘͳ͍έʔεͱ͍͏લఏͰ͓ฉ͖͍ͩ͘͞ɻ 9

Slide 10

Slide 10 text

Ұൠతͳ։ൃϑϩʔ 1. ίʔσΟϯάɾ࢓༷ࡦఆɾetc 2. ίϯύΠϧ 3. γϛϡϨʔλɾσόΠε࣮ߦɾϥΠϒϓϨϏϡʔ 4. UnitTest 5. ݁߹ςετ 6. CI 7. QA 8. ϕʔλςετ 9. ϦϦʔεςετ 10. ຊ൪ςετ 10

Slide 11

Slide 11 text

ϥϯλΠϜσόοάͷಛ௃ 1. ਓ͕ؒख࡞ۀͰߦ͏࣌ؒతίετ • ≒ۚમతίετ • ≒ࣄۀϦεΫ 2. ఆੑతͳҙݟͷ׆༻ͷ೉͠͞ • ʮͳΜ͔ॏ͍ؾ͕͢ΔʯΛͲ͏ѻ͏͔ 11

Slide 12

Slide 12 text

1.࣌ؒతίετͷվળ 12

Slide 13

Slide 13 text

ݕূ଎౓ͷվળ ϥϯλΠϜσόοάͷϑϩʔ 1. ίϯύΠϧ 2. సૹ 3. ؀ڥͷ֬ೝ 4. ը໘·Ͱͷૢ࡞ 5. ಈ࡞ݕূ ͜ΕΒͷͲ͜ʹͲΜͳ͕͔͔͍࣌ؒͬͯΔͷ͔Λ஌Δඞཁ͕͋Δɻ 13

Slide 14

Slide 14 text

ݕূ଎౓ͷվળ 3.؀ڥͷ֬ೝ • όʔδϣϯ൪߸ɺϏϧυ൪߸ • ϩάΛݟΔ • OSͷόʔδϣϯɺϞσϧ • ઃఆΞϓϦ͔Βࢀর • Ϗϧυͷ࠷ऴ୲౰ऀ ...etc 14

Slide 15

Slide 15 text

3.؀ڥͷ֬ೝ A. ΞϓϦͷதͰݟΕΔΑ͏ʹ͠ɺૢ࡞Λল͘ • ͳΜͰ΋͔ΜͰ΋දࣔͤͣɺඞཁͳ৘ใ͔ݟۃ ΊΔ • ߲໨͸ςελʔʹώΞϦϯά • ֬ೝʹίϛϡχέʔγϣϯ͕ඞཁͳ΋ͷ͕ ͳ͍͔ • ख࡞ۀʹΑΔૢ࡞͕ඞཁͳ΋ͷ͕ͳ͍͔ 15

Slide 16

Slide 16 text

σόοάϝχϡʔ • ςελʔ޲͚ͷಛघͳը໘ • ඇΤϯδχΞ2ʹͱͬͯɺඇৗʹڧྗͳଘࡏ 2 ࣮૷ͷมߋ͕ग़དྷͳ͍ςελʔ

Slide 17

Slide 17 text

σόοάϝχϡʔͷ࣮૷ 1. ద౰ͳը໘Λ༻ҙ͢Δ 2. ຊ൪Ͱݺ΂ͳ͍Α͏ʹ͢Δ 17

Slide 18

Slide 18 text

σόοάϝχϡʔͷ࣮૷ func onTapSettings(section: Section) { switch section { case .general: ... #if DEBUG // #endif·Ͱͷίʔυ͸ຊ൪ʹؚ·Εͳ͍ case .debugMenu: let vc = DebugMenuViewController() present(vc, animated: true) #endif } } #if DEBUG final class DebugMenuViewController: UITableController { ... } #endif 18

Slide 19

Slide 19 text

σόοάϝχϡʔͷ࣮૷ ։ൃ༻ػೳΛϞδϡʔϧԽ͠ɺ҆શʹ෼཭͢Δʹ͸ Swift Packageத৺ͷϓϩδΣΫτߏ੒ ͱͦͷ࣮ફ Day2 TrackC 14:50 େن໛ͳΞϓϦͷϚϧνϞδϡʔϧߏ ੒ͷ࣮ફ Day2 TrackA 11:30 19

Slide 20

Slide 20 text

ݕূ଎౓ͷվળ 3.؀ڥͷ֬ೝ ࠶Ϗϧυɾ࠶ΠϯετʔϧΛ൐͏؀ڥ • ઀ଓઌαʔόʔͷઃఆ • νϡʔτϦΞϧදࣔͷϦηοτ • Ωϟογϡͷ࡟আ 20

Slide 21

Slide 21 text

ݕূ଎౓ͷվળ 3.؀ڥͷ֬ೝ ࠶Ϗϧυɾ࠶ΠϯετʔϧΛ൐͏؀ڥ͸… σόοάϝχϡʔ͔Βઃఆɾ࣮ߦͰ͖ΔΑ͏ʹ͢ Δ 21

Slide 22

Slide 22 text

22

Slide 23

Slide 23 text

ݕূ଎౓ͷվળ 4.ը໘·Ͱͷૢ࡞ • ը໘ભҠ͕ଟ͍ • ௨৴΍ॏ͍ॲཧ͕ڬ·Δ΄Ͳ͕͔͔࣌ؒΔ • ભҠ৚͕݅ݫ͍͠ Hint • ىಈ͔ΒonAppear()΍viewDidAppear()· Ͱͷ࣌ؒΛܭଌ͢Δ 23

Slide 24

Slide 24 text

ݕূ଎౓ͷվળ 4.ը໘·Ͱͷૢ࡞ 1. σόοάϝχϡʔ͔Β௚઀ඈ΂ΔΑ͏ʹ͢Δ 2. URLεΩʔϜ͔Βىಈ͢Δ 24

Slide 25

Slide 25 text

TIPS Q. ΞϓϦΛ࠶ىಈ͢Δʹ͸ A. Shortcut.appΛ࢖͏ 1. ड͚औͬͨURLΛSafariͰ։͘γϣʔτΧοτΛ࡞੒ 2. ΞϓϦ͔Βࣗ਎ͷURLεΩʔϜΛؚΜͩγϣʔτΧοτ3Λୟ͘ 3. ΞϓϦΛऴྃͤ͞Δ 4. Shortcut.app͕URLεΩʔϜΛ࣮ߦ 5. ΞϓϦ͕࠶ىಈ͢Δ 3 shortcuts://run-shortcut?name=shortcutName&input=text&text=urlScheme 25

Slide 26

Slide 26 text

DEMO 26

Slide 27

Slide 27 text

ݕূ଎౓ͷվળ 5.ಈ࡞ݕূ • ࣌୹͠೉͍Օॴ • ϑΟʔϧʢମײʣͷݕূ͸վળͷ༨஍͋Γ • ΞχϝʔγϣϯɾδΣενϟʔɾײ֮ϑΟʔυόοΫ • ඍௐ੔͕ଟ͘ɺ࠶Ϗϧυ΋ଟ͍ 27

Slide 28

Slide 28 text

ݕূ଎౓ͷվળ ύϥϝʔλͷௐ੔͸࣮ߦதʹग़དྷΔΑ͏ʹ͢Δ • ࣮૷ίετ͕͔͔ΔͷͰɺΞϓϦͷίΞͷ෦෼ ͷར༻ʹߜΔ • ઃఆ஋Λڞ༗ग़དྷΔΑ͏ʹ͢Δ • มߋ͢ΔUI͸ಉ͡ը໘಺ʹ࣋ͭ 28

Slide 29

Slide 29 text

ݕূ଎౓ͷվળ Case Study Find MyͰ͸ɺύʔςΟΫϧͷ਺΍എܠͷϒϥʔೱ ౓Λௐ੔Ͱ͖Δػೳ͕ଘࡏ͍ͯͨ͠ɻ4 AirTag͕ͳͯ͘΋ɺݟ͚ͭΔ·ͰͷΞχϝʔγϣ ϯ͕ࣗಈ࠶ੜͰ͖Δɻ ࣮ػΛ࢖͍ͭͭɺ෺ཧతͳ੍໿ΛऔΓ෷ͬͯ ϑΟʔϧͷτϥΠΞϯυΤϥʔΛࢼͤΔྑ͍ྫ 4 https://www.cultofmac.com/741835/enable-airtag- debug-mode/ 29

Slide 30

Slide 30 text

ݕূ଎౓ͷվળ Recap • σόοάϝχϡʔΛ׆༻ͯ͠ɺΞϓϦͰݕূΛ׬݁͢Δ͜ͱͰݕূ࣌ؒΛ୹ॖ͢ Δ • ख࡞ۀ΍ίϛϡχέʔγϣϯΛݮΒ͢ • ࠶Ϗϧυ΍࠶ΠϯετʔϧΛආ͚Δ • ςελʔ޲͚ͷUXΛ௥ٻ͢Δ 30

Slide 31

Slide 31 text

ఆੑతͳҙݟͷ׆༻ͷ೉͠͞ ϥϯλΠϜσόοά͸UnitTestͱҟͳΓਓ͕ؒ৮ΔͷͰఆੑతͳҙݟ͕ಘΒΕΔɻ ൓໘ɺఆੑతͳҙݟ͸׆༻͕೉͍͠ - ʮͳΜ͔ؾ࣋ͪॏ͍ʯΛݕূ͢Δͷ͸೉͍͠ 31

Slide 32

Slide 32 text

ఆੑతͳҙݟͷ׆༻ͷ೉͠͞ νʔϜશମͰײ֮Λ߹ΘͤΔ౒ྗ͸্ͨ͠Ͱ… 1. ఆੑతͳҙݟͷཪ෇͚Λ͢Δ 2. ఆྔతͳࢦඪΛݟ͑ΔԽ͢Δ 32

Slide 33

Slide 33 text

ఆੑతͳҙݟͷ׆༻ͷ೉͠͞ ఆੑతͳҙݟͷཪ෇͚Λ͢Δ ཪ෇͚͕͋Δ͜ͱͰɺݕূίετ͕Լ͕Γνέοτ͸༗ҙٛͳ΋ͷʹ ʮॏ͍ɾ஗͍ʯͳͲɺఆੑతͳҙݟ͸ϩάΛݟͯ΋෼͔Βͳ͍͜ͱ͕ଟ͍ɻ RPScreenRecorderΛ࢖͏͜ͱͰૢ࡞ͷ15ඵલ·ͰΛه࿥͢Δ͜ͱ͕Ͱ͖Δ 33

Slide 34

Slide 34 text

import ReplayKit // ىಈ͙ͯ͢͠ʹΫϦοϓͷόοϑΝϦϯάΛ։࢝͢Δ func launched() async throws { try await RPScreenRecorder.shared().startClipBuffering() } ... // ҧ࿨ײΛײͨ͡Β͙͢ʹΫϦοϓΛγΣΞͯ͠΋Β͏ɻ func onTapClipShareButton() async throws { let url: URL = URL(string: "")! try await RPScreenRecorder.shared().exportClip(to: url, duration: 5) try await RPScreenRecorder.shared().stopClipBuffering() shareVideo(url) } 34

Slide 35

Slide 35 text

ఆੑతͳҙݟͷ׆༻ͷ೉ ͠͞ ఆྔతͳࢦඪΛݟ͑ΔԽ͢Δ શମͰܾΊͨ඼࣭ࢦඪΛՄࢹԽͯ͠ɺ໰୊ͷݟա ͝͠Λ๷͙ • FPS • ೤ • όοςϦʔফඅ • ...etc 35

Slide 36

Slide 36 text

ఆੑతͳҙݟͷ׆༻ͷ೉͠͞ Recap • ϥϯλΠϜσόοά͸ɺUnitTestͱҟͳΓఆੑతͳҙݟ͕ಘΒΕΔ • ఆੑతͳҙݟ͸׆༻͕೉͍͠ • ͜Ε·Ͱݕূͷ೉͔͕ͬͨ͠ɺΫϦοϓΛ࢖͏͜ͱͰࣄ࣮ͱݟൺ΂ͳ͕Βղ ܾͰ͖Δ • ఆྔతͳࢦඪΛݟ͑ΔԽ͢Δ • ςελʔͷײ֮ʹґଘ͠ͳ͍ମ੍ 36

Slide 37

Slide 37 text

noppefoxwolf/DebugMenuͷ঺ հ 37

Slide 38

Slide 38 text

DebugMenu • noppefoxwolf/DebugMenu • ৗʹσόοάϝχϡʔͷϥϯνϟʔΛදࣔ͢Δ • ύϑΥʔϚϯεͷৗ࣌දࣔػೳ • SwiftUI / UIKitରԠ • SPMରԠ 38

Slide 39

Slide 39 text

import DebugMenu func applaunched() { #if DEBUG DebugMenu.install(windowScene: windowScene, items: [ ViewControllerDebugItem(), ClearCacheDebugItem(), UserDefaultsResetDebugItem(), CustomDebugItem() ], complication: [ CPUUsageComplication() ]) #endif } 39

Slide 40

Slide 40 text

ViewControllerDebugIte m ೚ҙͷViewControllerΛ௚઀ݺͼग़͢ ViewControllerDebugItem( builder: { viewControllerType in viewControllerType.init(color: UIColor.blue) } ) 40

Slide 41

Slide 41 text

UIܥDebugItem • ToggleDebugItem • SliderDebugItem 41

Slide 42

Slide 42 text

/* ΧελϜDebugItem */ struct CustomDebugItem: DebugItem { /// දࣔ͢ΔΞΠςϜ໊ let debugItemTitle: String = "Custom item" /// let action: DebugItemAction = .didSelect { from, completion in ... completion(.success()) } } 42

Slide 43

Slide 43 text

μογϡϘʔυ • ը໘্ʹΦʔόʔϨΠ • ύϑΥʔϚϯεͷঢ়گΛදࣔ • ΧελϜՄೳ 43

Slide 44

Slide 44 text

ΫΠοΫΞΫηε • ΞϓϦ৘ใͷදࣔ • ΞΠςϜͷάϧʔϐϯά • ࣮ߦཤྺͷදࣔ • ΞΠςϜͷݕࡧ 44

Slide 45

Slide 45 text

Summary • ϥϯλΠϜσόοά͸… • ࣌ؒతɾۚમతʹίετ͕͔͔Δ • σόοάϝχϡʔʹΑΔ࡞ۀޮ཰ԽͰίετΛ཈͑Δ • ҰํͰUnitTestͰ͸ಘΒΕͳ͍ఆੑతͳҙݟ͕Ҿ͖ग़ͤΔ • ͔͠͠ఆੑతͳҙݟ͸׆༻͕೉͍͠ • ཪ෇͚ͱɺఆྔతͳࢦඪΛ࣋ͬͯ༗ޮʹ׆༻͢Δ • noppefoxwolf/DebugMenu 45