AppCode 2019.2 Help

Extract

Extract variable

If you come across an expression that is hard to understand, or it is duplicated in several places throughout you code, you can place the result of such expression or its part into a separate variable using the Extract Variable refactoring ⌥⌘V.

Perform the Extract Variable refactoring

  1. In the editor, select an expression or its part you want to extract or just place the caret within this expression.

  2. Press ⌥⌘V or select Refactor | Extract | Extract Variable from the main menu.

  3. If you've placed the caret within the expression, AppCode will offer you a list of potential code selections. Choose the desired selection from the list.

  4. If the expression you want to extract is used multiple times, you can select whether you want to replace all occurrences or just the current one.

  5. If necessary, change the default variable name and use additional options:
    • For Swift: check Declare with 'var' if you want to declare a variable (with var). Deselect this checkbox to declare a constant (with let). Uncheck Specify type explicitly if you don't want to add a data type to the variable declaration.

    • For Objective-C: check Declare const to declare a new reference as a constant (with const):

  6. Press .

Code example

Before

After

- (void)performLogin { // self.textFieldEmail.text will be extracted // to the email variable BOOL isEmailValid = [self.emailValidator isEmailValid:self.textFieldEmail.text]; if (isEmailValid == NO) { [self.loginModel loginWithEmail:self.textFieldEmail.text]; } }
- (void)performLogin { // Extracted variable NSString *email = self.textFieldEmail.text; BOOL isEmailValid = [self.emailValidator isEmailValid:email]; if (isEmailValid == NO) { [self.loginModel loginWithEmail:email]; } }

Before

After

private func performLogin() { // email: self.textFieldEmail.text ?? will be extracted // to the email variable let isEmailValid = self.emailValidator.isEmailValid(email: self.textFieldEmail.text ?? "") if (isEmailValid == true) { self.loginModel.login(email: self.textFieldEmail.text ?? "") } }
private func performLogin() { // Extracted variable let email = self.textFieldEmail.text ?? "" let isEmailValid = self.emailValidator.isEmailValid(email: email) if (isEmailValid == true) { self.loginModel.login(email: email) } }

Extract closure

The Extract Closure refactoring helps you create a closure based on the selected chunk of code.

The refactoring is available for Swift only.

Perform the Extract Closure refactoring

  1. In the editor, select an expression which you want to extract into a closure.

  2. Press ⌃T and select Closure. Alternatively, select Refactor | Extract | Closure from the main or context menu.

  3. If there are several expressions available for extracting, select the required one from the list that opens and press .

  4. In the dialog that opens, type the name of the new closure and change the parameter names and types if necessary.

  5. Press .

Code example

Before

After

private func performLogin() { let emailField = self.textFieldEmail let email = emailField?.text ?? "" let isEmailValid = self.emailValidator.isEmailValid(email: email) // This expression will be extracted to closure emailField?.textColor = isEmailValid ? UIColor.black : UIColor.red // ... }
private func performLogin() { let emailField = self.textFieldEmail let email = emailField?.text ?? "" let isEmailValid = self.emailValidator.isEmailValid(email: email) // Extracted closure let setFieldStyle = { (textField: UITextField?, islValid: Bool) in textField?.textColor = islValid ? UIColor.black : UIColor.red } setFieldStyle(emailField, isEmailValid) // ... }

Extract constant

The Extract Constant refactoring helps you avoid using hardcoded constants without any explanations about their values or purpose.

The refactoring is available for Objective-C only.

Perform the Extract Constant refactoring

  1. In the editor, select an expression or declaration of a variable you want to replace with a constant.

  2. Press ⌥⌘C to introduce a constant or select Refactor | Extract | Constant from the main or context menu.

  3. If there are several expressions available for extracting, select the required one from the list that opens and press .

  4. Select a name for the constant from the list of suggestions that opens or type a new one.

  5. Check the Put to header checkbox if you want the constant to be moved to the header file.

  6. Uncheck the Declare static checkbox if you don't want the constant to be declared as static.

  7. Press .

Code example

Before

After

@implementation PasswordValidator + (BOOL)isPasswordValid:(NSString *)password { // 4 will be extracted to a constant return password.length > 4; } @end
// Extracted constant static const int kMinPasswordLength = 4; @implementation PasswordValidator + (BOOL)isPasswordValid:(NSString *)password { return password.length > kMinPasswordLength; } @end

Extract instance variable

With the Extract Instance Variable refactoring, you can place an expression into an instance variable.

The refactoring is available for Objective-C only.

Perform the Extract Instance Variable refactoring

  1. In the editor, select an expression you want to replace with an instance variable.

  2. Press ⌥⌘F or select Refactor | Extract | Instant Variable from the main or context menu.

  3. If there are several expressions available for extracting, select the required one from the list that opens and press .

  4. Select a name for the instance variable from the list of suggestions that opens or type a new one.

  5. If you want to create a property for the variable or declare it in the interface, select the corresponding checkboxes in the popup that opens.

  6. Press .

Code example

Before

After

@implementation LoginViewController { } - (void)performLogin { // ... [self.loginModel loginWithEmail:email password:password completion:^(BOOL success) { // success will be extracted to // an instance variable if (success) { [self showAlertLoginSuccess]; } else { [self showAlertLoginFailed]; } }]; }
@implementation LoginViewController { // Extracted instance variable BOOL _loginSuccessful; } - (void)performLogin { // ... [self.loginModel loginWithEmail:email password:password completion:^(BOOL success) { _loginSuccessful = success; if (_loginSuccessful) { [self showAlertLoginSuccess]; } else { [self showAlertLoginFailed]; } }]; }

Extract property

The Extract Property refactoring lets you move expressions and local declarations to properties.

The refactoring is available for Objective-C only.

Perform the Extract Property refactoring

  1. In the editor, select the expression or declaration you want to replace with a property.

  2. Press ⌥⌘E or select Refactor | Extract | Property from the main or context menu.

  3. If there are several expressions available for extracting, select the required one from the list that opens and press .

  4. Select a name for the property from the list of suggestions that opens or type a new one.

  5. If you want the property to be generated in a private category, select the Put to private category checkbox. Otherwise, the property will be declared in the header file.

  6. Press .

Code example

Before

After

@interface LoginViewController () // ... @end @implementation LoginViewController { } - (void)performLogin { // ... [self.loginModel loginWithEmail:email password:password completion:^(BOOL success) { // success will be extracted to // a property if (success) { [self showAlertLoginSuccess]; } else { [self showAlertLoginFailed]; } }]; }
@interface LoginViewController () // ... // Extracted property @property(nonatomic) BOOL loginSuccessful; @end @implementation LoginViewController { } - (void)performLogin { // ... [self.loginModel loginWithEmail:email password:password completion:^(BOOL success) { self.loginSuccessful = success; if (self.loginSuccessful) { [self showAlertLoginSuccess]; } else { [self showAlertLoginFailed]; } }]; }

Extract parameter

The Extract Parameter refactoring is used to add a new parameter to a method declaration and to update the method calls accordingly.

The refactoring is available for Objective-C only.

Perform the Extract Parameter refactoring

  1. In the editor, place a cursor within the expression that you want to introduce as a parameter

  2. Press ⌥⌘P or select Refactor | Extract | Parameter from the main or context menu.

  3. If there are several expressions available for extracting, select the required one from the list that opens and press .

  4. If you want to declare the generated parameter as a constant, check Declare const in the popup that opens.

  5. Press .

Code example

Before

After

@implementation Greeting { } - (NSString *)generateGreeting{ // This expression will be converted to // the method's parameter NSString *userName = @"Bob"; return [NSString stringWithFormat:@"Hello %@", userName]; } - (void)print { // Method's call NSLog(@"%@", [self generateGreeting]); } @end
@implementation Greeting { } // Method with the new parameter - (NSString *)generateGreeting:(NSString *)userName { return [NSString stringWithFormat:@"Hello %@", userName]; } - (void)print { // Method's call NSLog(@"%@", [self generateGreeting:@"Bob"]); } @end

Extract define

The Extract Define refactoring method defines the selected set of tokens as a macro using the #define directive and replaces the set of tokens with the macro call in the code. The macro definition can be located in the current file or moved to the related header file.

The refactoring is available for Objective-C only.

Perform the Extract Define refactoring

  1. In the editor, select the expression you want to replace with a macro call.

  2. Press ⌥⌘D or select Refactor | Extract | Extract Define from the main or context menu.

  3. If there are several expressions available for extracting, select the required one from the list that opens and press .

  4. If more than one occurrence of the selected expression is found, AppCode will suggest replacing all the occurrences or just the selected one. Select the desired option from the list that opens.

  5. Select a name for the macro from the list of suggestions that opens or type a new one.

  6. Select Put to header if you want to move the macro definition to the header file.

Code example

Before

After

@implementation Screen{ } - (CGPoint)getScreenCenter { // [UIScreen mainScreen].bounds.size will be extracted return CGPointMake(0.5 * [UIScreen mainScreen].bounds.size.width, 0.5 * [UIScreen mainScreen].bounds.size.height); } @end
// Extracted #define #define SCREEN_SIZE [UIScreen mainScreen].bounds.size @implementation Screen{ } - (CGPoint)getScreenCenter { return CGPointMake(0.5 * SCREEN_SIZE.width, 0.5 * SCREEN_SIZE.height); } @end

Extract typedef

The Extract Typedef refactoring changes the selected declaration of a type to a typedef definition. You can apply Extract Typedef when actual declaration is cumbersome, potentially confusing, or likely to vary from one implementation to another, or just to make code presentation more clear and readable.

The refactoring is available for Objective-C only.

Perform the Extract Typedef refactoring

  1. In the editor, select the type declaration to be re-declared.

  2. Press ⌥⌘K or select Refactor | Extract | Extract Typedef from the main or context menu.

  3. If there are several expressions available for extracting, select the required one from the list that opens and press .

  4. If more than one occurrence of the selected expression is found, AppCode will suggest replacing all the occurrences or just the selected one. Select the desired option from the list that opens.

  5. Select a name for the typedef from the list of suggestions that opens or type a new one.

  6. Select Put to header if you want to move the typedef definition to the header file.

Code example

Before

After

@interface LoginModel : NSObject - (void)loginWithEmail:(NSString *)email password:(NSString *)password // void (^)(BOOL success) will be extracted to a typedef completion:(void (^)(BOOL success))completion; @end
// Extracted typedef typedef void (^LoginModelCompletion)(BOOL); @interface LoginModel : NSObject - (void)loginWithEmail:(NSString *)email password:(NSString *)password completion:(LoginModelCompletion)completion; @end

Extract method

The Extract Method refactoring lets you take a code fragment that can be grouped together, move it into a separated method and replace the old code with a call to the method.

The Extract Method refactoring has the following limitations:

  • Refactoring does not work with multiple output values in the automatic mode. You have to change your code before applying the refactoring, for example, you may introduce a special data-class that contains all output values.

  • Refactoring does not work for a code fragment which conditionally returns from the containing method and is not placed at the end of it.

To reverse the Extract Method refactoring, press ⌥⌘N to invoke the Inline refactoring.

Perform the Extract Method refactoring

  1. Select a code fragment you want to extract to a method.

  2. Press ⌥⌘M or from the main or context menu, select Refactor | Extract | Method.

  3. In the dialog that opens, configure method options, such as visibility, parameter names, selector parts (for Objective-C), and so on. You can also change a name of the method if you need.

  4. Click Extract.

Code example

Before

After

- (void)setupUI { // ... // This code will be extracted to a method self.textFieldEmail.placeholder = @"Email"; self.textFieldEmail.keyboardType = UIKeyboardTypeEmailAddress; self.textFieldEmail.autocorrectionType = UITextAutocorrectionTypeNo; self.textFieldEmail.autocapitalizationType = UITextAutocapitalizationTypeNone; [self setIsValid:YES forTextField:self.textFieldEmail]; }
- (void)setupUI { // ... // Extracted method's call [self setupTextFieldStyle]; } // Extracted method - (void)setupTextFieldStyle { self.textFieldEmail.placeholder = @"Email"; self.textFieldEmail.keyboardType = UIKeyboardTypeEmailAddress; self.textFieldEmail.autocorrectionType = UITextAutocorrectionTypeNo; self.textFieldEmail.autocapitalizationType = UITextAutocapitalizationTypeNone; [self setIsValid:YES forTextField:self.textFieldEmail]; }

Before

After

private func setupUI() { // ... // This code will be extracted to a method self.textFieldEmail.placeholder = "Email" self.textFieldEmail.keyboardType = .emailAddress self.textFieldEmail.autocorrectionType = .no self.textFieldEmail.autocapitalizationType = .none self.setIsValid(isValid: true, textField: self.textFieldEmail) }
private func setupUI() { // ... // Extracted method's call setupTextFieldStyle() } // Extracted method private func setupTextFieldStyle() { self.textFieldEmail.placeholder = "Email" self.textFieldEmail.keyboardType = .emailAddress self.textFieldEmail.autocorrectionType = .no self.textFieldEmail.autocapitalizationType = .none self.setIsValid(isValid: true, textField: self.textFieldEmail) }

Extract block parameter

With the Extract Block Parameter refactoring, you can create a block declaration based on the selected chunk of code within a method. As a result, the created block is passed as a parameter to this method, and all existing usages of this method are changed accordingly.

The refactoring is available for Objective-C only.

Perform the Extract Block Parameter refactoring

  1. In the editor, select a chuck of code (within a method) which you want to replace with a block declaration.

  2. Select Refactor | Extract | Extract Block Parameter from the main or context menu.

  3. In the dialog that opens, type the name of the block. If necessary, add/delete parameters, edit parameter names and types, and click Extract.

Code example

Before

After

- (void)performLogin { // ... [self.loginModel loginWithEmail:email password:password completion:^(BOOL success) { // This code block will be extracted if (success) { [self showAlertLoginSuccess]; } else { [self showAlertLoginFailed]; } }]; } - (IBAction)buttonLoginPressed:(id)sender { // Method's call [self performLogin]; }
- (void)performLogin:(void (^)(BOOL))completion { // ... [self.loginModel loginWithEmail:email password:password completion:^(BOOL success) { // Extracted block completion(success); }]; } - (IBAction)buttonLoginPressed:(id)sender { // Method's call with the extracted block // as a parameter [self performLogin:^(BOOL controller) { if (controller) { [self showAlertLoginSuccess]; } else { [self showAlertLoginFailed]; } }]; }

Extract superclass

The Extract Superclass refactoring enables extracting certain members of a class into a newly created superclass.

The refactoring is available for Objective-C only.

Perform the Extract Superclass refactoring

  1. Select the desired class in the editor.

  2. Select Refactor | Extract | Superclass from the main or context menu.

  3. In the dialog that opens, type the name of the new superclass, select the members that you want to move to the superclass, and click Extract.

Code example

Before

After

// All methods of the Dog class // will moved to a superclass // Dog.h @interface Dog : NSObject - (void)run; - (void)eat; @end // Dog.m @implementation Dog { } -(void)run { NSLog(@"I am running"); } - (void)eat { NSLog(@"I am eating"); } @end
// New superclass // Animal.h @interface Animal : NSObject - (void)run; - (void)eat; @end // Animal.m @implementation Animal { } -(void)run { NSLog(@"I am running"); } - (void)eat { NSLog(@"I am eating"); } @end // The Dog class is now a subclass // of the Animal class // Dog.h @interface Dog : Animal @end // Dog.m @implementation Dog { } @end

Extract subclass

The Extract Subclass refactoring enables extracting certain members of a class into a newly created subclass.

The refactoring is available for Objective-C only.

Perform the Extract Subclass refactoring

  1. Select the desired class it in the editor.

  2. Select Refactor | Extract | Subclass from the main or context menu.

  3. In the dialog that opens, type the name of the new subclass, select the members that you want to move there, and click Extract.

Code example

Before

After

// Animal.h @interface Animal : NSObject - (void)meow; - (void)run; - (void)eat; @end // Animal.m @implementation Animal { } // This method will be moved // to a subclass - (void)meow{ NSLog(@"Meow!"); } - (void)run { NSLog(@"I am running"); } - (void)eat { NSLog(@"I am eating"); } @end
// New subclass // Cat.h @interface Cat : Animal - (void)meow; @end // Cat.m @implementation Cat { } - (void)meow{ NSLog(@"Meow!"); } @end // The Animal class // Animal.h @interface Animal : NSObject - (void)run; - (void)eat; @end // Animal.m @implementation Animal { } - (void)run { NSLog(@"I am running"); } - (void)eat { NSLog(@"I am eating"); } @end

Extract protocol

With the Extract Protocol refactoring you can create a new protocol based on the members of the current class.

The refactoring is available for Objective-C only.

Perform the Extract Protocol refactoring

  1. Select the desired class in the editor.

  2. Select Refactor | Extract | Protocol from the main or context menu.

  3. In the dialog that opens, type the name of the new protocol, select the members that you want to move there, and click Extract.

Code example

Before

After

// Dog.h @interface Dog // This method will be extracted // to a protocol - (void)swim; - (void)run; - (void)eat; @end // Dog.m @implementation Dog { } - (void)swim { NSLog(@"I am swimming"); } - (void)run { NSLog(@"I am running"); } - (void)eat { NSLog(@"I am eating"); } @end
// New protocol // Swimmable.h @protocol Swimmable <NSObject>> - (void)swim; @end // Dog.h @interface Dog <Swimmable> - (void)run; - (void)eat; @end // Dog.m @implementation Dog { } - (void)swim { NSLog(@"I am swimming"); } - (void)run { NSLog(@"I am running"); } - (void)eat { NSLog(@"I am eating"); } @end

Extract category

With the Extract Category refactoring you can create a new category based on the members of the current class.

The refactoring is available for Objective-C only.

Perform the Extract Category refactoring

  1. Select the desired class in the editor.

  2. Select Refactor | Extract | Category from the main or context menu.

  3. In the dialog that opens, type the name of the new category, select the members that you want to move there, and click Extract.

Code example

Before

After

// Cat.h @interface Cat : NSObject - (void)purr; - (void)meow; @end // Cat.m @implementation Cat { } // This method will be extracted // to a category - (void)purr { NSLog(@"Purr, purr, purr..."); } - (void)meow { NSLog(@"Meow!"); } @end
// New category // Cat+Purr.h @interface Cat (Purr) - (void)purr; @end // Cat+Purr.m @implementation Cat (Purr) - (void)purr { NSLog(@"Purr, purr, purr..."); } @end // Cat.h @interface Cat : NSObject - (void)meow; @end // Cat.m @implementation Cat { } - (void)meow { NSLog(@"Meow!"); } @end
Last modified: 10 October 2019