├── Xcode Selector.workflow └── Contents │ ├── Info.plist │ ├── QuickLook │ └── Thumbnail.png │ └── document.wflow ├── readme.md ├── screenshot.png └── screenshot2.png /Xcode Selector.workflow/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSServices 6 | 7 | 8 | NSMenuItem 9 | 10 | default 11 | Xcode Selector 2 12 | 13 | NSMessage 14 | runWorkflowAsService 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Xcode Selector.workflow/Contents/QuickLook/Thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macandyp/XcodeSelector/9590c173d9bf38da1fd0255372c918f608e1a9e4/Xcode Selector.workflow/Contents/QuickLook/Thumbnail.png -------------------------------------------------------------------------------- /Xcode Selector.workflow/Contents/document.wflow: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AMApplicationBuild 6 | 428 7 | AMApplicationVersion 8 | 2.7 9 | AMDocumentVersion 10 | 2 11 | actions 12 | 13 | 14 | action 15 | 16 | AMAccepts 17 | 18 | Container 19 | List 20 | Optional 21 | 22 | Types 23 | 24 | com.apple.applescript.object 25 | 26 | 27 | AMActionVersion 28 | 1.0.2 29 | AMApplication 30 | 31 | Automator 32 | 33 | AMParameterProperties 34 | 35 | source 36 | 37 | 38 | AMProvides 39 | 40 | Container 41 | List 42 | Types 43 | 44 | com.apple.applescript.object 45 | 46 | 47 | ActionBundlePath 48 | /System/Library/Automator/Run AppleScript.action 49 | ActionName 50 | Run AppleScript 51 | ActionParameters 52 | 53 | source 54 | #################################################################### #################################################################### ## ## Created By: James Headrick ## Date: 29 Sept 2016 ## Modified: 5 Oct 2016 ## Version: 1.0 ## ## Description: This utility is will recursively search the /Applications directory for ## files with "Xcode" in the name. It will: ## 1. Prompt the user to select a version ## 2. Quit running versions of Xcode ## 3. Run xcode-select to select the proper toolchain ## 4. Open the selected version of Xcode ## #################################################################### #################################################################### #### Global Variables 😳 global xcodeCount global totalStepCount global currentStepCount global foundPaths on run initializeVariables() set progress total steps to totalStepCount updateStepCount() set progress additional description to "Beginning Xcode Selection" prepareFilePathsForDisplay(getXcodeVersionsInDefaultDirectory()) set progress description to "Select a version of Xcode" set currentXcode to getCurrentXcodeSelectVersion() set xcodePrompt to "Select a version of Xcode" if (count of characters in currentXcode) is greater than 0 then set xcodePrompt to xcodePrompt & return & "Current Selection: " & currentXcode & return end if chooseAVersion(foundPaths, xcodePrompt) end run on initializeVariables() set progress description to "Preparing..." set xcodeCount to 0 set totalStepCount to 6 set currentStepCount to 0 set foundPaths to {} end initializeVariables on updateStepCount() set progress completed steps to currentStepCount set currentStepCount to currentStepCount + 1 end updateStepCount on ensureMinimumQuantityOfChoices(xcodePathList) ## This is to ensure the initial Xcode choice isn't too small and truncated if (count of xcodePathList) is less than 5 then log "less than 5" repeat (5 - (count of xcodePathList)) times set xcodePathList to xcodePathList & "" end repeat end if return xcodePathList end ensureMinimumQuantityOfChoices on prepareFilePathsForDisplay(itemsFound) set searchAdditionalDirsString to "Search a Different Directory..." set cleanList to {} # remove old filler choices from list repeat with listItem in foundPaths if listItem as string is not equal to "" and listItem as string is not equal to searchAdditionalDirsString as string then set cleanList's end to listItem end if end repeat # reset foundPaths set foundPaths to cleanList #display alert contents of foundPaths # append newly found Xcodes repeat with itemFound in itemsFound tell application "System Events" set foundPath to (POSIX path of itemFound as text) end tell set addToList to true repeat with aPath in foundPaths if aPath as text is equal to foundPath as text then set addToList to false end if end repeat if addToList is true then set end of foundPaths to foundPath end if end repeat set end of foundPaths to searchAdditionalDirsString set foundPaths to ensureMinimumQuantityOfChoices(foundPaths) end prepareFilePathsForDisplay on chooseAVersion(foundXcodePaths, userPrompt) tell application "System Events" activate set chosenVersion to (choose from list foundPaths with title "Xcode Selector" with prompt userPrompt default items "None" OK button name "Continue" cancel button name "Cancel") end tell if chosenVersion is not false then if (count of characters of (first item of chosenVersion)) is 0 then chooseAVersion(foundXcodePaths, userPrompt) else if first item in chosenVersion is "Search a Different Directory..." then activate set selectedDirectory to "" try set selectedDirectory to choose folder on error log "crap" end try if (count of characters of (selectedDirectory as text)) is greater than 0 then set itemsFound to recursiveFolderSearch(selectedDirectory) prepareFilePathsForDisplay(itemsFound) end if chooseAVersion(foundPaths, userPrompt) else quitXcode() selectXcodeVersion(first item in chosenVersion) end if end if end chooseAVersion #################################################################### ### Manage Xcode Interaction #################################################################### on getCurrentXcodeSelectVersion() updateStepCount() try set currentVersion to (do shell script "xcode-select -p") log currentVersion set currentXcode to text beginning thru ((offset of ".app/" in currentVersion) + 3) of currentVersion log currentXcode return currentXcode on error errMsg number errNum log errNum & ": " & errMsg return "" end try end getCurrentXcodeSelectVersion on selectXcodeVersion(selectedVersion) activate set pathToXcode to quoted form of POSIX path of selectedVersion try updateStepCount() set progress description to "Switching Xcode Toolchain" do shell script "sudo xcode-select -switch " & pathToXcode with administrator privileges display notification with title "Successfully set Xcode Version" subtitle selectedVersion sound name "Submarine" startSelectedXcodeVersion(pathToXcode) on error error_message number error_number set progress description to "Error: " & error_message as text display alert "Failed to set the current version of Xcode" message "Error " & (error_number as text) & ": " & (error_message as text) as critical giving up after 10 end try end selectXcodeVersion on quitXcode() # Quit all apps associated with a specific version of Xcode updateStepCount() set progress description to "Attempting to quit running versions of Xcode" set progress description to "Quitting Xcode" try do shell script "killall Xcode" end try set progress description to "Quitting iOS Simulator" try do shell script "killall Simulator" end try set progress description to "Quitting watchOS Simulator" try do shell script "killall 'Simulator (Watch)'" end try set progress description to "Quitting Xcode Server Builder" try do shell script "killall 'Xcode Server Builder'" end try set progress description to "Quitting DesktopReplayer" try do shell script "killall DesktopReplayer" end try end quitXcode on startSelectedXcodeVersion(selectedVersionPath) updateStepCount() set progress description to "Opening Xcode" do shell script "open " & selectedVersionPath end startSelectedXcodeVersion #################################################################### #################################################################### ### Search recursively for Xcode in applications folder #################################################################### on getXcodeVersionsInDefaultDirectory() updateStepCount() set progress description to "Looking for Xcode..." set applicationsDirectory to path to applications folder as alias # Search applications directory and subdirectories for Xcode set xcodeList to recursiveFolderSearch(applicationsDirectory) return xcodeList end getXcodeVersionsInDefaultDirectory on recursiveFolderSearch(currentDirectory) set progress description to "Searching for Xcode in " & currentDirectory as text set xcodeList to searchFolderForXcode(currentDirectory) tell application "System Events" set folderNames to name of every folder in currentDirectory end tell repeat with currentFolder in folderNames set newFolderPath to (((currentDirectory as text) & currentFolder & ":") as alias) set progress description to "Searching for Xcode in " & newFolderPath set xcodeList to xcodeList & recursiveFolderSearch(newFolderPath) end repeat return xcodeList end recursiveFolderSearch on searchFolderForXcode(chosenFolder) tell application "System Events" set xcodes to (every file of chosenFolder) whose (name contains "Xcode" and name ends with ".app") set xcodeCount to xcodeCount + (count of xcodes) set foundString to "Found " & xcodeCount & " versions of Xcode" end tell set progress additional description to foundString as string tell application "System Events" return xcodes end tell end searchFolderForXcode #################################################################### 55 | 56 | BundleIdentifier 57 | com.apple.Automator.RunScript 58 | CFBundleVersion 59 | 1.0.2 60 | CanShowSelectedItemsWhenRun 61 | 62 | CanShowWhenRun 63 | 64 | Category 65 | 66 | AMCategoryUtilities 67 | 68 | Class Name 69 | RunScriptAction 70 | InputUUID 71 | 7A11623A-A2BA-4CAE-A033-51F953A989DC 72 | Keywords 73 | 74 | Run 75 | 76 | OutputUUID 77 | 073EFD9C-5C45-4893-B72E-5E3847E325D6 78 | UUID 79 | D975C9FA-9DB3-48F6-8333-0BF4BC0160CD 80 | UnlocalizedApplications 81 | 82 | Automator 83 | 84 | arguments 85 | 86 | 0 87 | 88 | default value 89 | on run {input, parameters} 90 | 91 | (* Your script goes here *) 92 | 93 | return input 94 | end run 95 | name 96 | source 97 | required 98 | 0 99 | type 100 | 0 101 | uuid 102 | 0 103 | 104 | 105 | conversionLabel 106 | 0 107 | isViewVisible 108 | 109 | location 110 | 673.500000:316.000000 111 | nibPath 112 | /System/Library/Automator/Run AppleScript.action/Contents/Resources/Base.lproj/main.nib 113 | 114 | isViewVisible 115 | 116 | 117 | 118 | connectors 119 | 120 | workflowMetaData 121 | 122 | serviceInputTypeIdentifier 123 | com.apple.Automator.nothing 124 | serviceOutputTypeIdentifier 125 | com.apple.Automator.nothing 126 | serviceProcessesInput 127 | 0 128 | workflowTypeIdentifier 129 | com.apple.Automator.servicesMenu 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # XcodeSelector 2 | 3 | ## Problem 4 | 5 | Sometimes you want to have multiple versions of Xcode installed on your machine. Sure, you think it'll never happen to you, but then it does. Using `xcode-select` in Terminal isn't difficult, but it does get tedious having to go in all the time to check. 6 | 7 | ## Solution 8 | 9 | XcodeSelector is simply a Service that is globally availble that checks for any version of Xcode in your Applications directory, and asks which one you want to work with. It does ask for your system password, but only because `xcode-select` requires root execution. **This workflow does nothing with your password, otherwise**. 10 | 11 | ## Installing 12 | 13 | Download the repository, and double-click the Xcode Selector.workflow file. You'll be prompted to install the Service. 14 | 15 | ## Using 16 | 1. From any application, open the Services menu, and select XcodeSelector. 17 | 18 | 19 | 2. Pick the version of Xcode you'd like to work with. 20 | 21 | 22 | ### Contributors 23 | * Andy Pereira: [Twitter](https://twitter.com/macandyp) 24 | * James Headrick: [Twitter](https://twitter.com/jwheadricknj) 25 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macandyp/XcodeSelector/9590c173d9bf38da1fd0255372c918f608e1a9e4/screenshot.png -------------------------------------------------------------------------------- /screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/macandyp/XcodeSelector/9590c173d9bf38da1fd0255372c918f608e1a9e4/screenshot2.png --------------------------------------------------------------------------------