Hi, I'm Martin and I write software. I also have a hell of a lot of stuff going through my head with thoughts and opinions on many things. Unfortunately, in this whole jumble I often fail to articulate my point of view very well. This blog is an attempt to rectify that by trying to put all my thoughts on various subjects down in one place. If you want to get in touch, email me at firstname.lastname@example.org.
I've spent a lot of time and words this year talking about what Xcode does have. At the same time I've spent quite a few tweets pining for certain features or wishing pain on those who are responsible for annoying bugs. I thought it would be an interesting idea to put together my personal wish list for the future of Xcode. These aren't in any particular order, though I have marked which are bugs I'd love to see fixed and which are features I'd like to see added. And finally I've included radar numbers where appropriate to allow you to file duplicates if you so desire.
[UPDATE 8/2/13]: I've struck through the titles of those items that have since been fixed
This is one of the biggest complaints people have about Xcode 4: it is so friggin' slow! I'm on a 2.93GHz Quad Core i7 iMac, which by all accounts is an incredibly fast machine, and it can feel really slow at times. Slow opening files, slow showing and hiding the UI, slow searching for documentation. It also goes through memory like it's going out of fashion. It's not unusual for me to quit Xcode and gain up to 8 GB of RAM back on my system.
The other big bug is that indexing periodically stops working. Either the index gets corrupted somehow or the indexer seems to hang. Either way, it happens often enough to affect almost everyone. The problem is that the indexer powers pretty much everything in Xcode 4, so when it breaks you lose code completion, syntax highlighting, fixits, refactoring and more. It has improved with each release but it still happens too frequently to ignore.
So I have a window (A) with a tab. I decide "this tab would be much better on this other window (B)". So I drag the tab from A to B. Unfortunately I'm unable to drop the tab on B because it doesn't have any tabs yet, and so doesn't have a tab bar. Unlike Safari, Xcode won't let me drop the tab anywhere but a tab bar. This means that the only way to perform this rather trivial operation is to create a temporary tab to show the tab bar.
This is sort of the inverse of the above request. I would love to be able to take a tabless window and dock it as a tab on another window, without having to create a temporary tab.
And now for one of the most annoying bugs. I have a bunch of behaviours set up to show various tabs. The problem is, when these tabs aren't visible, it isn't guaranteed where they will show. Sometimes they show in the frontmost window, but sometimes they open as separate windows. Ideally it would always be the former, but the latter does happen and ends up leading me to curse the tabs system in Xcode.
Most users of Xcode 4 have hit this one. You spend ages working on something, it gets to the end of the day and you close your workspace by clicking the red button at the top. Then *it* appears. The small, insignificant but oh so annoying extra window. You opened it hours ago and forgot about it, it was hidden. But now it just sits there laughing at you, because it knows that next time you open this workspace you're going to have to set EVERYTHING up again.
So please Apple, let me assign a certain window as the "main" window. This window should always be opened when the workspace is, and ideally closing it should also close the workspace.
Do exactly what it says on the tin.
I love schemes, they are fantastic. However, even I admit they can be a bit hard to grasp at first. A big part of the problem is the edit schemes window. It somewhat betrays how they actually work. When I first saw schemes I thought from the icons that it ran through them top to bottom, doing a Build, then Run, then Test, then Profile etc. And visually they all appear as equal operations.
In reality though you have 5 operations: Run, Test, Profile, Analyse and Archive. Before all of these can happen though, something has to be built. What would make more sense to me, and hopefully make schemes easier for others, would be to separate build from the other rows, to show that it is a distinct type of step.
In almost every application on OS X, escape will dismiss a sheet or a preferences window. Unfortunately Xcode 4 thinks that's too mainstream.
Filing radars is a pain. First off you need to open a browser window. Then you need to log in. Then you need click new problem and then you get a lovely web form to fill out. And it gets even better when you click submit and find radar has logged you out and lost your bug. It takes a lot of effort to write a bug in the first place, without all this extra cruft.
Now imagine that Radar is built into the organiser. You can see all your radars and browse them quickly. You can also write new radars. Even better than this, if you choose a radar type that requires a system profiler, it will automatically generate and attach one for you. It also allows you to attach screenshots and even a project that Xcode knows about. It removes all the friction and encourages people to file more bugs.
I honestly was shocked I hadn't filed this radar until writing this post. I assume almost everyone who's used Xcode for as long as I have has filed a similar one. Basically we want extensibility. We want to be able to build upon the foundations of Xcode and add new features that Apple may not have time for, or may not even have thought of. Almost every other IDE supports this, and internally Xcode seems to have several plugin systems. It's a shame that it doesn't have one other developers can use. Especially as several of the feature suggestions I give could potentially be implemented by 3rd parties.
AAAAAAAAAAAAAAAAH! HULK SMASH!
Nearly 2012 and Xcode 4 doesn't have a replace all in selection option. I am genuinely surprised that this hasn't been fixed yet.
C# and Visual Studio have a really cool feature called regions. Regions are effectively just preprocessor blocks that can be collapsed by the editor. Think of a #pragma mark, but which also had an end block and could be collapsed. I long for this in Xcode as it would let me hide huge chunks of classes that I don't need to see right now.
The biggest uproar I can remember when Xcode 4 first came out was the loss of the command-option-click shortcut. Performing that on a symbol would use it as the search term for a documentation search, which allowed for you to get to the docs for a method really quickly. I'd love to see this back in, as quick help is largely useless in those areas and it's quite a bit slower to perform a search manually.
Some people hate headers. Personally I think they're a fantastic tool. What we can all agree on though, is that Xcode could do a much better job helping us work with them. There are two common scenarios: you have something defined in your header that you want to implement, or you have something defined in your implementation you want to declare. In the former case Xcode could offer to create stub methods in your implementation for any unimplemented methods defined in that header. In the latter case it could offer to either add the method to the header, or to a class extension in your .m.
Xcode can already warn you if you're missing an import for a class or a framework. It should also know about the location of many of these missing classes or frameworks and whether they are linked into the project. It would be useful if it could put 2 and 2 together and offer a fixit for importing missing headers.
I always find it useful to know if a method is public or private when calling it. Unfortunately, there is no ideal way to distinguish between them in code. The best looking way is to prefix with an underscore, but Apple doesn't recommend that. You could prefix with other characters, but that's kind of ugly. Xcode already lets you colour instance variables differently to local ones, so why can't it colour calls to header defined methods (i.e. public methods) differently to those defined in the implementation (i.e. private methods).
I don't use code folding in Xcode 4. A large part of that is because code only stays folded as long as you have that file up. As soon as you switch away it unfolds everything. It would be great if this at least persisted while Xcode is open, but even better if it remembered the state between launches.
I'm not 100% how many people would use this, but it's an interesting idea nonetheless. The media library is filled with video, audio and images, which can all be dragged out. At the moment they simply insert the name of the resource if they are dragged to code. It would be useful if it instead generated the appropriate source code to use that resource. Say I drag the NSUser image to source code, it would add [NSImage imageNamed:@"NSUser"].
All good programmers know to use constants for common string values, especially keys and notifications. This allows the compiler to check for misspellings and for Xcode to offer code completion. But often the first time through you write a plain string as it's quicker when you're prototyping. Or maybe you're getting some code from a bad programmer (no cookie) and it is litered by these strings. Xcode could offer an "extract strings as constant" refactoring option, that would do most of the hardwork for you. It couldn't be perfect (two strings could have the same value, but have different constant names based on their semantic use) but it could do a lot of the groundwork for you.
A pretty simple one. Xcode doesn't support it. It should.
If you've ever used Visual Studio, you'll know it has damn good code completion. One of the things it does really well is show a summary of the item selected in the completion list. This helps when you're not 100% sure of which item to choose. Now I'm constantly going on about how useless quick help is, but this is the one area I think it would be really useful. The Xcode team already realises this, which is why you can manually bring up quick help in the code completion list. I want to see an option to have this automatically appear after a short delay though.
Quoth the radar:
Number of times I've used NSStream in 7 years of Cocoa development: 0
Number of times I've used NSString in the past week: >100
Percentage of time Xcode suggests NSStream instead of NSString as a the best completion: >50%
This is one I came across the need for a few days ago. I sometimes want finer grain control over which exceptions I break on. In some situations I don't want certain exceptions to be break, such as when I'm running tests that check that an exception is thrown.
A common situation when debugging a feature is to have several breakpoints scattered throughout several files as you follow the code path. Unfortunately the breakpoint navigator groups breakpoints by file, not by the code path you're following. On top of this you often want to enable and disable several breakpoints at a time. Breakpoint groups would solve that by letting you collect breakpoints together into groups that make logical sense to your app.
NSLog. Every Cocoa programmer knows it well. But in order to use it you need to recompile your app, and then have to remember to take them out. There is another way though, and that is breakpoints. You can set a breakpoint to log a variable and continue. This doesn't require a recompile, can't be accidentally shipped and can easily be turned on and off. Unfortunately it's a pain to make, so Xcode could help out by letting you select a variable or a bit of code, right click it and choose to create a "log breakpoint" from that code.
Unit testing has seen rather large improvements in Xcode recently, granted it's coming from a rather lacklustre start. But viewing results is still a pain to deal with as Xcode treats unit test failures as identical to build errors. Odd as it may sound for something written in Java, the JUnit test runner UI does a really good job of this. It has the oft cited green/red bar to denote success failure, and lists the tests that passed and failed. It also gives information such as the number of passes, tests run, failures and errors as well as the time taken to run in the UI, all which you need to go look at the log to find in Xcode.
Having a new navigator in the sidebar dedicated to running tests, based on the example set by JUnit, would truly make testing a first class citizen in Xcode.
This is a bug that hit me recently and caused me to wish pain upon all those who worked on Xcode. When unit testing you usually define a test host setting, which is the path to binary the tests will be injected in to. It seems Xcode ignores the "path" part and just takes the binary name and searches for that in your build products directory. That isn't a big deal until you have multiple targets for the same app, with the same binary name. This means Xcode will pick one of them, and it may not be the one you want.
Simple one. Instruments has support for UI testing iOS apps, I'd like to see that on the Mac.
LLDB is still too crashy to use. There are many crashes that happen, but the only one I've been able to semi regularly reproduce is using the 'po' command, which will at some point cause Xcode to hard crash. By hard crash I mean it quits faster than I've ever seen it quit, providing no crash log or any indication of what went wrong. I long for the day LLDB is stable enough to use regularly, because it is so much faster than GDB.
Looking at the media library you realise there aren't all that many images there. In reality though Cocoa provides many more standard images, including a standard folder, status indicators and trash icons, but they aren't listed. In fact the media library doesn't show anything added since Leopard.
IBPlugins are dead. I was hoping they'd return but they haven't. This means that we've actually taken a step back in the quality of tools for building UIs for Cocoa apps. Apple really needs to add better support for 3rd party code. There are two possible ways to do this.
The first is simply to improve the User Defined Runtime Attributes sections. It already supports strings, integers and booleans, but it also needs to support images, colours, fonts and probably a few other types. Add in key path completion like with bindings and it would allow for the removal of a lot of code.
The other way is to allow headers to be annotated. We already have IBOutlet and IBAction. Why not also have an IBAttribute, that we can put next to a property and maybe define some options on. Xcode could then dynamically generate an inspector for the class from this information.
NIBs can be rather complicated. Thankfully we now have a nice big canvas, so why not use it to have comments associated with views, rather than cramped in an often hidden inspector. Below is a mock up I supplied with the radar I filed, that uses a NIB and stickies to show what it would look like. We've got this extra virtual space, why not use it?
Related to the above, in IB3 you could have comments appear next to a view when it was selected. The checkbox for this has been in Xcode 4 since the beginning, but doesn't actually do anything.
The thing I miss most from IB3 aren't actually IBPlugins, but the tooltips on inspectors. Hover over a control in an inspector and it would tell you which API it actually represented, which was invaluable when you wanted to know how to do something programatically.
In IB3, the object library used to collect objects into groups. Unfortunately the option to view object groups in the library has gone, making it a bit harder to find what you want.
Quite often you know a constant name, but don't know its value. Unfortunately the many inspectors in IB require you to enter in values directly. It would be really cool if you could type in a constant name, hit enter and IB would substitute it with the appropriate value. Even more so if it kept the constant there to aid refactoring.
I'll just link to two videos. The first on the general code bubble concept. The second on Microsoft's Debugger Canvas which implements similar functionality for Visual Studio debugging. If you don't see the benefit of such a navigation system then something is very, very wrong with you.
Navigation in IDEs sucks. Stepping through code is pretty well supported, as is jumping to a certain point in code. But the higher level navigation sucks really bad. We logically group our files in layers, such as models, views and controllers. The problem is we work in features, which span all these layers. People often comment on Xcode 4 looking like iTunes as though it is a disparaging remark, but I think it could take something from iTunes: playlists.
Imagine lightweight groups, which you could drag references to code into. You could throw one together for each feature you work on, meaning you don't have to search all over your source tree to find the files and methods you need for the feature you're working on.
Source trees were one of those weird features I didn't quite get in Xcode. Then it actually clicked how useful they are. For those who don't know, they allow you to specify custom points from which to base a file reference. By default Xcode gives you options such as an absolute path, relative to the group, relative to the project etc
So one day I had to move my workspace file, and it broke all my references to my framework projects. I realised that it would be useful to set up a source tree to my framework source folder and link the framework projects relative to that. It also gives the added benefit of being able to have my framework source folder be independent from my workspace location. Problem is, Xcode doesn't allow this for projects. Cue sad Pilky.
We have a jump to definition feature, but no inverse. It is hard to be completely accurate with jump to callers in a dynamic language, as you can't really know that until runtime. However, you can find a lot of the places it will be called from, and indeed you need to already to perform many refactorings. Being able to click on a method declaration and see a list of all the places it is called from would solve a lot of problems that at the moment require a less intelligent project find.
Xcode lets you group files in the file navigator. You can link those groups to folders on disk. If you create a new file in that group it will default to putting it in the linked folder on disk. All really good so far. Unfortunately if you then try to move a file into or out of that group, it doesn't move on disk. It's a pretty basic operation you may want to do but it requires so much effort, moving around in the finder then fixing broken references in Xcode, and it's something that should be handled for you by Xcode.
I never found a use for bookmarks in Xcode 3. Now they're gone I can see how useful they could be. Being able to mark arbitrary points in your code and give them names can provide an easier way to navigate your code. Combined with the 'playlist' idea above it could give so much more flexibility in how you organise and navigate your code.
If you deal with frameworks, you may end up with the same project being added to multiple workspaces. This is useful for editing the framework inline with the app, but also for things such as debugging. The problem is, a project can only be open in one workspace at a time. This causes all sorts of issue, especially if you open them in the wrong order and the workspace you want to reference is opened first, meaning the workspace you want to work on won't build.
I'm sure other people have their own requests. Maybe it'd be useful for you to post your own along with radar numbers. For the most part Xcode 4 is a solid IDE, with very well thought out core principles. The only thing missing from giving it a solid foundation is stability and performance. Once it has that, then the Xcode team can really start powering ahead with new features to make our development lives easier.