Slide 1

Slide 1 text

Kyome macOS native Symposium #08 2022/08/27 (Sat) Hacking Xcode Behaviors

Slide 2

Slide 2 text

ࣗݾ঺հ IUUQTLZPNFJP ,ZPNF ,ZPNFTVLF macOS޲͚ͷϢʔςΟϦςΟΞϓϦ։ൃऀʢझຯ݉෭ۀʣ ϝχϡʔόʔৗறܕΞϓϦɺApp Extension ͕ಘҙ෼໺ OSSϓϩδΣΫτӡӦʹνϟϨϯδத

Slide 3

Slide 3 text

ࣗݾ঺հ RunCat activity indicator HandyPalette color picker ScreenPointer presentation tool ShiftWindow window organizer

Slide 4

Slide 4 text

Xcode Behaviors

Slide 5

Slide 5 text

Xcode Behaviors Build PhasesͷRun ScriptsͰ͸ TARGETͷϏϧυ࣌ʹShell ScriptͰ ॲཧΛڬΈࠐΉ͜ͱ͕Մೳ Linter΍FormatterΛ࣮ߦͨ͠Γɺ
 Ϧιʔε༻ͷSwiftίʔυΛੜ੒ͨ͠ ΓɺϏϧυલͷԼॲཧʹར༻Մೳ ϓϩδΣΫτ͝ͱʹݸผʹࢦఆ͢Δ ΋ͷ Run Scripts

Slide 6

Slide 6 text

Xcode Behaviors Behaviors͸ϓϩδΣΫτ୯ҐͰ͸
 ͳ͘ɺXcodeͰ։͘͢΂ͯͷϓϩ δΣΫτʹରͯ͠ɺ֤छΠϕϯτΛ
 τϦΨʔͱ༷ͨ͠ʑͳઃఆ͕Մೳ RunʹShell ScriptΛొ࿥͢Δ͜ͱ ͰɺΠϕϯτͷ։࢝ɾ੒ޭɾࣦഊɾ ग़ྗͳͲͷλΠϛϯάʹ೚ҙͷॲཧ Λ࣮ߦՄೳ Behaviors 😀

Slide 7

Slide 7 text

Xcode Behaviors ݱঢ়ҎԼͷΠϕϯτΛαϙʔτ #VJME 5FTUJOH 3VOOJOH (16'SBNF$BQUVSF 4FBSDI 9DPEF4FSWFS 9DPEFͰαϙʔτऴྃʁ $* 9DPEF$MPVE 'JMF 6OMPDL 1MBZHSPVOET $PSF.- 9DPEF͔Β 
 Behaviors

Slide 8

Slide 8 text

Xcode Behaviors Swift Package Managerʹؔ͢Δ
 Πϕϯτ͸αϙʔτ͞Ε͍ͯͳ͍
 ͷ͕࢒೦ Reset Package Caches Resolve Package Versions Update to Latest Package Versions
 Behaviors 🫤

Slide 9

Slide 9 text

Xcode Behaviors Behaviors 🤔 Կ͔ʹ࢖͑ͦ͏

Slide 10

Slide 10 text

XCHook & XCMonitor

Slide 11

Slide 11 text

XCHook & XCMonitor XCHook͸Xcode BehaviorsͷBuildͱTestingΛϑοΫͯ͠ɺ
 ֎෦ΞϓϦʹ௨஌Λૹ৴Ͱ͖ΔΑ͏ʹ͢ΔSwift Package੡ϥΠϒϥϦ Swift Packageͱͯ͠ར༻Մೳɿhttps://github.com/kyome22/XCHook 􀐛 XcodeͷPreferencesΛॻ͖׵͑ͯɺBehaviorsΠϕϯτʹScriptΛࢦఆ ΠϕϯτΛղऍͯ͠৘ใ੔ܗˍ֎෦ΞϓϦʹ޲͚ͯ௨஌ૹ৴ ௨஌ͷड৴पΓΛ؆୯ʹ͢Δ֎෦ΞϓϦ޲͚ͷAPI

Slide 12

Slide 12 text

XCHook & XCMonitor XCMonitor͸XcodeͷϏϧυͱςετͷΠϕϯτΛ؂ࢹͯ͠
 ϩάΛऩूͰ͖Δϝχϡʔόʔৗறܕπʔϧ GitHub͔ΒΞϓϦΛΠϯετʔϧՄೳɿhttps://github.com/kyome22/XCMonitor 􁓵 ɹ ঢ়ଶΛϦΞϧλΠϜʹ൓ө

Slide 13

Slide 13 text

XCHook & XCMonitor ऴ͓ྃͯ͘͠ 􀐛 XCHook XCMonitor Xcode XcodeͷPreferencesΛ্ॻ͖ͯ͠
 ScriptΛ֤ΠϕϯτͷRun߲໨ʹࢦఆ͢Δ ؀ڥઃఆ͔ΒXCHookΛ༗ޮʹ͢Δ ಋೖฤ Scriptͷ࣮ߦʹඞཁͳԼ४උΛ͢Δ

Slide 14

Slide 14 text

XCHook & XCMonitor BehaviorsͷΠϕϯτൃՐ 􀐛 XCHook XCMonitor Xcode Script͕ΠϕϯτΛղऍͯ͠৘ใΛ੔ܗ ৘ใΛ֎෦ΞϓϦʹ௨஌ͱͯ͠ૹ৴ Xcodeͷىಈঢ়ଶΛ؂ࢹͭͭ͠ɺ௨஌Λৗ࣌଴ػ ड৴࣍ୈɺදࣔΛߋ৽ˍΠϕϯτͷϩάΛஷΊΔ ར༻ฤ

Slide 15

Slide 15 text

vs App Sandboxͷน

Slide 16

Slide 16 text

vs App Sandboxͷน XCMonitor Xcode 􀙦 App Sandbox App Sandbox͸ɺΞϓϦ͕ΞΫηεՄೳͳྖҬΛ੍ݶ͢Δ͜ͱͰɺ
 γεςϜͷϦιʔεͱϢʔβʔͷσʔλΛอޢ͢ΔͨΊͷ΋ͷ ֎෦ΞϓϦΛૢ࡞ͨ͠Γঢ়ଶΛऔಘ͢Δ͜ͱ͸௨ৗෆՄೳ ࣗ࡞ΞϓϦͷ৔߹ɺApp Sandboxͷ༗ޮ/ແޮ͸։ൃऀʹҕͶΒΕ͍ͯΔ Xcode͸App Sandboxʹอޢ͞Ε͍ͯΔͨΊɺ֎෦͔ΒΞΫηεͰ͖ͳ͍

Slide 17

Slide 17 text

vs App Sandboxͷน Xcodeଆ͔Β֎෦ΞϓϦʹ޲͚ͯ߹๏తʹσʔλΛૹ৴͢Δ࢓૊Έ͕ඞཁ BehaviorsͷRun ScriptͰShell ScriptΛ࣮ߦ ͞ΒʹShell Script಺ͰSwiftͷεΫϦϓτΛ࣮ߦ͠
 DistributedNoti fi cationCenterͰ֎෦ΞϓϦʹ޲͚৘ใΛൃ৴ XCMonitor Xcode 􀙦 App Sandbox 􀐕 Behaviors >_ Shell Script Swift Script 􀫊

Slide 18

Slide 18 text

vs App Sandboxͷน XCMonitor Xcode 􀙦 App Sandbox 􀐕 Behaviors >_ Shell Script Swift Script 􀫊 ~/.xchook BehaviorsͷRun ScriptͰεΫϦϓτΛಈ͔͢৔߹ɺ
 Shell ScriptͱSwiftͷεΫϦϓτʹ͸࣮ߦݖݶΛ෇༩͢Δ chmod 744 ͜ΕΒͷεΫϦϓτ͸ϗʔϜσΟϨΫτϦ௚Լʹ .xchook σΟϨΫτϦΛ
 ࡞੒ͯͦ͜͠ʹ഑ஔ

Slide 19

Slide 19 text

vs App Sandboxͷน XCMonitor Xcode 􀙦 App Sandbox Plist App Sandbox 􀞡 ಋೖϋʔυϧΛԼ͛ΔͨΊɺBehaviorsͷRun ScriptΛࣗಈͰࢦఆ͢Δ
 ࢓૊Έ͕ཉ͍͠ Preferencesͷ಺༰͸ ~/Library/Preferences/com.apple.dt.Xcode.plist 
 ʹอଘ͞ΕΔ App SandboxΛແޮʹ͢Ε͹ɺ֎෦ΞϓϦ͔ΒϑΝΠϧΛಡΈॻ͖Մೳ

Slide 20

Slide 20 text

vs App Sandboxͷน ಋೖϋʔυϧΛԼ͛ΔͨΊɺBehaviorsͷRun ScriptΛࣗಈͰࢦఆ͢Δ
 ࢓૊Έ͕ཉ͍͠ Preferencesͷ಺༰͸ ~/Library/Preferences/com.apple.dt.Xcode.plist 
 ʹอଘ͞ΕΔ App SandboxΛແޮʹ͢Ε͹ɺ֎෦ΞϓϦ͔ΒϑΝΠϧΛಡΈॻ͖Մೳ XCMonitor Xcode 􀙦 App Sandbox Plist App Sandbox 􀞡 Full Access

Slide 21

Slide 21 text

ϓϩδΣΫτύεͷऔಘ

Slide 22

Slide 22 text

ϓϩδΣΫτύεͷऔಘ ϓϩδΣΫτ໊ͱύεΛޙͰར༻͢ΔͨΊɺRun ScriptͷதͰऔಘ͍ͨ͠ XcodeͰ։͘ϓϩδΣΫτܗࣜʹ͸ɺXcode Projectʢ .xcodeproj ʣͱ
 Xcode Workspaceʢ .xcworkspace ʣͱ Swift Package ͷ̏छྨ͕͋Δ Run ScriptͷதͰར༻Մೳͳ؀ڥม਺Λ׆༻ͯ͠ύεΛղੳ

Slide 23

Slide 23 text

ϓϩδΣΫτύεͷऔಘ Run ScriptΛ࣮ߦͨ͠ࡍͷ؀ڥม਺ Xcode Projectͷ৔߹ ؀ڥม਺ ஋ XcodeProject PROJECT_NAME.xcodeproj XcodeProjectPath PROJECT_ROOT/PROJECT_NAME.xcodeproj XcodeWorkspacePath PROJECT_ROOT/PROJECT_NAME.xcodeproj/project.xcworkspace PWD PROJECT_ROOT * PROJECT_ROOT = ϓϩδΣΫτͷϧʔτͷઈରύε * PROJECT_NAME = ϓϩδΣΫτ໊

Slide 24

Slide 24 text

ϓϩδΣΫτύεͷऔಘ Run ScriptΛ࣮ߦͨ͠ࡍͷ؀ڥม਺ Xcode Workspaceͷ৔߹ʢCocoaPodsΛ࢖͍ͬͯΔͳͲʣ ؀ڥม਺ ஋ XcodeWorkspace PROJECT_NAME.xcworkspace XcodeWorkspacePath PROJECT_ROOT/PROJECT_NAME.xcworkspace PWD PROJECT_ROOT * PROJECT_ROOT = ϓϩδΣΫτͷϧʔτͷઈରύε * PROJECT_NAME = ϓϩδΣΫτ໊

Slide 25

Slide 25 text

ϓϩδΣΫτύεͷऔಘ Run ScriptΛ࣮ߦͨ͠ࡍͷ؀ڥม਺ Swift Packageܗࣜͷ৔߹ ؀ڥม਺ ஋ XcodeWorkspace package.xcworkspace XcodeWorkspacePath PROJECT_ROOT/.swiftpm/xcode/package.xcworkspace PWD PROJECT_ROOT/.swiftpm/xcode * PROJECT_ROOT = ϓϩδΣΫτͷϧʔτͷઈରύε

Slide 26

Slide 26 text

ϓϩδΣΫτύεͷऔಘ if (؀ڥม਺XcodeProject͕औಘՄೳ) { Xcode Project } else if (xcworkspaceϑΝΠϧͷ໊લ͕package.xcworkspace) { Swift Package } else { Xcode Workspace } Run ScriptΛ࣮ߦͨ͠ࡍͷ؀ڥม਺ͷಛ௃ ؀ڥม਺ XcodeProject ͕औಘͰ͖Δͷ͸Xcode Projectܗࣜͷ৔߹ͷΈ Swift Packageܗࣜͷ৔߹ɺxcworkspaceϑΝΠϧͷ໊લ͸
 package.xcworkspace Ͱݻఆ

Slide 27

Slide 27 text

ϓϩδΣΫτύεͷऔಘ ҎԼͷShell ScriptͰϓϩδΣΫτ໊ͱύε͕औಘͰ͖Δ #!/bin/sh - if [ "$XcodeProject" ]; then # Normal Xcode Project PROJECT_NAME=`basename "$XcodeProject" .xcodeproj` PROJECT_PATH=$XcodeProjectPath elif [ "$XcodeWorkspace" = "package.xcworkspace" ]; then # Swift Package Library PROJECT_NAME=`basename $(dirname "$XcodeWorkspacePath" | sed -r "s/\.swiftpm.+//")` PROJECT_PATH=$XcodeWorkspacePath else # XCWorkspace (Probably using CocoaPods.) PROJECT_NAME=`basename "$XcodeWorkspace" .xcworkspace` PROJECT_PATH=$XcodeWorkspacePath fi ࢀরɿhttps://github.com/Kyome22/XCHook/blob/main/Sources/XCHook/run_scripts/build_start.sh

Slide 28

Slide 28 text

XcodeͷPreferencesΛ ॻ͖׵͑Δ

Slide 29

Slide 29 text

XcodeͷPreferencesΛॻ͖׵͑Δ Preferencesͷσʔλ͸ ~/Library/Preferences/com.apple.dt.Xcode.plist ʹ
 อଘ͞Ε͓ͯΓɺ͜ΕʹखΛՃ͑Ε͹ྑ͍ BinaryܗࣜͷProperty ListͷͨΊɺςΩετΤσΟλͰ։͍ͯ΋ಡΊͳ͍ XcodeͰ։͘ͱಡΈॻ͖͕Ͱ͖Δ͕ɺ਺ेඵʹҰ౓ͷස౓ͰϦϩʔυ͞Ε
 දࣔߏ଄͕มΘΔͷͰखಈͰฤू͢Δͷ͸ࠔ೉
 ʢࣙॻܕ͸ॱংΛอূ͠ͳ͍ͨΊϩʔυͷͨͼʹॱং͕มΘΓಘΔʣ

Slide 30

Slide 30 text

XcodeͷPreferencesΛॻ͖׵͑Δ { "Xcode.AlertEvents.4_1": { "Xcode.AlertEvents.BuildStart": { "Xcode.Alert.RunScript": { "enabled": boolean, "path": "Shell Scriptͷύε" } }, "Xcode.AlertEvents.TestingSucceeds": { "Xcode.Alert.RunScript": { "enabled": boolean, "path": "Shell Scriptͷύε" } } } } Plist ͷ಺༰ΛJSONܗࣜͰൈਮͨ͠΋ͷ BehaviorsʹRun ScriptΛઃఆ͢Δʹ͸ɺ Xcode.AlertEvents ͱ Xcode.AlertEvents.4_1 ͷ಺༰Λॻ͖׵͑Ε͹ྑ͍ ྫ͑͹ɺXcode.AlertEvent.BuildStart ͷத ͷ Xcode.Alert.RunScript ʹ࣮ߦ͍ͨ͠
 Shell ScriptͷύεΛॻ͖ࠐΉ

Slide 31

Slide 31 text

XcodeͷPreferencesΛॻ͖׵͑Δ { "Xcode.AlertEvents.4_1": { "Xcode.AlertEvents.BuildStart": { "Xcode.Alert.RunScript": { "enabled": boolean, "path": "Shell Scriptͷύε" } }, "Xcode.AlertEvents.TestingSucceeds": { "Xcode.Alert.RunScript": { "enabled": boolean, "path": "Shell Scriptͷύε" } } } } Plist ͷ಺༰ΛJSONܗࣜͰൈਮͨ͠΋ͷ BehaviorsʹRun ScriptΛઃఆ͢Δʹ͸ɺ Xcode.AlertEvents ͱ Xcode.AlertEvents.4_1 ͷ಺༰Λॻ͖׵͑Ε͹ྑ͍ ྫ͑͹ɺXcode.AlertEvent.BuildStart ͷத ͷ Xcode.Alert.RunScript ʹ࣮ߦ͍ͨ͠
 Shell ScriptͷύεΛॻ͖ࠐΉ ֊૚ߏ଄ͷਂ͍෦෼ͷॻ͖׵͕͑ඞཁ ଞͷ෦෼͸ͦͷ··อ͍ͪͨ

Slide 32

Slide 32 text

XcodeͷPreferencesΛॻ͖׵͑Δ 4_1 ͬͯͳΜͩʁ 🧐 Xcode.AlertEvents ͱ Xcode.AlertEvents.4_1 ͸΄΅ಉ͡σʔλߏ଄͕ͩɺ
 ͓ͦΒ͘໾ׂ͕ҧ͏ Xcode.AlertEvents.4_1 ͸Ϣʔβʔ͕ࢦఆͨ͠શͯͷઃఆ͕ೖΔͷͰຊମ Xcode.AlertEvents ͸4_1ͷόοΫΞοϓʁʢҰ෦ͷઃఆ͚͕ͩೖΔʣ

Slide 33

Slide 33 text

XcodeͷPreferencesΛॻ͖׵͑Δ Command LineͰProperty ListΛॻ͖׵͑Δ৔߹ɺplutil ΍ PlistBuddy Λ
 ࢖༻͢Δ͜ͱ͕ଟ͍ plutil ͸̍֊૚໨·Ͱ͔͠௚઀ૢ࡞Ͱ͖ͳ͍ 😩 → ࿦֎ PlistBuddy ͸̎֊૚Ҏ্͋ͬͯ΋ૢ࡞͕Մೳ 😃 อଘܗ͕ࣜXMLʹͳͬͯ͠·͏ ☹ ্ॻ͖͍ͨ͠ՕॴͷΈΛॻ͖׵͑ΔΑ͏ͳϚʔδ͕Ͱ͖ͳ͍ 🤯
 ʢ߲̍໨ͣͭͷॻ͖׵͑ͱ·ͩଘࡏ͍ͯ͠ͳ͍σʔλͷ௥Ճ͸Ͱ͖Δʣ

Slide 34

Slide 34 text

্ॻ͖͍ͨ͠ՕॴͷΈΛॻ͖׵͑ΔΑ͏ͳϚʔδ͕Ͱ͖ͳ͍ͷҙຯ XcodeͷPreferencesΛॻ͖׵͑Δ { "Apple": { "Price": 100, "Color": "Green" }, "Banana": { "Price": 100, "Color": "Yellow" }, "Cherry": { "Price": 100, "Color": "Red" } } { "Apple": { "Price": 150 }, "Banana": { "Price": 150 }, "Cherry": { "Price": 150 } } { "Apple": { "Price": 150, "Color": "Green" }, "Banana": { "Price": 150, "Color": "Yellow" }, "Cherry": { "Price": 150, "Color": "Red" } } ΦϦδφϧ ॻ͖׵͍͑ͨ಺༰ ཧ૝ͷϚʔδ݁Ռ

Slide 35

Slide 35 text

্ॻ͖͍ͨ͠ՕॴͷΈΛॻ͖׵͑ΔΑ͏ͳϚʔδ͕Ͱ͖ͳ͍ͷҙຯ XcodeͷPreferencesΛॻ͖׵͑Δ { "Apple": { "Price": 100, "Color": "Green" }, "Banana": { "Price": 100, "Color": "Yellow" }, "Cherry": { "Price": 100, "Color": "Red" } } { "Apple": { "Price": 150 }, "Banana": { "Price": 150 }, "Cherry": { "Price": 150 } } ΦϦδφϧ ॻ͖׵͍͑ͨ಺༰ طʹಉ໊ͷΩʔ͕ଘࡏͯ͠
 ͍Δ৔߹Ϛʔδ͕Ͱ͖ͳ͍ PlistBuddyͰͷϚʔδ݁Ռ

Slide 36

Slide 36 text

XcodeͷPreferencesΛॻ͖׵͑Δ let saveURL = URL(fileURLWithPath: "sample.plist") var dict: [String: Any] = [:] // dictΛฤूʢதུʣ let data = try! PropertyListSerialization.data(fromPropertyList: dict, format: .binary, options: .zero) try! data.write(to: saveURL, options: .atomic) طଘͷCommand LineπʔϧΛ࢖ΘͣSwiftͰࣗલ࣮૷͢Δ SwiftͰProperty ListΛॻ͖׵͑Δ৔߹ɺPropertyListSerialization Λ࢖͑͹
 BinaryܗࣜͷProperty ListΛฤूՄೳ

Slide 37

Slide 37 text

҆શͷͨΊɺProperty Listͷॻ͖׵͑͸Xcodeඇىಈ࣌ʹߦ͏ Xcodeͷىಈதʹॻ͖׵͑ͯ΋ଈ࣌൓ө͞Εͳ͍ Ұ౓ऴྃͯ͠࠶ىಈ͢Δͱ൓ө͞ΕΔ XcodeͷPreferencesΛॻ͖׵͑Δ

Slide 38

Slide 38 text

ΠϕϯτͷώετϦʔΛ 
 ਖ਼͍͠ॱংͰऔಘ͢Δ

Slide 39

Slide 39 text

ΠϕϯτͷώετϦʔΛਖ਼͍͠ॱংͰऔಘ͢Δ ͍͟ɺXcodeͷΠϕϯτΛ؂ࢹͯ͠ϩάΛऩूͯ͠ΈΔͱɺ
 ͨ·ʹΠϕϯτͷಧ͘ॱং͕લޙͯ͠͠·͏͜ͱʹؾ͍ͮͨ 􀙄 􀊄 Ϗϧυ։࢝ 􀙄 Ϗϧυ੒ޭ 􁁛 ςετ੒ޭ 􀙄 􀊄 Ϗϧυ։࢝ 􀙄 Ϗϧυ੒ޭ 􁁛 ςετ੒ޭ ٯॱʹͳ͍ͬͯΔ😫 ςετ։࢝ 􁁚 􀊄 ςετ։࢝ 􁁚 􀊄

Slide 40

Slide 40 text

ςετ։࢝ 􁁚 􀊄 ΠϕϯτͷώετϦʔΛਖ਼͍͠ॱংͰऔಘ͢Δ Run Scriptͷ࣮ߦ͸ΠϕϯτͷൃՐ࣌Ͱ͸͋Δ͕ɺஞ࣍ॲཧͰ͸ͳ͘ฒྻॲཧ ͞ΕΔͨΊɺRun Scriptͷ࣮ߦ׬ྃΛ଴ͨͣʹΠϕϯτ͕ਐΉ 􀙄 􀊄 Ϗϧυ։࢝ ஞ࣍ॲཧͷΠϝʔδ 􀙄 Ϗϧυ੒ޭ 􀙄 Ϗϧυ Run Script A >_ Run Script B >_

Slide 41

Slide 41 text

ΠϕϯτͷώετϦʔΛਖ਼͍͠ॱংͰऔಘ͢Δ Run Scriptͷ࣮ߦ͸ΠϕϯτͷൃՐ࣌Ͱ͸͋Δ͕ɺஞ࣍ॲཧͰ͸ͳ͘ฒྻॲཧ ͞ΕΔͨΊɺRun Scriptͷ࣮ߦ׬ྃΛ଴ͨͣʹΠϕϯτ͕ਐΉ 􀙄 􀊄 Ϗϧυ։࢝ 􀙄 Ϗϧυ੒ޭ Run Script A ςετ։࢝ 􁁚 􀊄 􀙄 Ϗϧυ Run Script B ฒྻॲཧͷΠϝʔδ ࣍ͷॲཧʹॏͳ͍ͬͯΔ

Slide 42

Slide 42 text

Run Scriptͷ࣮ߦ͸ΠϕϯτͷൃՐ࣌Ͱ͸͋Δ͕ɺஞ࣍ॲཧͰ͸ͳ͘ฒྻॲཧ ͞ΕΔͨΊɺRun Scriptͷ࣮ߦ׬ྃΛ଴ͨͣʹΠϕϯτ͕ਐΉ ͠͹͠͹Πϕϯτͷॱং͕લޙ͢Δݱ৅͕ى͖ಘΔ
 ʢApple Silicon MacͷϏϧυ͕ߴ଎͗ͯ͢௨஌ॲཧͷํ͕ෛ͚Δʁʣ ΠϕϯτͷώετϦʔΛਖ਼͍͠ॱংͰऔಘ͢Δ 􀙄 􀊄 Ϗϧυ։࢝ 􀙄 Ϗϧυ੒ޭ Run Script A ςετ։࢝ 􁁚 􀊄 􀙄 Ϗϧυ Run Script B ॲཧͷ׬͕ྃٯస

Slide 43

Slide 43 text

ΠϕϯτͷώετϦʔΛਖ਼͍͠ॱংͰऔಘ͢Δ Πϕϯτͷ௨஌ॱংΛอূ͢ΔͨΊɺಧ͍ͨॱ͸৴༻ͤͣɺ
 λΠϜελϯϓΛجʹ౎౓ฒͼସ͑Δ ࣮ߦ͢ΔShell Scriptͷ๯಄Ͱ date ίϚϯυΛ࢖ͬͯλΠϜελϯϓΛ
 औಘͯ͠Έͨ

Slide 44

Slide 44 text

ΠϕϯτͷώετϦʔΛਖ਼͍͠ॱংͰऔಘ͢Δ Πϕϯτͷ௨஌ॱংΛอূ͢ΔͨΊɺಧ͍ͨॱ͸৴༻ͤͣɺ
 λΠϜελϯϓΛجʹ౎౓ฒͼସ͑Δ ࣮ߦ͢ΔShell Scriptͷ๯಄Ͱ date ίϚϯυΛ࢖ͬͯλΠϜελϯϓΛ
 औಘͯ͠Έͨ ҰॠͰϏϧυ͕׬ྃ͢Δ৔߹ɺ໰୊ΛղফͰ͖ͳ͔ͬͨ 😧 macOS ͷ date ίϚϯυ͸ϛϦඵϨϕϧ·ͰऔಘͰ͖ͳ͍͜ͱ͕൑໌

Slide 45

Slide 45 text

ΠϕϯτͷώετϦʔΛਖ਼͍͠ॱংͰऔಘ͢Δ ϛϦඵϨϕϧͷλΠϜελϯϓΛऔಘ͍ͨ͠ 1. HomebrewͰcoreutilsΛΠϯετʔϧͯ͠ gdate ίϚϯυΛ࢖͏ XCHook͸Swift PackageϥΠϒϥϦͳͷͰHomebrewʹཔΓͨ͘ͳ͍ 🙅

Slide 46

Slide 46 text

ϛϦඵϨϕϧͷλΠϜελϯϓΛऔಘ͍ͨ͠ 2. macOSʹϓϦΠϯετʔϧ͞Ε͍ͯΔPerlΛ࢖ͬͯϛϦඵ·Ͱग़ྗ͢Δ কདྷతʹPerlɺPythonɺRuby͕macOSͷϓϦΠϯετʔϧର৅͔Β
 ֎ΕΔͱ͍͏࿩͕͋ΔͷͰආ͚͍ͨ 🙅 ΠϕϯτͷώετϦʔΛਖ਼͍͠ॱংͰऔಘ͢Δ ࢀরɿhttps://developer.apple.com/documentation/macos-release-notes/macos-catalina-10_15-
 ɹɹɹrelease-notes#Scripting-Language-Runtims

Slide 47

Slide 47 text

ϛϦඵϨϕϧͷλΠϜελϯϓΛऔಘ͍ͨ͠ 3. CݴޠͰϛϦඵ·Ͱग़ྗ͢ΔίʔυΛ༻ҙ͓͍ͯͯ͠ɺ
 ؀ڥ͝ͱʹϏϧυ͠ɺ࣮ߦϑΝΠϧΛར༻͢Δ CݴޠͳΒϓϦΠϯετʔϧ͔Β֎͞Εͳ͍ʢ͸ͣ ࣮֬ʹϛϦඵ·ͰऔಘͰ͖Δ ϓϩηοα͕ҟͳΔͱ࣮ߦϑΝΠϧ͕ಈ࡞͠ͳ͍ͨΊಋೖ࣌ʹϏϧυ͢Δ
 ʢApple Silicon MacͰϏϧυ࣮ͨ͠ߦϑΝΠϧ͸Intel MacͰಈ͔ͳ͍ʣ ΠϕϯτͷώετϦʔΛਖ਼͍͠ॱংͰऔಘ͢Δ 👌

Slide 48

Slide 48 text

ΠϕϯτͷώετϦʔΛਖ਼͍͠ॱংͰऔಘ͢Δ func run(_ args: String...) { let task = Process() task.launchPath = "/bin/sh" task.arguments = ["-c", args.joined(separator: " ")] task.launch() task.waitUntilExit() } run("gcc", "timestamp.c", "-o", "ts") CݴޠͰϛϦඵϨϕϧͷλΠϜελϯϓΛऔಘ͢ΔʢϏϧυฤʣ Process() Λ࢖ͬͯSwift͔ΒShellΛୟ͘ ༻ҙ͓͍ͯͨ͠CݴޠͷίʔυΛ gcc ͰίϯύΠϧ͢Δ

Slide 49

Slide 49 text

CݴޠͰϛϦඵϨϕϧͷλΠϜελϯϓΛऔಘ͢Δʢ࣮ߦฤʣ ίϯύΠϧ࣮ͨ͠ߦϑΝΠϧΛ ~/.xchook ʹஔ͍͓ͯ͘ Run Scriptͷ࣮ߦ࣌ʹShell Scriptͷ๯಄Ͱ࣮ߦϑΝΠϧΛ࢖͏ ΠϕϯτͷώετϦʔΛਖ਼͍͠ॱংͰऔಘ͢Δ XCMonitor Xcode 􀙦 App Sandbox 􀐕 Behaviors >_ Shell Script Swift Script 􀫊 ~/.xchook $ C fi le &

Slide 50

Slide 50 text

೚ҙͷϓϩδΣΫτ΢Πϯυ΢Λ 
 ࠷લ໘ʹදࣔͤ͞Δ

Slide 51

Slide 51 text

೚ҙͷϓϩδΣΫτ΢Πϯυ΢Λ࠷લ໘ʹදࣔͤ͞Δ Ϗϧυ͕׬ྃͨ͜͠ͱ΍ςετ͕ऴΘͬͨ͜ͱΛXCMonitorͰ஌ͬͨޙʹ
 ͦͷϓϩδΣΫτͷ΢Πϯυ΢Λ࠷લ໘ʹදࣔͤ͞Δػೳ͕ཉ͘͠ͳͬͨ ֎෦ΞϓϦͷ΢Πϯυ΢͸؅׋֎ͷͨΊ௨ৗ͸੍ޚͰ͖ͳ͍
 ʢApp SandboxΛແޮʹͯ͠Accessibility APIΛ࢖ͬͯ΋ͳ͓೉͍͠ʣ

Slide 52

Slide 52 text

೚ҙͷϓϩδΣΫτ΢Πϯυ΢Λ࠷લ໘ʹදࣔͤ͞Δ Ϗϧυ͕׬ྃͨ͜͠ͱ΍ςετ͕ऴΘͬͨ͜ͱΛXCMonitorͰ஌ͬͨޙʹ
 ͦͷϓϩδΣΫτͷ΢Πϯυ΢Λ࠷લ໘ʹදࣔͤ͞Δػೳ͕ཉ͘͠ͳͬͨ ֎෦ΞϓϦͷ΢Πϯυ΢͸؅׋֎ͷͨΊ௨ৗ͸੍ޚͰ͖ͳ͍
 ʢApp SandboxΛແޮʹͯ͠Accessibility APIΛ࢖ͬͯ΋ͳ͓೉͍͠ʣ ൃ૝Λม͑ͯɺϓϩδΣΫτϑΝΠϧΛXcodeͰ։͘͜ͱͰ
 ࠷લ໘ʹ΢Πϯυ΢Λදࣔͤ͞Δ͜ͱʹͨ͠
 ʢ೚ҙͷϑΝΠϧΛ೚ҙͷΞϓϦͰ։͘ͷ͸App Sandbox؀ڥͰ΋Մೳ)

Slide 53

Slide 53 text

೚ҙͷϓϩδΣΫτ΢Πϯυ΢Λ࠷લ໘ʹදࣔͤ͞Δ ϓϩδΣΫτϑΝΠϧΛXcodeͰ։͘ NSWorkspace.shared.openApplication(at:con fi guration:) Ͱ͸
 XcodeΛ։͚ͩ͘Ͱ೚ҙͷϑΝΠϧ͸։͚ͳ͍ NSWorkspace.shared.open(_:withApplicationAt:con fi guration:) Ͱ
 ϑΝΠϧͷύεͱΞϓϦͷύε૒ํΛࢦఆͯ͠։͘ ͜ͷ࣌ͷͨΊʹRun ScriptͰϓϩδΣΫτϑΝΠϧͷύεΛऔಘ͍ͯͨ͠

Slide 54

Slide 54 text

Run Scriptͷσόοάํ๏

Slide 55

Slide 55 text

Run Scriptͷσόοάํ๏ BehaviorsͷRun Scriptʹ͓͍ͯඪ४ग़ྗ͸֬ೝͷํ๏͕ͳ͍
 cat ΍ echo ίϚϯυɺSwift.print() Λ࢖ͬͯ΋֬ೝͰ͖Δ৔ॴʹग़ྗ͞Εͳ͍ Console.appͰϩάϝοηʔδΛ֬ೝ͢Δ Shell ScriptͰ͸ logger -s Λ࢖͏ SwiftͷεΫϦϓτͰ͸ NSLog() Λ࢖͏ Console.app

Slide 56

Slide 56 text

Run Scriptͷσόοάํ๏ Console.appͰϩάϝοηʔδΛ֬ೝ͢Δ ֆจࣈΛ࢖͏ͱߜΓࠐΈ΍͍͢😋

Slide 57

Slide 57 text

·ͱΊ XcodeͷϏϧυͱςετͷΠϕϯτΛϑοΫͯ͠௨஌͢Δ࢓૊ΈΛ
 Swift PackageͰ࡞ͬͨΑʙ 👆ͷσϞΞϓϦͱͯ͠ϏϧυͱςετͷϩάΛ؂ࢹ͢Δ
 ϝχϡʔόʔৗறܕΞϓϦΛ࡞ͬͯ഑෍͍ͯ͠ΔΑʙ App SandboxͷนΛճආͨ͠ΓɺProperty ListΛॻ͖׵͑ͨΓɺ
 ΠϕϯτऔಘͷॱংΛอূ͢ΔͷʹςΫχοΫ͕ඞཁͩͬͨΑʙ Thank you!