A Skeleton Project for Scalable iOS Development

Folder management is as important as designing app architectures!

Intro

Okay, so this is my second post for my documentation blog or “tutorials”. Before I go further to introduce more tutorials and blogs, I like to introduce you to my Tutorial Project that I will working on for my tutorials and blogs.

This is NOT a must follow principles on structuring project files. Everyone has their own definition of things as well, and every project is special in their own way and may has their own configurations as well. So DON’T RESTRICT the creativity.

The purpose of this post is to share my recommendation on folder structure and its purposes.

Okay lets go to the point.

My Default MVVM + C App Skeleton

Its runnable. But still not much going on 😅😅.

What is this? What is that?

Okay lets jump from top to bottom. Remember, this definitions is from my perspective and personal opinion, please leave a comment if you have any suggestion or thoughts!

Application Folder

Application folder contains files that directly needed by the app to run such as AppDelegate or SceneDelegate, plists (Info.plist, Google-Service.plist), SSL certificate from SSL pinnings, many more. The AppCoordinator in my case is responsible on holding the app navigation controller, that’s why I put it there.

If you want to know how to configure these, scrolls down needed setup.

Helpers

Helpers as its name, is contains files that act as utilities for reusable operations that can be implemented in many different place throughout the app. For example, Extensions, DateHelper class, FontManager, CurrencyHelper and many more. I prefer not to contain any subclassed class because it has a place for its own later on (look in Supports). Helpers have to stand alone.

This is one of the example of my FontManager inside Helpers folder in my other project to get the idea.

enum DefaultFontName : String {
case regular = "Montserrat-Regular"
case bold = "Montserrat-SemiBold
case italic = "MontSerrat-Italic"
}
class FontManager {
static func getHeading1(fontAttribute : DefaultFontName)->UIFont
{ return UIFont(name: fontAttribute.rawValue, size: 24)! }
static func getHeading2(fontAttribute : DefaultFontName)->UIFont
{ return UIFont(name: fontAttribute.rawValue, size: 20)! }

static func getBody1(fontAttribute : DefaultFontName)->UIFont {
return UIFont(name: fontAttribute.rawValue, size: 16)!
}
}

It can stand alone, global, and serve a very specific purpose to provide standard fonts for the app.

Modules

This is the heart of the app. Where your view models, view controllers, coordinators and storyboards may have included. As you can see in the example, I divide the modules into some features group based on the flow of the app. Auth contains only for authentication views and operations in this app, it includes Login, Register, ChangePassword, OTP, and other account related features that you want to provide.

The best way to structure this folder is to look at the scope of the responsibility/usage that a class has. For example HomeTabBarCoordinator is put inside Main not inside Home, because it acts as a container and preparator for the Home, Profile and History. It initiates UITabbarController and starts HomeCoordinator, HistoryCoordinator and ProfileCoordinator with their own UINavigationController. So it doesn’t belong to Home, but outside of it because it’s responsibilty scope applies for all of the child folders (Home, History, Profile).

If there’s many coordinators inside a folder, you can create Coordinators folder, Views for cells, or custom views that used specifically inside the folder, ViewModels folder and also ViewControllers. Don’t hesitate to create Storyboards folder if you need to use many storyboards for a specific module. Folders are made to group. Don’t hesitate creating them! Treat them as modules and sub-modules and sub-sub-modules and sub-sub-sub-modules…

Sometimes, you can create a folder outside like Transactions. Transactions in this case is like a section/group of features inside of your home screen like Payments, to pay taxes, pay bills, pay insurance. Products, buy tickets, buy foods, buy groceries. It may be shown inside a home screen as a group. So if you can find something in common, yeah thats okay to make folders!

A very deep folder tree makes you harder to find files quickly. So treat them like a stand alone, like a module! Group them as much as you like based on their common functionalities as well.

Constants

Aah, the most useful one. It contains configurations, that remain constant throughout the app runs. In my case I store Configs, Colors, URLs, ErrorCodes, StatusCodes, Strings, etc. Some contains a struct with a static variables, others has enums. Don’t be afraid to separate them in many Swift Files. Like this!

It is easier to find a configuration this way rather than one file contains every constant in the app.

Models

In my case, models are used to store responses and requests model for the API. You have decode a JSON file structure to an object, it requires a blueprint, a model.

Models folder also can be used to represent data from Database, local or online.

Services

IF you want to create a service pattern for your network layer you can do it here. You can create a service class, or NetworkManager, LocalStorageManager, or Factories folder if you need one. Well, personally I don’t like to use Factories because its still very confusing for me 😅😅, So, I use Coordinators as my dependencies injector.

For example, AuthService, PaymentService, HomeService, etc.

Supports

Supports and Helpers are NOT the same. Supports are the building blocks of the app. For example BaseViewController, BaseTableViewController, etc or maybe Coordinator Protocol, ViewModel Protocol, Service Protocol and any protocols that has to be implemented in all corresponding components. It also contains many globally used view like custom popups, data pickers, loading screen, view subclasses.

I put my global custom button, or global custom textfield here as a subclass. Once again, don’t hesitate to create new folders. You can use Views to contains all of the necessary things you need.

Here’s is the idea of the Supports folder.

Globally reusable Views and Architectural Building Blocks.

I’m not using much of the protocols. But some folks may want to use it to standardize the components used by developers.

Assets

Simple. Contains Fonts, Assets.xcassets files in my scenario. You can add more like more xcassets if you want to, or maybe Videos, lottie animations, Audio and many more! Remember, don’t hesitate to create a folder to group those as needed.

Some needed setup.

Well I usually remove the Scene Delegate because I’m not using any SwiftUI just yet. You can find how to set it up here if you plan to use XIB or Storyboards.

Moving the Info.plist to another folder

First move your Info.plist to the target folder. If you run it, you’ll realized that the info.plist can’t be located by the compiler.

error: Build input file cannot be found: '/.../CoordinatorTutorial/CoordinatorTutorial/Info.plist' (in target 'CoordinatorTutorial' from project 'CoordinatorTutorial')

Open your .xcodeproj and navigate to Targets. You can search Info.plist inside the search bar or find it in Packaging section. Change the Info.plist File key to match as your destination folder path. In my case is CoordinatorTutorial/Application/Info.plist .

That’s how its done.

Moving the AppDelegate, LaunchScreen.storyboard, Assets.xcassets

nahh, just move it around, You’ll going to be fine. Just, don’t delete it if its not necessary.

Conclusion

So thats all for the introduction to my skeleton project. It can be implemented to other architecture as well like MVVM or MVP or MVC if you like. Remember, this is NOT a must follow principles on structuring project files. Everyone has their own definition of things as well, and every project is special in their own way. So DON’T RESTRICT the creativity.

I hope my post can be a great help in anyway.

Wish you all good health and a good food! 🍫🍲

Nomad Developer, Loves to travel and would walk for a coffee.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store