andré michael bonkowski

Refactoring in AppCode

| Comments

AppCode offers a rich set of refactoring’s, which is fast, safe, and easy to use.

Rename

Naming is surprisingly difficult. It’s easy to get “paralyzed” if the perfect name of a class or method does not pops into place immediately. But hey, you can always rename it later!

The “Rename” refactoring in AppCode is triggered by the shortcut ⇧F6. By using this, you can rename a file, class, method, property, ivar, local variable, and so on. In the file or project view, the shortcut triggers renaming a file or a class.

Rename class from file or project view

If you just are renaming a file (such as a plist or an image), AppCode will rename the file, and also change where it is referenced. If you are renaming a class, both the header, and the implementation of the class is renamed, and the references of the files in the project file. If you select Rename when the cursor is on a class name used by the class, the selected class is renamed.

If you triggers the rename from inside the source file, the name of the class, variable, and so on, is entering a “edit mode,” almost like “Edit all in Scope,” in Xcode. The difference is that while in Xcode you renamed only the names inside the current class, the renaming in AppCode is global.

Inline rename class from the file or project view In the example above, changing the name KMRObjectViewLayout to something else, will rename the KMRObjectViewLayout class, it’s containing file, and all the references to the class.

Rename method inline

Here is an example of how it looks like when you are renaming a method name. All instances in scope are selected and edited.

Rename class from file or project view In the next example, shown above, we want to rename an instance variable. AppCode gives us a few name proposals, based on the name of the variable, and its usage. (As you can see, contentWidth is suggested based on the method name)

Change signature

I often begin with a method signature that after a while needs to be altered. This can be to include an additional argument, or maybe the argument is not needed anymore, or even the order of the arguments is not right. If the method is called from several places, this can be a time-consuming and error prone task. By using the ⌘F6, Change Signature, this is done in a simple and safe way.

The video below shows how you can use the Change Signature refactoring.

As you can see, this is a really powerful feature, which I use a lot. You can also change the return type, and even convert a method to a function or a block, or vice versa.

Convert

Converting a method to a function or a block can also be done by using one of the Convert to menu items. In addition to these, you also have Convert to Property and Convert to Instance Variable.

Move

The Move refactoring allows you to move a property, ivar’s and methods from one class to another. If the target class does not exist, you get a warning that tells you that. While this is correct, I would expect AppCode to ask whether I want to create the non-existing class. There is a feature request for this already registered in the AppCode issue tracker, so I expect it to be in a future build of the EAP.

Update: The “missing” feature is now fixed.

This is one of the other great things about JetBrains. They respond to bug reports and feature requests almost immediately, and the Issue Tracker is publicly visible.

Copy

When in the project browser, selecting a header, or an implementation file, or when inside one of these files, F5 will prompt you to enter the name of the new copy of the files, and where to copy them. While in the “To directory” input field ⌃␣ will provide path completion. When accepting, the class name inside the source files is changed as well.

Copy a class

Safe Delete

Before you delete a class or a file, you want to ensure that it’s not used somewhere. Safe Delete does that for you, and warn you if this is the case. Besides search for usages, by default it also searches in comments and strings. The keyboard shortcut for this are ⌦⌘

Extract…

There are several Extract factoring’s, and here is a short description of each:

Extract Variable

Let say that you have a hard coded value. You select the value, and type ⌥⌘V. AppCode will declare a variable above where it’s used, with the correct type, and the name of the new variable selected. To change the proposed name, just begin to type the name of the variable. If no value or expression is explicitly selected, AppCode gives you a suggestion of what to base the value of the introduced value from as shown in the example below:

Select variable expression

Extract Constant

This refactoring, ⌥⌘C, is similar to Extract Variable, but this introduces a constant instead. If no actual value is selected, AppCode gives you an opportunity to select what the constant is based on from values and expressions in scope. When the constant is selected, AppCode asks for you if you would like to replace only this one, or all similar values found in the current file.

Extract Parameter

If you are creating a variable inside a method, but you would like it to be passed as a parameter, Extract parameter, ⌥⌘ P is the refactoring you would like to use.

Extract Property

By using ⌥⌘E on a variable, AppCode shows a dialog where the declaration of the property is shown, togheter with a checkbox. If you check the checkbox, the property is generated in a private category. If not, the property is declared in the header.

Introduce property

Extract Instance Variable

By using ⌥⌘I on a local variable, AppCode changes it into an ivar, but with the option to generate a property for the variable if the checkbox is selected. You can also select to declare the ivar in the interface (which you don’t want to do).

Extract Define

⌥⌘F extracts a macro from the selected value or expression

Extract Typedef

As the name suggests, ⌥⌘F creates a typdef from the selected type.

Extract Method

This is one of the most my frequently used refactoring. Let say a method has too much responsibility, and you want to move some of the logic into a new method, Select the code you want to move, type ⌥⌘F, and AppCode generates a new method for you, including necessary parameters.

Extract method

As you can see from the screenshot above, it’s quite similar to Change Signature. The main difference is the Targets drop down. Depending on what you select in this drop down, the signature is declared in the header file, in a private category, or just in the implementation file.

Extract Block Parameter

By using Extract Block Parameter you select a chunk of code. A block declaration based on the selected code is created, and the signature of the method is changed to take a block of this type. Finally, the existing usages of this method are changed so that the extracted block is passed as a parameter.

Extract Superclass

To create a superclass from an existing class, the easiest way to accomplish this is to select the Extract Superclass. This refactoring does not have a default keyboard shortcut (You can create one yourself). You will be presented with a dialog where methods, properties, and ivars are shown in a list with checkboxes, and an input field where you type the name of the new superclass. You check the name of what you want to move into the new superclass. If one of the selected methods has dependencies to other methods, properties, or ivars, you get a warning, telling you about the problem. Extract Superclass

Extract Subclass

Here you create a subclass from a superclass. You select which methods, ivars and properties you want to take with you into the new subclass.

Extract Protocol and Category

Similar to the two above, except you are extracting protocols and categories.

Inline

If you want to inline a method, AppCode will move the implementation of the method into where it’s called from. If the method is called from more than one place, AppCode prompts you and asks for “Do you want to inline ‘n’ usages of method ‘mehodName’? You options are: cancel the refactoring, execute the operation or view usages of the method you have selected to inline. If you select the latter, a list of usages is shown, and while navigating in this list, you can exclude the calls you don’t want to inline by . If you change your mind, and want to include them again, you can do that by typing⇧⌫

Below is a sample of an excluded usage of a method. This feature is also used in all refactoring where the change will affect more than in one place. Excluded file

You can think of the Inline refactoring as an inverse of Extract Variable, Extract Constant and so on.

Pull Members Up and Pull Members Down

These refactoring’s are the same as Extract Superclass and Extract Subclass. (At least as far as I know).

Refactor This…

Refactor this If your having trouble remembering all the different Refactor keyboard shortcuts, you should at least try to learn this one: ⌃T. This shortcut will present a popup menu containing all the available refactoring’s, that you can select from, by using the number in front of the name, or navigate by using the arrow keys, and select the one you want by

If you are new to AppCode, or haven’t used the Refactorings that AppCode offers, I would suggest that you take a closer look at what it have to give.

Navigation in AppCode (EAP)

| Comments

Xcode

My first meeting with Xcode, which was version 3 something, did not impress me. A couple of years later, Xcode 4 was presented at WWDC 2010, and while my first impression was positive, this feeling was short lived. It crashed continually, and while it looked good, which it still does, the editing experience and feature set were far below my expectations for a modern IDE.

JetBrains

I know that more than 10 years experience with IDE’s from JetBrains, such as IntelliJ and RubyMine, does something with your expectations of what an IDE should provide. So, when you start using an another IDE, and you don’t find these features, it’s easy to render it useless. But for Xcode, it was not like that. I really wanted to like it. I used Xcode for over two years with my teeth clenched, (almost) without any complaints, because what other Objective-C IDE’s existed?

As you maybe have guessed, I used to be a Java developer (and still am if I really have to). One of the podcast`s I used to listen to then was “The Java Posse.” In October 2009 the posse had an interview with a couple of guys from JetBrains, Roman Strobl and Dmitry Jemerov, and in this talk Roman mentioned that they where working on an IDE for Objective-C. Before this I used to fantasize about a “IntelliJ for Objective-C,” but I never expected it to happen, and now they actually said that they were working on it. Wow!

Time went by, and in October 2011, I was working on a Rails project, and didn’t actually code that much in Objective-C, JetBrains released their first AppCode beta.

A couple of months later, I was hired to to work on a iOS project. I did use Xcode the first couple of weeks since the other team members used Xcode, but the frustration over Xcode and all its crashes made me do the switch. I have used AppCode everyday since then, and I have never looked back.

Why the love?

When fellow developers ask me: “what is so great about AppCode” (and the other JetBrains IDE’s), it’s not easy to give one simple answer. It’s not that there is one or two major features that makes it great. It is the collection of simple solutions to everyday tasks, such as quick and effective navigation in source and project, the VCS integration, the power of the editor, the refactoring support (including the speed and correctness of the refactorings), code generation, local history, completions, templates etc.

Key maps

AppCode support a few different key mappings, such as: Default, IntelliJ IDEA, Xcode, Visual Studio, ReSharper and Emacs. The video and screenshots in this blog post are taken from the Early Access Program for AppCode 2.0. This program allows developers to test and participate in discussions about the next release. I have more than once reported a bug, which has been fixed only a couple of days later. My experience with the EAP versions, is that they are quite stable, and I have had much fewer bugs and crashes using the EAP’s than Xcode.

Navigate to class

When you want to go to a class, you use the shortcut ⌘O to open the “Navigate to class” dialog. The video below shows different ways to use this shortcut to open a class.

Navigate to file

What if you want to navigate to a file other than a class, such as an image file or a plist? Open the “Navigate to file” dialog by typing ⇧⌘O

As you can see from the screenshot above, only so much of the filename is needed to identify the file, and any fragments of the filename can be used. This does also apply for “Navigate to class” and “Navigate to symbol” as described below.

Navigate to symbol

I know there is a method somewhere in the code called “initializeBadge, but I can’t remember in which class. The text search in AppCode is really fast, but here an even faster solution is to use. Open the “Navigate to symbol” dialog by typing ⌥⌘O and enter the name of the symbol you are looking for. Since’m lazy, I only type “initBad”.

If you have opened “Navigate to Class,” but you really wanted to “Navigate to File”, you don’t have to close the dialog, and then type the wanted shortcut again. You can toggle between the different dialogs, and text that you have entered is restored between the dialogs. The last text you typed is also remembered to the next time you use one of these navigation dialogs. I promise, you’ll going to use them a lot.

Recently Changed Files

The shortcuts I use the most must to be ⇧⌘E “View Recently Changed Files” and ⌘E “View Recent Files”. Usually, I edit a small set of related files, and are going back and forth between these files.

Navigation in code

When I code, I often want to navigate to the definition or declaration of a method, property, variable, and so on. The shortcuts I use to do this are “Goto Declaration” ⌘B and “Goto Definition” ⌥⌘B

If there are multiple definitions, such as for NSString, a list of the different definitions is shown.

You can also toggle between related files ⌃⌘↑. Unfortunately, this does not include going to the corresponding unit tests as of now, but the 2.0 EAP roadmap contains the following bullet point: “Navigation between test and code”.

What’s next?

The next post about AppCode is about refactoring…