What Is Other Option Available in Swift Instead of Refactoring and Renaming Class or Attribute Name

How do I refactor Swift in Xcode?

AFAIK the refactoring is not working with Swift right now, however, at least in the same file(scope), you can do the following:
Sample Image

How do I completely rename an Xcode project (i.e. inclusive of folders)?


Step 1 - Rename the project

  1. Click on the project you want to rename in the "Project navigator" in the left panel of the Xcode window.
  2. In the right panel, select the "File inspector", and the name of your project should be found under "Identity and Type". Change it to your new name.
  3. When the dialog asks whether to rename or not rename the
    project's content items, click "Rename". Say yes to any warning about uncommitted changes.

Step 2 - Rename the scheme

Note: for Xcode 14, Sept. 2022: in some cases Xcode now automatically renames the scheme, when Xcode performs Step 1 above. If so, there is nothing to do in Step 2.

  1. At the top middle of the window, to the left of the active device/simulator, there is a scheme for your product under its old name; click & hold on it, then choose "Manage Schemes…".
  2. Click on the old name in the scheme (similar to renaming files in Xcode) and it will become editable; change the name and click "Close".

Step 3 - Rename the folder with your assets

  1. Quit Xcode. Rename the master folder that contains all your project files.
  2. In the correctly-named master folder, beside your newly-named .xcodeproj file, there is probably a wrongly-named OLD folder containing your source files. Rename the OLD folder to your new name. {If you use git you could use git mv oldname newname. Note that when using git mv old new you generally must (i) completely commit all other changes (ii) only then git mv old new (iii) commit that (iv) only then make further changes. If steps i-ii-iii-iv are followed, git will maintain history through the rename.}
  3. Re-open the project in Xcode. If you see a warning "The folder OLD does not exist", dismiss the warning. The source files in the renamed folder will have red names because the path to them has broken.
  4. In the "Project navigator" in the left-hand panel, click on the top-level folder representing the OLD folder you renamed.
  5. In the right-hand panel, under "Identity and Type", change the "Name" field from the OLD name to the new name.
  6. Just below that field is a "Location" menu. If the full path has not corrected itself, click on the nearby folder icon and choose the renamed folder. You may have to perform this fix for each source file if the links to them remain broken.

Step 4 - Rename the Build plist data

  1. Click on the project in the "Project navigator" on the left, and in the main panel select "Build Settings".
  2. Search for "plist" in the settings.
  3. In the Packaging section, you will see fields for Info.plist and Product Bundle Identifier.
  4. If there is a file name entered in Info.plist, update it (it may have been updated automatically in Step 1).
  5. Do the same for Product Bundle Identifier, unless it is utilizing the ${PRODUCT_NAME} variable. In that case, search for "product" in the settings and update Product Name. If Product Name is based on ${TARGET_NAME}, click on the actual target item in the TARGETS list on the left of the settings pane and edit it, and all related settings will update immediately.
  6. Search the settings for "prefix" and ensure that Prefix Header's path is also updated to the new name.
  7. If you use SwiftUI, search for "Development Assets" and update the path. Enclose in double-quotes ("") quotes if the path contains a space ( ).
  8. If you have an entitlements file, search for "signing" and update Code Signing Entitlements. Accordingly, rename the actual entitlements file in the Project Navigator also. (Side note: In Xcode 13 entitlements files have a yellow checkmark icon in the Project Navigator; you may have created one if e.g. you use shared containers/App Groups.)

Step 5 - Repeat step 3 for tests (if you have them)

Step 6 - Repeat step 3 for core data if its name matches project name (if you have it)

Step 7 - Clean and rebuild your project

  1. Command + Shift + K to clean
  2. Command + B to build

Further points.

  • If the project has storyboards.

At this stage, open the overall folder simply in the Mac finder. Type the old name in the file text search. You will see that the old name appears very often as customModule="OldName" in all storyboard files. (Explanation.) These can be fixed, in Xcode, one by one, on each storyboard: Tap on the view controller. Tap on the Identity Inspector (4th small button) in the right hand panel. Look at the Custom Class -> Module field. Notice it seemingly shows NewName. However (still as of Xcode14) it's incorrect. Simply tap the drop-down, and explicitly select the new name. (If you now review that storyboard file with a text editor, you will see it is fixed.) You may prefer to change them all just using a plain text editor.

What is refactoring and what is only modifying code?

Martin Fowler's "Refactoring: Improving the Design of Existing Code" is perhaps THE reference:

Refactoring is a controlled technique
for improving the design of an
existing code base. Its essence is
applying a series of small
behavior-preserving transformations,
each of which "too small to be worth
doing". However the cumulative effect
of each of these transformations is
quite significant. By doing them in
small steps you reduce the risk of
introducing errors. You also avoid
having the system broken while you are
carrying out the restructuring - which
allows you to gradually refactor a
system over an extended period of
time.

Refactoring goes hand-in-hand with unit testing. Write tests before you refactor and then you have a confidence level in the refactoring (proportional to the coverage of the tests).

A good reference is: Information about Refactoring

With JSONDecoder in Swift 4, can missing keys use a default value instead of having to be optional properties?

Approach that I prefer is using so called DTOs - data transfer object.
It is a struct, that conforms to Codable and represents the desired object.

struct MyClassDTO: Codable {
let items: [String]?
let otherVar: Int?
}

Then you simply init the object that you want to use in the app with that DTO.

 class MyClass {
let items: [String]
var otherVar = 3
init(_ dto: MyClassDTO) {
items = dto.items ?? [String]()
otherVar = dto.otherVar ?? 3
}

var dto: MyClassDTO {
return MyClassDTO(items: items, otherVar: otherVar)
}
}

This approach is also good since you can rename and change final object however you wish to.
It is clear and requires less code than manual decoding.
Moreover, with this approach you can separate networking layer from other app.

Objective C Reflection - Extracting Property name

I don't know a way of achieving quite what you want. However, you could perhaps make access using hard-coded key names somewhat safer. For example, you might make a macro like:

#define CHECKED_PROPERTY(obj, prop) ((void)((obj).prop), @#prop)

This macro expands to an expression using the comma operator. First the obj.prop sub-expression is evaluated, but its result is discarded. The point of this is just to make the compiler validate the expression, so it will complain if prop is not a valid property of obj. The second sub-expression stringifies the prop argument using the # preprocessor operator. It prefixes it with @ to turn the string literal into an Objective-C NSString literal.

And use it like so:

NSString* key = CHECKED_PROPERTY(foo, p);

This expands to:

NSString* key = ((void)((foo).p), @"p");

This evaluates foo.p but ignores the result and has the effect of setting key to @"p".

Then if you refactor and rename p to x, either the refactor engine (if it's really smart) will figure out that it needs to do something with the above, or at least the compiler will complain if the refactor misses it. (This falls down if you rename p to x and q to p, though.)



Related Topics



Leave a reply



Submit