Best practices to re-structure my already existing project

Hi,


I started programming on iOS a couple of years ago, and created my first app while learning Objective-C and the whole structure of xCode. Needless to say that any project structure/best practices were completely non-existent back then, because I was learning the basics and only focusing on "making it work".

Through a quite cool turn of events, the app has actually grown hugely, and it's now a big project involving multiple people, but I'm still the only iOS developper.


The app works great, but the code/structure itself is really bad. Basically, all my files are together in a main folder, a lot of code is copied across the app multiple times. The same happens in my Storyboard: I have some custom cells that are re-used in 5 or 6 different views, and I have 6 different copies of that particular custom cell, with some minor changes in between them. But for maintenance, it's an absolute nightmare.


I decided to take some time now to restructure everything, because going forward it will be impossible to work with other iOS developpers on this project if the structure isn't good.


But where should I start? It seems so difficult now, with the amount of code and views I already have. I absolutely know I've been really, really stupid to wait so long to do this, but I really need some help/advice now on how to get out of this mess.


Thanks a lot guys!

Assuming your app already uses strong MVC (Model View Controller) design, I would start by organizing the existing files into a nice folder structure. Remove the files from your project (remove references only), create that folder structure on disk, then mirror that structure in your Xcode project. For my projects, I typically have this folder structure at a minumum:


+ Application (contains main app controller and any app-level items)
+ Models
+ Views
+ Screens (I tend to use the word 'screens' instead of Controllers)
+ Utilities


In complex cases, I'll also add subfolders/subgroups to each.


You can then see if it makes sense to "package" up certain folders and make them nested projects, frameworks, etc. e.g. you may find a set of utilities to be useful across many different apps. By having that as a separate area, easy to have a different team maintain it.


As a second pass throughout your codebase, refactor to merge redundant pieces of code.

Hi rsharp,


thanks a lot for your answer. Would you please help me by expliciting what each of the folders should contain? What is the difference between Models, Views and Screens? I'm pretty new to all of this, and have absolutely never thought about it, so yeah.


Concerning the refactoring, how should I refactor the Storyboard custom cells that are duplicate? My current situation:

in my main Storyboard I have multiple UIViewControllers that contain an UITableView that contain one or multiple custom UITableViewCells.


Then, in the implementation file of these different UIViewControllers, I have some UITableView delegate methods that implement the cell (cellForIndexPath), etc. Most of the time, that code is more or less similar. But it is duplicated a couple of times.


How can I get out of that? Where do I centralize that code and the Custom Cell?


As you can notice, I'm really new (or bad, as you want ;-) ) at this, and have absolutely no clue as to how to do this.


Thanks !

As directed, use design patterns such as MVC but also delegation, model object, factory.


For those part your code that are duplicated, extract them in an object and instantiate it at the point of use.

Common tenets of OOD are:

  • Favor composition over inheritance.
  • Encapsulate the concept that varies.
  • Commit to an interface, not to an implementation.

AppCode from JetBrains is an IDE that works in tandem with XCode and offers powerful refactoring tool for Objective C and Swift.

For your folders, you can start by creating a folder for each functional section of your application. Then create subfolders in each, e.g model, view and controller.

In our project, we have subfolders for each feature folder, like so (you don't have to do this, but I show it for the sake of example):

Storyboard >> Main storyboard for that feature

Module >> Each functional part of the feature has is its own module and has the following subfolders: Model, ViewController, Library, Factory

Component >> UI controls specific to that feature (each has its own storyboard)

Factory >> Object creational classes

Entity >> Model objects

Data >> Data stores

Config >> Configuration files

Library >> Helpers, handlers, managers

Facade >> Classes that invoke services and process the result

Style >> Style objects contain data like color values

Concerning the UITableViewDelegate and UITableViewDataSource methods that are similar, the best practice is to encapsulate them as separate objects.


Have objects like so:


@interface InvoicesDataSource : NSObject <UITableViewDataSource> {...}
@interface InvoicesDelegate : NSObject <UITableViewDelegate> {...}


Instead of making self the delegate and the datasource, create instances of these objects and assign them as the delegate and the datasource.


This way, you can make them re-usable. If some aspects of your data sources and delegates vary, encapsulate what varies into yet other objects that all conform to the same protocol. These other objects will configure your data sources and delegates.


There is a book by Addison Wesley written for such a case as yours when you need to refactor an entire application: Refactoring to Patterns.

Best practices to re-structure my already existing project
 
 
Q