Intro
Xcode is the application development program made by Apple, available free in the App Store. It's used to make apps for iOS, OS X, Apple TV, and Apple Watch, in Swift or Objective-C, and can be used for C and C++ development as well. It is a powerful, intuitive piece of software… if you can see it. Voiceover users have a harder time of things in some ways. That's not to say that Xcode isn't usable--it certainly is--but it can be difficult and frustrating to try to work out the different pieces and make sense of it all if you are new. Hopefully, this guide will help you get used to Xcode as a VoiceOver user.
Credits
I have to extend a huge, huge thanks to several people and resources. Without all these, there's no way I could have figured out everything I have, and this resource simply would not exist.
First, there are some great people on the MV-Dev, Swift-Language, Xcode-users, and Cocoa-dev mailing lists. MV-Dev has gotten less popular lately, but some of its members can still be found elsewhere. Cocoa-dev and the rest are mainstream Apple lists, but if you explain that you are using VoiceOver and can't use the mouse or see the screen, they are usually good about helping. Several times, I've asked people on these lists to explain what's going on visually when VoiceOver does something odd, and their responses have let me figure out why things happen and better explain them in the text below. Of course, they are all also good resources as you learn more about development and Swift/Objective-C overall, accessibility-specific or not.
Next, thanks go to all the great people on Twitter, especially Eric Knapp. Eric once spent over two hours of his own time on Skype with me, as we worked through Xcode 7. He filled in the holes I still had in my understanding of the basics of Xcode, then he watched as I tried things--connecting outlets, making segues, and more--with VoiceOver. He offered many suggestions about alternative methods of doing things, and he is the main reason I was able to put this guide together and that I have finally started making apps on my own.
Finally, Apple and the Apple Accessibility Team deserve a big shout-out. They have been hard at work making Xcode more accessible than ever, and while version 7 is still not perfect, it's at last fully and easily usable--so far as I can tell, at least. The accessibility of Xcode improves with every version, but 7 feels like the first one to be stable and really usable.
Assumptions
I am going to make a few assumptions in this article.
- You are very comfortable with using Voiceover, including issuing mouse command equivalents, changing cursor tracking, interacting, and so on.
- You are comfortable with terms such as UI, UI control/element, action, outlet, and the like.
- You have at least some programming experience, particularly in Swift.
- You are using Swift, and making projects based on storyboards rather than NIBs. You can use NIBs if you like--they should work just as well--but I haven't tested them with the below tutorial. Objective-C users will also be just fine, so long as you remember to use the header of your view controller for adding stubs.
Xcode Overview
Make a New Project
When you open Xcode, after you get through any downloads of SDKs or documentation that may pop up, you will be ready to start a new project. If not, go to File > New > Project… I will not go into detail about each of the options and settings you will encounter, as this tutorial is about Xcode and Voiceover. The settings you will want will vary depending on what you're trying to do, and the meanings of the different options are all over the internet. The only things to note are:
- You usually land on a "templates scroll area". To choose a template, interact, find the template you want, and vo-space. To the right of the scroll area you can see which template has been selected.
- More importantly, to the left of the scroll area is a table of all the different categories you can pick from. I mention this because VoiceOver usually goes to the first item in a window, but in this case it doesn't, so you might miss that table unless you know to look for it.
Once you have the category and template you want, and have checked or unchecked the relevant checkboxes after the scroll area, press enter. The next screen is where you fill out the basics of your application: its name, your organization's name (make one up or leave it blank if you like), a couple identifiers, the category, and other configuration settings.
Finally, press enter one more time, and you are in a standard Finder dialog. Use this to select a location in which the project will be stored, and decide on a couple final options. Once you choose all this, the project is created and we are ready to get started. Note that projects are stored in folders, which contain all the necessary files. If your project is named "Hello World" and you put it in a programming folder inside your Documents folder, the path to your actual project file--along with all the other files in the app--will be ~/Documents/programming/Hello World. The .xcodeproj file in this folder will open your project in Xcode if you close it and need to open it again.
The Different Groups
When you have a project open in Xcode, you have several different groups. You will be focused inside one of them when your new project is first created, so stop interacting a few times before you do anything else - this guide will make no sense otherwise. Now vo-left until you find the toolbar, so we have a common starting point. Okay, let's jump right in.
The Toolbar
Interact with the toolbar. You will first see "Run" and "Stop" buttons, whose functions are obvious. To run, though, you can just use cmd-r instead of coming here, and cmd-period will stop an app that's already running.
You next find a "scheme, list, 0 items selected" item. This isn't actually a list, it's a quick way to choose the current scheme and destination. Interact with it, and you will discover an "Active Scheme" popup menu containing all the schemes you have, then a popup from which you can choose a destination. For iOS apps, destinations include iOS simulators, and all the items in this menu will be "interactive". From what I can tell, you don't need to bother interacting; all you'll get is the name VoiceOver already read, and an image of the device to be simulated.
The next item you come to is the "Activity View" group. If you interact with this, you'll find a few controls and some information, such as the time and status of the last attempted build, options to view any errors or warnings, and so on. The items here will change depending on how your project is doing and what you did recently, but it's a quick way to get an overview of the status.
The last two items are "Editor" and "View" groups. Both include options to change how the Xcode window works, but I haven't played with them extensively. Just note that the radio buttons in the "View" group are not announced as being selected, even though they are.
The Navigator Group
VO-right from the toolbar and you will land on a group whose name is the path to the currently open Xcode project file; interact with this. The first thing you'll find is the Navigator Group. This is where you can view the files in your project, review warnings and errors, see previous build attempts, manage breakpoints, and more. If you interact, you will land on a list of eight radio buttons, each of which will change what information is contained in the rest of this area. The Project Navigator, for example, will show a table displaying every file in your project with options to sort and filter those files. The Issue Navigator will show a table of any errors or warnings in your code, with options for how to display them and which items should be displayed. Each of the eight buttons displays an easy-to-use view, in my experience (I haven't investigated all of them) and there are no accessibility gotchas you need to be aware of, at least to the best of my knowledge. Note that the Command key with the numbers 1 through 8 will select each radio button; cmd-1 is the Project Navigator, cmd-4 is the Issue Navigator, and so forth.
The Editor AreaGroup
Next up is the Editor Area Group, which displays the content of whatever file is selected in the Project Navigator. Each file or area inside the Editor Area will itself be a group, letting you hold several files at once (doing this is using an Assistant Editor, and since you don't need to see the screen, you can open as many of these as you like without having them clutter your view). The Editor Area will also hold a "Debug Bar" and "Debug" group, but only when your app is running and has errors or log/print statements to execute. You will notice splitters between most of the groups in this area, but you can ignore them.
Below I have described a general outline of how each major file type will appear in the Editor Area. No matter which one you choose, you will always find a "Navigation Bar Group" at the start, which holds buttons and controls to jump around your project. I usually use this for the unlabeled menu button, which offers a "recent files" menu that lets me quickly access files I've recently viewed.
.xcodeproj
Selecting a .xcodeproj file in your Project Navigator will show information and settings for your project. You will first find a button to toggle showing/hiding the table of possible project targets. After that comes a search field, then a group of tabs you can use to select which category of options you want to view. Finally, you have a scroll area holding the options and settings for the selected project/target and options category. Since all of these are fully accessible and well-labeled, I will not go into detail about each one--standard Xcode tutorials will be able to explain everything about this section, and Voiceover users will have no trouble accessing everything.
The one thing to note is that, if you want to add to the Build Phases, Included Frameworks, or other tables, you cannot vo-space on the 'Add' buttons. Instead, put the mouse on the button with vo-cmd-f5, then click or press vo-shift-space.
Source Code
If you select a source code file--.swift, .h, .m, .mm, .c, and so on--in the Project Outline table, the group inside the Source Code Group that matches the filename will be different. There is a scroll area containing two items: a ruler (interact with that to view errors in the selected file), and a text field containing the code of the file.
That's the long way to view source code: select the file in the Navigator Group, go to the Source Code Group, interact with the group named after the selected file and then with the scroll area, and find the item called "Source Code, Edit Text". It sounds tedious, but you will get used to it, I promise. You'll use this a lot when moving from one group to the next inside the Editor Area, but if you choose a new file in the Project Navigator table, you can just press vo-j twice to land right in the text field holding your code. Remember that, to navigate and edit the source code, you don't have to interact with the edit text item at all.
.XIB or .storyboard
Xcode Interface Builder files (.xib) or storyboards are the third major type you will probably use. They are an outline of how your project's interface, or part of it, looks and is laid out. When selected, they appear in the Source Code Group as a table that shows your interface hierarchically. For example, if you have three buttons in a custom view, you will be able to expand that view in the table to see the buttons. If no table appears, only a scroll area, interact with the scroll area and press the "show/hide outline view" button to show the table.
That scroll area is also important. It shows your UI visually, using "unknown" items the don't do VoiceOver users very much good. However, it also holds the buttons to stack, align, and pin selected views, and shows you which size classes are currently in use, if your project uses them.
The Inspector Group
As with most parts of Xcode, this Group's contents will change based on what you're doing when you view it. If you are looking at a control in an Interface Builder file, the Inspector will let you change attributes of that control; if you are building a Mac app, you will see "Bindings" and other options not available on iOS apps; if you are looking at a source code file, you can change the file's name and other attributes, but most of the options will be very different.
This is accessible, so I will not outline every possible control here, but remember that command and option together with the number of the radio button you want will switch to that Inspector. Cmd-option-4, for example, opens the Attributes Inspector; if it wasn't already the active one, it will become so and you will usually be switched to it. This is a quick way to get to an Inspector from the outline table of your interface without a bunch of interacting, but it may not always work, whereas manually moving to it always will.
The Library Group
Here is where you can, among other things, find UI controls to add to your interface or select a code snippet. When you interact with the Library Group, you land on four radio buttons, each of which selects a different set of items from which to choose and all of which are fairly obvious. UI controls are found under the button labeled "Object Library". Once you choose a button, move to the right and interact with the scroll area to see all the different items available. After the scroll area is a checkbox to choose how the items are displayed, though this setting seems to make no difference to Voiceover as far as I can tell. Finally, you have a "filter" search field, which will limit what is in the scroll area to only matches to your search string as you type--no need to press enter.
That's It
There you have a basic overview of Xcode's layout and functionality. Remember that my goal is not to teach you Xcode; rather, it is to help you figure out what's where so you can follow any of the many tutorials out there that explains how to use this app. Hopefully, you now have a better grasp on Xcode's layout and basic functionality, and are now ready to start doing something with your new project! That leads us to…
Laying Out The User Interface
At the start of the previous section, you should have created a new project. It's time now to make an interface for your new app, and you won' have to do any coding at all! With your project open, follow the below steps to add something--maybe a label or a button--to your app.
Adding Controls
Step one of any UI is to add the building blocks--the buttons, text fields, checkboxes, and the rest. Most guides tell you to simply drag the items you want from the Object Library to your XIB file or storyboard, but it is not quite that simple for Voiceover users. Neither, however, is it difficult.
- In the Navigator Group, find the table of all project files. Choose the desired storyboard (usually main.storyboard) by arrowing to it.
- Move to the Source Code Group and interact with it, then with the group named for the storyboard file you chose. VO-right once to the Outline table. You don't need to stay here, you just need to know where it is. If you don't see a table, remember that you can interact with the scroll area you'll find and press the "Show or Hide Outline View" button. Stop interacting with the scroll area and the table should be there, just to the left of the scroll area.
- Now stop interacting with the Source Code group, then vo-right to the Library Group. Interact with it, check the Object Library radio button, and locate the Library Group scroll area. Interact and find the UI control you want. Hint: use the 'Filter' field to the right of the scroll area to type in what you're looking for (no need to press enter) and cut down on how many controls you have to look through.
- Once VoiceOver is on the control you want, route the mouse there with vo-cmd-f5, then lock the mouse button down with vo-cmd-shift-space. As you move around in the next steps, you will hear a swishing sound indicating that your mouse is down, and dragging the control. Note that we never turn off cursor tracking, as you may be used to doing in older versions of Xcode.
- Return to the Editor Area Group. Interact with it, then with the group for your storyboard, then with the outline table. VO-up or down until you find where you want the control to be (if this is a basic project, you'll likely want it in View Controller > View, so move to the View item).
- Vo-right once, and you will be on an unlabeled button to the right of the view into which you want to place your control. Unlock the mouse on this button with another press of vo-cmd-shift-space. Your control should be added to your view.
- If the control lands outside of your view, the move was likely illegal. For example, putting a button inside a text field won't work. Check that you are allowed to add the control to the view, and that you were focused on the right thing. Adding to a view controller, for instance, will work but won't add the control to any view, so you'll never see the control if you run your app. Adding a view controller will make a new scene in your storyboard, so don't worry if a view controller won't land inside a parent view--it's not supposed to. You can try routing the mouse to the unlabeled button (vo-cmd-f5) before unlocking the mouse if you want to, but I haven't found that to be necessary. Still, if all else fails, it's worth a try.
Moving Controls in the Outline Table
If you need to move a control into a different view or scene, it's pretty simple. You'll essentially lock the mouse down on the unlabeled button of the control to move, go to the control into which, or before which, you want to move what you're dragging, focus on its unlabeled button, and unlock the mouse. The unlabeled buttons in the outline table are the key to all this; just drag those by locking the mouse down on them, then unlocking it where you want to drop, and you should find you get good results. As noted in the final step above, illegal moves will simply not work, so be sure you are allowed to make a move before concluding that you or Xcode did something wrong. Note that illegal moves may still move your control, just not where you wanted it.
Making Connections
The next step is to make your UI respond to clicks and other events. I will not cover the specifics of coding or MVC here, but I will tell you what to do when a tutorial or forum post tells you to "control-drag your UI element to its view controller".
- Write the outlet and function stubs you'll be using in your view controller. You may do them all at once, or one at a time, it doesn't matter. For instance, an outlet might be:
@IBOutlet weak var someButton:UIButton!
(Note the exclamation mark!) A function stub that a button will trigger might be:
@IBAction func myButtonDoesThis(sender:UIButton) {
}
- Once these are made, build the project with cmd-b. A brief alert will appear, telling you if the build was successful or not. Either way, you should be safe to move on to step 3; all building does here is make Xcode notice the newly created outlets and actions.
- Find the storyboard in the Navigator Group's Project Outline table and press cmd-option-enter. This should open the storyboard's view controller in an assistant editor; you must have the storyboard and its controller both open to proceed. Now return to the Source Code Group, and go back to your view controller file's scroll area.
- Just to the right of the view controller text in the scroll area is a "ruler". Interact with this, and you'll see a bunch of connections, something like, "IB Outlet -myButton, in ViewController, not connected". Similar text will be used for actions. Find the one you want to connect, route the mouse to it with vo-cmd-f5, and lock the mouse down with vo-shift-cmd-space.
- Stop interacting until you reach the Source Code Group and can see the two files in it (usually three un-interact commands). Interact with your storyboard file and from there find and interact with the outline table. Locate the UI control to which the action or outlet will belong, and press vo-right to get to the unlabeled button next to it. Once there, unlock the mouse. VoiceOver won't say it, but the connection should be made.
- To confirm this, return to the Ruler in the scroll area of your view controller file. The text of the connection should now read "connected" instead of "not connected".
- That's it, you're done! Use these steps to hook up any controls you have, remembering to build the project before you try, as building is what places those connections in the ruler. You don't need to build after every connection is made, only after you add a new IBAction or IBOutlet to your view controller's source code.
Viewing and Disconnecting Connections
If you need to review the connections that exist for a given view or UI control, there are a couple ways. You can use the ruler in the view controller that owns the view, as discussed above, or you can use the Connections Inspector.
Highlight a view--anything from a scene all the way down to a cell--in the outline table of your storyboard. Navigate to the Inspector Group and choose the Connections Inspector, then interact with the scroll area. VO-right to move through all the items here; anything that lists a connection type, followed by "Disconnect, AX button" is connected. For instance, you might find a disconnect button after the referencing outlet in the inspector if you've hooked up an outlet as we did above. Activating this button will, just as you'd imagine, disconnect this connection.
Connecting to First Responder
Recently, I had to use First Responder to hook up some menu items. The process is kind of odd, so I wanted to document it here. I can't promise that it works exactly the same on iOS apps, or for controls other than NSMenuItem, but here's what I found. Note that you must have your function already written and marked as IBAction, then build your app, before this will work. If you don't, the final step--where you choose the function to which to bind the menu item--won't be able to find the function you want to use.
- Select the menu item in your storyboard's outline table, then go to the Connections Inspector.
- Find the "Sent Actions" section, then the "Connect Action, AX" button. Route the mouse to it with vo-cmd-f5, and lock it down with vo-cmd-shift-space.
- Go back to the Editor Area, then your storyboard's outline table. Find the First Responder object in the same scene as the menu item, and put VO on the unlabeled button to the right of First Responder.
- Route the mouse there, then unlock it. If all goes well, VoiceOver will inform you that "Xcode has new window".
- Press vo-f2 twice and select the "Untitled Window" from the menu. You're in a list of all possible actions, each of which is an unknown element.
- Fortunately, you can search by typing, as you can in most Mac menus. Type the first several letters of your function's name (the one you want this menu item to call when the item is selected), and use vo-arrows to find the method. If you can't find it, try typing the same characters, then add more, to filter further.
- Once you find the proper function, press vo-space on it (it's an unknown, but this should still work). The window will disappear and you are back in your outline table.
- To check that it worked, find your menu item again, then go to the Connections Inspector. Under "Sent Actions" should be a disconnect button, followed by the name of the function you just chose.
Creating Segues
Now that you have all the scenes and UI controls added to your storyboard, you have to figure out how your users will get from one scene to another; you do this by creating segues. A segue is how you tell your app to load a new view over/in addition to an existing one. For example, tapping the "Compose" button in Mail on iOS segues from your current view to the view that manages message composition. Visual-based guides tell you to control-drag from the button that opens the new view to the new view itself, but VoiceOver users do things a bit differently.
- In your storyboard's outline table, find the destination view controller (usually the very first thing inside a scene). Once VoiceOver focuses on it, stop interacting until you are out of the Editor Area Group, then head into the Connections Inspector.
- Select the Connections Inspector (cmd-option-6) and interact with the scroll area at the bottom of the Inspector Group, then locate the segues section.
- Find the segue type you want--show, popover, modal, whatever it is. Next to the segue name is a "connect [segue type] AX button". Put your mouse on it with vo-cmd-f5, then lock the mouse down with vo-shift-cmd-space.
- Return to the Editor Area Group, then your storyboard's outline table, with which you should interact. Find the button or other control you want to trigger the segue (yes, this will feel backwards) and put your focus on the unlabeled button to that control's right.
- Once on the button, release the mouse with vo-shift-cmd-space again. VoiceOver will say "Xcode has new window" after a moment.
- Press vo-f2 twice, choose the new window from the list, and vo-space on the "action, unknown" item you land on. I'm told that, visually, this is a floating button asking you to confirm the segue, but VoiceOver won't focus on it automatically so you have to switch to its window manually before you can confirm.
That's it, the segue should now work as expected, and a segue item will now have appeared in your table. The reason it feels backwards is that you are pretty much saying to the target view, "I want to segue to you, using this kind of segue. Now I'll tell you and your segue what button I want to use to start the process." Essentially, you're going from the view to the button, rather than the button to the view.
You can select the segue item in your outline table, then use the Attributes Inspector to change, well, attributes. If you want a modal segue rather than a show, you can do that; if you don't want it to animate, you can uncheck that box; you get the idea. This is also how you'd assign a segue to a custom subclass if you made one; create the segue as described above, then use the Attributes Inspector to change it class to your custom subclass.
Auto Layout
Auto Layout is going to be your best friend, particularly as a blind developer. With it, you can specify rules (called constraints) for spacing, boundaries, positions, and more. There are a great many Auto Layout tutorials out there, so i will not cover what this system does or how to employ it. However, most tutorials will focus on all the lines, handles, guides,, and other visual cues Xcode offers. If you are unable to see these, there is a simple solution.
Please note that the following steps will create constraints, which are themselves objects. Constraints appear in your storyboard's outline table under the "Constraints" section in the scene in which they apply. If you use the arrow keys to review your table, without interacting with the table first, you will not see them at all. You must interact with the table, then use vo-up or vo-down, in order for VoiceOver to consistently pick up the "Constraints" section and let you view your constraints. If the section is already open, VoiceOver seems to detect them, otherwise it simply skips the "Constraints" row in the table entirely.
Constraints to the Superview
- In your storyboard's outline table, find the control you want to constrain. Moving VoiceOver's focus to it is enough to select it.
- Move to the Scroll Area to the right of the outline table and interact, then find and activate the Align button.
- You're in a sort of grid, with a checkbox and button to the left, used to enable or disable that row's constraint type. After that is an image, followed by the textual name of the constraint type, followed by a text field. Find the text item that reads "horizontally in container" or "vertically in container". Enable one or both, depending on whether you're trying to align your control with the side or top/bottom of the superview.
- The text field is where you express the distance, in pixels. Remember that this is from the top left, so if you're pinning the control a certain distance below the top of the superview, use negative numbers.
- Once you've enabled the desired constraints and entered the distances, go to the bottom of the window and activate the "add X constraints" button, where X is the number of constraints you've just set up. You'll notice a new "constraints" row in your storyboard's outline now or, if you've already added constraints, you'll see new ones in that section.
Constraints Between Two Views
- Interact with the storyboard's outline table and find the first control of the two you want to constrain. Once on it, hit vo-cmd-enter twice (the first time de-selects the item, so you must press the command again). If the controls you want to select are all right next to each other in the table, use shift-arrows to select them instead, and skip step 2.
- Being careful to use vo-arrow keys, not the arrows by themselves--doing so will de-select everything--find the second control. Press vo-cmd-enter on it, too, but you'll only need to do this once. Note that these controls need not appear one atop the other in the table. Repeat for any other controls you want to bind together.
- Stop interacting with the table and interact with the storyboard's scroll area instead. Locate the "Align" button and activate it. You can now choose any relational constraint you wish, such as aligning tops or vertical centers. See the previous section for how this popover is laid out, as it is very similar.
- To apply a constraint that will space one control a set distance from another, use the "leading edges" or "trailing edges" constraints. You'll change this later to make the leading edge of one control space itself a set distance from the trailing edge of the other, or vice versa, but choose both leading or both trailing for now. Type the constant in the text field as described in the previous section. Remember to use a negative number if the spacing constraint is right to left, since that's moving left along the X axis. Same for moving down the Y axis (toward the bottom of the screen).
- If you're using a spacial constraint between two controls, you have an extra step. Find that newly applied constraint in the outline table, and go to the Attributes Inspector with cmd-option-4. Use the popup menus to control which edge is aligned with which, the equality, and if you wish to reverse the two controls in the order. If you followed the steps so far, you'll want to choose an edge that is not the same as the edge chosen for one control. That is, be sure one control's leading or trailing edge is constrained with the other control's trailing or leading edge. This gives you spacing between the two, defined by the number you entered.
For example, to space a text field 20 pixels below the bottom of a button, you'd select both controls and make a constraint to align top or bottom edges. You'd then choose that constraint in the outline table, move to the Inspector, and change the values. If you chose "align top edges", you'd choose "bottom edge" for the text field, so that the bottom of the field will be aligned with the top of the button. You'd then enter 20 in the "constant" field to add the spacing, and there you have your constraint. To do this to controls relative to their superview rather than to each other, choose a horizontal or vertical center constraint, and adjust it as just described.
Constraints Via the Menu Bar
In the above instructions, I told you to use the Align button in the storyboard's scroll area. First, it's quick to get to, and second, it lets you type in a constant for a distance if you want to. However, you can also go to the Editor dropdown menu (not the Edit menu) and choose Align from there. You can't enter constants, but you can choose the constraint you want right from the menu. Better still, you can use the hotkeys already there for some of the constraints, and assign your own to those that lack them. To align two views' left edges, for instance, just select them and press cmd-left bracket. There is no way to access the items in the Pin button's popover from the menus, which is the other reason I use the scroll area for both in the instructions.
Debugging
As careful and clever as you are, you will make mistakes in your code or, worse, your logic. Errors come in two basic types: those that are discovered by Xcode before your app will even compile or run, and those that only appear later, while your app is running. Both are manageable in Xcode, even for VoiceOver users, and here's how.
File by File
The easiest way to catch many errors is as you're writing code. Fortunately, Xcode makes this very easy: the ruler. Next to the text field where you type code is the same ruler we used to connect outlets and actions earlier. That ruler has a second purpose, and that's to show errors as Xcode detects them. This method of debugging is file-by-file, so you only see problems in the single file you're looking at, but it's very effective for syntax or build errors.
To use this method, simply interact with the ruler and vo-up or vo-down--trying to go left or right seems to be less reliable. You'll find errors, including the type (build, syntax, etc); the error text itself; and the line number. Though VoiceOver says each error is a button, pressing it will do nothing. You must instead press cmd-l, type the line number the error told you, and press enter. The line in question will be highlighted, so remember to hit an arrow key before typing or what you type will replace the whole line! The only down side to this process is that your cursor won't land on the place in the line where the problem is, so it can sometimes be hard to know what is being referred to if the line includes a lot of variables and/or function calls.
Errors can take a few seconds to clear, so if you find one and fix it, the button in the ruler may not disappear right away. Rarely, an error will persist even though you've fixed it, which led to a very frustrating ten minutes for me until I figured out what was going on. Building your project (cmd-b) seems to clear out any errors that refuse to go away on their own.
The ruler is also used during runtime if an error is discovered. Xcode will put the problematic file in the first group of the Editor Area--so don't be surprised if which file is there changes once your app runs--and will place a marker in the ruler for the line in question. For example, if your app forces an optional to unwrap but gets a nil value, that's an error. The line where that happens will be marked in the ruler, and you can discover it like any other error warning. If you stop the app from running, this marker will disappear, so be sure to locate the problem before stopping execution.
Note that you can type, as well as use arrow keys to navigate, in your source code text even while you are interacting with the ruler. This lets you make changes to your code, then vo-up or vo-down without any interaction commands at all to see the new status of any problems. The only downside is that commands like vo-l or vo-c won't work unless you interact with, or at least focus on, the source code text field. You will also find searching with vo-f less reliable unless you interact with the code first. If you don't need those functions, though, and want only to navigate and modify your code, feel free to stay in the ruler even as you make your changes.
Command Apostrophe
The keystroke cmd-apostrophe will jump you to the next issue in your code, whether it's in the current file or not. The problem is that it can often skip bugs in the current file and go to another one, picking up warnings you already know are there and are intentionally ignoring. The good thing is that it puts your cursor on the exact character where the problem starts, and can even pop up a dialog offering to fix the problem if Xcode thinks it knows how. This is useful for quickly jumping from issue to issue without caring where each problem is, but if you're concentrating on one or two files and ignoring the rest, this may not be the best debugging tool to use.
The Issue Navigator
A more comprehensive overview of the problems in your code can be found in the Issue Navigator (inside the Navigator Group, accessed with cmd-4). Find the Issue Navigator Outline Table and arrow through it to see the problems. This table is organized first by project, then by file within the project, then by error/warning.
One thing to keep in mind with this table is that it will sometimes pop up the same dialogs I mentioned before, offering to fix your code if it can. You can press enter to accept the change, or escape to close the popup without accepting. Either way, you will no longer be interacting with the table if you had been before, so remember to interact again if you need to after you get rid of one of those popups. More troublesome is that, particularly when viewing issues related to a storyboard, focus jumps to the scroll area of the storyboard and out of the table, before you have a chance to hear what the problem is. To avoid this, and the popups as well, you can turn off cursor tracking (vo-shift-f3) while you browse the table, then turn it on again when you're done.
Debug Group
As soon as it's needed, the Debug Group will appear at the end of the Editor Area. This happens whenever your app has a log or print statement to execute, or runs into an error not caught before the app started running. Essentially, anything that prints to the screen will show up here, be it something intentional by you or the text of a problem you didn't know was there.
Any text here is printed to the "console", which appears to VoiceOver as a multi-line text field. You must interact with the field (again, found inside the Debug Group, not the Debug Bar Group) and use VoiceOver navigation to get around it. For some reason, plain arrow keys won't provide feedback as you press them, though things like cmd-up or cmd-down can be used to move quickly to the start or end of the text. Sometimes, you may need to issue the interaction command twice before it will work, though--again--I don't know why.
Once you get to the console, though, you can easily read any text printed there. Remember that log statements and text generated by errors will usually include a very long timestamp, app ID number, and more, and this information can often take up nearly a full line before text that is more useful is spoken. If using Swift, "print" statements don't have this problem and I like to use them over logging for exactly that reason.
Wrapping Up
You now know how Xcode is laid out; how to make a new project; how to add UI elements to your project, move them around, and connect them to actions or outlets; how to use Auto Layout to keep things looking pretty; and how to debug your code on a basic level. Everything else is covered in great detail elsewhere online. As I've said, the point of this guide is not to teach you Xcode or Cocoa, but rather to explain what to do when the tutorial you are following starts going on about mouse dragging and pretty lines and shapes.
I strongly encourage you to look at Apple's developer resources, other articles and tutorials online, and even dig through Xcode's menu bar to see what else is there (cmd-ctrl-j and cmd-ctrl-left/right are hugely useful, for instance). As always, sound off in the comments if you have any questions or if I need to make something more clear. Just remember that I'm trying to teach you Xcode with VoiceOver, not Xcode/programming as a whole. I can try to answer your general Xcode or programming questions, but they fall outside the scope of this guide, so please tweet @VOTips instead if you have questions like that. I can't promise I can answer--I'm no expert, by any means, nor am I a teacher--but I can give it a shot.
Comments
This Guide
Hi thank you for this guide on Xcode, after reading this once it has already made a few things clearer to me concerning Xcode especially the sections about constraints. I have been trying to learn Xcode for a while now and will go through this guide over the next month or so and will be happy to give you feedback on how I am doing if you want some.
Once again many thanks for the guide.
John
Adding icons or launch images to your project
Hi, this was a nice guy that was posted. But, what happens once you have an iOS app built? You need to add the icons and launch images to your app in order to submit to the store. We are visually impaired people. So, we cannot go and use Photoshop or any other photo editing app because it might not work. How do you design your own app icons in order to submit to the store? Thank you.
I'd out source it
Honestly, I'd just out source that. Maybe a friend can do it, maybe you'd pay a person or company to do it, but images are like visual check on my layouts. If and when I get to that point, I'll get sighted help, because it's simply not something I can do on my own with results I can know will look good. Sure, I can grab images and size them, but even then, I can't know the details of the appearance or if there's an overall visual effect I should be maintaining which I'm not. Icons and other visuals are for sighted people only, so it makes sense to have sighted people handle them.
Fundamentals of Swift
This guide has been very helpful. Over the last two weeks or so I've been gathering resources to get a start using Swift 2.0. I have a couple books and I'm using Lynda.com to start building my knowledge but I wanted to ask those of you currently using Xcode and Swift where you learned how to code.
I know the fundamentals of coding but as I venture into the specifics of Swift I'd like to find out what other resources are out there and have been successfully used by other blind coders to be successful.
If you can share where you learned what you know I'd greatly appreciate it.
Thanks so much!
Difficulty with xcode assistant editor
Hi, I am a blind user of Mac OS. I wish to begin to learn programming with Xcode. I find some beautifull guide but I have an important obstacle. I can see the my exercices result in Playground because I cannot go on the column of the right where Playground shows the video result of written code. I activated the Assistant Editor in the Xcode menubar but it remains not visible for Voiceover. I'm using Xcode 7.3.1. How can I do? Thanks!
Accessibility issue with xCode 8.0
Thanks for the guide! Have you tried xCode 8.0? I'm a VoiceOver user. When editing xib files in Interface Builder, I cannot get to the toolbar at the bottom right corner of the canvas. Consequently, I cannot create layout constraints using tools like align, pin, and etc. Do you happen to know a way to get around this problem? Thanks!
Voiceover say Xcode.SourceCodeSimbolKind.Mac
Hi.
I apologize that my English is bad, but I've put it with an automatic translator.
I am blind programmer, and I am introducing myself to the world of Xcode.
I have followed your guide and it seems fantastic, but I would like to ask you a question:
When I am writing code I hear the sound of autocomplete voice-over, but I do not read until I do not under and up arrows, is there any way of automatic form of first aid?
And besides that, before the statement reads me the phrase Xcode.SourceCodeSymbolkind.Mac, is there any way to disable it to read that?
I appreciate your response.
Greetings.
Changes in Xcode 8
I recently started a tutorial for iOS programming in Xcode and Swift. This is the first time I used Xcode in years, and the first time since I started using VoiceOver. The last time I did anything in Xcode, I had enough vision to use my computer visually with a magnifier instead of a screen reader.
I used this guide as a starting point for figuring out the Xcode interface with VoiceOver. Although it was very helpful, I noticed a few things that are different now. These are mostly improvements, so kudos to Apple for making the app more accessible.
In the toolbar, the guide mentions that the items in the view group do not indicate which ones are selected. They are now announced as check boxes, so there is no issue here anymore.
In the editor area, the navigation bar at the top is now called the jump bar, which is consistent with the Xcode documentation. The first item in the bar now has a label, "related items."
If the assistant editor is open, each file has its own jump bar. If you navigate to the end of a jump bar for an assistant editor, you will find an unlabeled button, which ironically has a VoiceOver hint. This is the close button for that file, so clicking it will remove the file from the editor while keeping the others open.
When viewing a user interface file, the canvas now has all elements properly labeled, instead of the bunch of unknowns as described in the guide. This is particularly useful if you have VoiceOver set to announce what is under the mouse cursor as you move it. You can then explore the canvas with the mouse and hear each element as the pointer tracks over it, which can give a rough idea of how the elements are visually arranged. Note that if you added or changed AutoLayout constraints, you need to update frames for the affected objects before their positions will be shown correctly on the canvas.
You do not have to build your project anymore after adding an outlet or action method to a source file. The connection well in the ruler automatically appears after you enter the outlet or action declaration in the file, so you can make the connection right away. Alternatively, you can have Xcode enter the code for you by making a connection from the inspector pane to the source file, though that method is generally slower with VoiceOver.
When making connections between two objects, Xcode displays a popover letting you select the property or method to use for the connection. The guide here gives two examples of this, one when connecting to first responder and one when making a segue. The items in the popover are described in the guide as being unknown items, but now these items are properly labeled for VoiceOver. You still need to move focus to the popover manually, by pressing VO-F2-F2, as described in the guide.
I ran into a couple of intermittent issues while selecting files in the project navigator. The first is that VoiceOver would, for some odd reason, decide to announce the status of one of the buttons on the right side of the Xcode window while moving from file to file in the navigator. This made selecting the file I wanted rather tedious. The other is that, after landing on a storyboard file, VoiceOver stopped working as expected, with various navigation commands doing weird things. I had to turn VoiceOver off and back on before it behaved correctly again. I cannot reproduce these bugs consistently, but I had both of them happen a few times now.
One thing this guide does not cover is autocompletion. As you type something into the source editor, a popup appears with suggestions for finishing what you typed. You can use up and down on the keyboard to choose from the menu, then hit Return on the result you wanted, or press Escape to dismiss the suggestions. VoiceOver announces the suggestions as you focus on them, but the announcements begin with a rather cryptic image label, which is pretty annoying since it takes longer to hear what the suggestion actually is. Also, if you want to hear what the first suggestion is, you need to press down, then press up to bring focus back to the first, because VoiceOver does not appear to announce the first result automatically, at least in my experience. Some might hate the autocompletion engine entirely, since it can sometimes get in the way while typing, but there is an option to disable it in the preferences somewhere. I personally like it, especially when entering a very long function name, and Apple loves using long names in their APIs.
Those are my observations to this point. I hope someone finds this useful.
Autolayout problems
In xCode 8, one can use autolayout fairly easily. However, I am running into cryptic problems with it. I have 3 labels on a view: name, phone, and address. I have pinned name, phone, and address in vertical order in the top left corner of the view. I need to make these labels the same size as the address label since it is the widest. I do the typical actions of selecting the labels, going to the align in the canvas button bar, choose right edges (trailing edges), then press the add 4 constraints button at the bottom of the window. Instead of aligning the phone and name label's right edge with address' label, xCode makes phone and address align with the name label's right edge. Is there anything to look at that might solve this problem?
re: Autolayout problems
Just a guess, you may want to check out Content Hugging & Content Compression Priorities. Or even try using stack views.
Stack views
I tried a sample layout with stack views and got the desired layout. However, the vertical layout of the main stack forces all of the embedded stacks to the bottom. If one is added to the bottom of the vertical rows, the top row moves up a little. Any way to get the entire set of vertical rows of stack views to float to the top of the window?
rather cryptic image
"VoiceOver announces the suggestions as you focus on them, but the announcements begin with a rather cryptic image label, which is pretty annoying since it takes longer to hear what the suggestion actually is."
This is what I asked in the previous comment, that if there is any way to prevent VoiceOver from announcing these images.
I've tried adding the strings to the VoiceOver dictionary by replacing them with an empty string, but it does not give the desired result.
Writing Stubs
Hey, this is a fantastic guide and cool that you keep it up to date! Do you know/have a resource which details how to write the UI stubs? I am a beginner in UI programming, so it would be quite helpful to get some additional input. Thanks a lot!
Making connections
Curious, how did you make the connections between the story board and the view controller? I tried several things but it did not appear to work.
up to date?
I am a little confused. I see comments in 2017 saying this guide is up to date, but the guide refers to xCode 7 while we're up to xCode 9 now. To what degree are the instructions in this guide still applicable?
Connections in Xcode 9
I don’t find the “ruler” in Xcode 9. How can I do to make the connections? Thanks!
connections in xCode 9
Hi, hi, hi! anybody discovered a method to make the connections using Voiceover in Xcode 9? Thanks!
add app icon in Xcode 9.3
Hello, someone knows how can I add the images in the Assets.xcassets using Voiceover. there are some sections where the Voiceover reads only "Device group". It is possible to know where may I put the images for the app icon? Thank you very much!
Re: add app icon in Xcode 9.3
I just finished working this out. I was doing an app from a book and they wanted the icons aded.
If you select the AppIcons row in the table and then go to the scroll area you will find and item that says "dimmed collection". Interacting with that area you see at the far right an item labeled "Device". Here is where all the fun starts.
I recommend the first time you do this that you have if possible someone sighted to watch and make sure you put things in the correct places. If you are an Aira Explorer they can help you. If not, you can get a sighted friend to do the same. This area of Xcode could use some improvement by apple to make things more clear. There is text that helps a sighted user but we can't access that text.
If you interact with the "Device" you will see two Device items and a place for an icon labeled 1x. The 1x slot is for the 1024x1024 icon used for AppStore submission. The two Device items are, left to right, iPhone and iPad.
The iPhone area contains four more Device areas. Each of these areas have a 2x and a 3x item. These items are for the four types of icons needed for the iPhone.
Going back to the Device item one down from the top of the tree, if you will, provides the set of five areas for the iPad icons. If memory serves the first four are like the ones for the iPhone and the last one is for the iPad Pro with its special scrfeen.
At this point it becomes necessary to drag and drop icons into the slots in this table like area. There are 10 rows if items that I believe visually appear to be two across and 10 down.
Xcode will complain if you place a wrong resolution icon into the slot.
If you want to do this much easier and you are familiar with editing a JSON file by hand you can edit the Contents file and just add the file line to each area in the file with the pointer to the icon. Afted editing this by hand it is important to place all the .png files in the same directory. Also, don't leave any extra files there that shouldn't be there because Xcode will complain about unattached child or some strange error.
That's the long and short of it. I have really done this and it works.
Good luck,
J. R.
Hello
Hello
Thank you for your amazing Guide, but I have a problem in adding ui controls to the view. I’m following the book intro to app development with Swift, in the tutorial they want me to remove the view and add an Image view. I tried to do it by locking the mouse, and releasing it on the unlabeled button, unfortunately it didn’t work.