iOS App Development
How to Create Your Own Framework for Your iOS App
In this tutorial we’ll create a framework for your app. It’s a good way to divide your app into independent modules and allow to reuse your code in different apps.

In this tutorial, we use the latest version of Xcode (11.3.1) and macOS Catalina (10.15.4) for the moment of writing.
Usually, it’s a good idea to divide your app into separate parts. It allows you to make your modules even more independent, test them separately, reuse code and even create independent frameworks and deliver them into your app using Swift Package Manager (SPM), CocoaPods or Carthage supporting different versions for different apps.
Sounds awesome, right? But even if it doesn’t, let’s create a new framework and we’ll see how good it is.
You can use this tutorial on its own, yet it uses SwiftUI and Combine, frameworks introduced by Apple in 2019, so if you have no prior experience working with these frameworks, I recommend to take a look at the previous parts where we created the app we’re going to use in this tutorial. After all, these frameworks look promising and awesome.
To check the other parts, use the following links:
- Getting Started with SwiftUI and Combine Using MVVM and Protocols for iOS.
- Creating an iOS App With SwiftUI and Combine Using MVVM and Protocols.
- Creating an iOS App With SwiftUI, Combine, MVVM, and Protocols [Part 3].
- How to Create Your Own Framework for Your iOS App (this tutorial).
- Using Core Data in Your SwiftUI App with Combine, MVVM and Protocols.
If you don’t want to check the previous parts and prefer to start from here, download the complete code for the app we’re going to improve with our new frameworks here.
What we will learn
As source code, we have an app written with SwiftUI and Combine. It uses Protocols and MVVM. The issue is that the app doesn’t have a persistent storage for its data. But, fortunately, we created a protocol for our DataManager there that stores all the data in an array, so we can replace it with another one and implement a persistent storage touching no other parts of the project. We’re going to do it in the next tutorial but now, let’s do some preparations.
By the end of this tutorial we will learn:
- How to create frameworks inside of the project;
- How to add other frameworks as a dependency into an app or into another framework;
- How to use one framework for iOS, watchOS, macOS, tvOS.
We’ll prepare everything to add a Core Data storage into the app and use it instead of just an array that’s not persistent for sure.
Getting Started
Open the project developed in the previous parts (or download the app here and open it in Xcode). Your app is a To-do list app, you can build and run it and add new tasks there and mark them as completed. Also, you can toggle between showing or hiding completed tasks.
How to Create a Framework
Now, we’re going to create a new framework. This framework will contain only a protocol that’ll describe how our database helpers should work. After a while, we’ll create another framework specifically for Core Data and make it conform to the protocol. In the future, should we change the database, we’ll replace Core Data with Realm, SQL or whatever we want changing only the helper.
I know it might be too much to create two frameworks for just a tiny database, but it eventually pays off when you decide to start a new project, migrate this to a new database or when your project grows.
Create a Workspace
Let’s start by creating a workspace where we put our project and all the modules we’re going to create. Actually, when your app grows, it’s better to import your frameworks into the project using CocoaPods, Carthage or Swift Package Manager, but we won’t cover how to do that in this tutorial, so we’ll go a simpler way.
Choose File — New — Workspace. Find the root folder for your project and select it, call your workspace as your project (DemoToDoList.xcworkspace) and click Save.
After that, close your project if it’s open, then find DemoToDoList.xcodeproj in Finder, drag & drop it into the workspace. Now, try to run your project. Everything should work as it did before.
Create a framework
It’s time to create a new framework. Choose File — New — Project in the menu. Select Framework in the Framework & Library section on the iOS tab, then click Next. Type DBHelper in the Product Name, unselect Include Unit Tests, make sure the language is Swift, then click Next. In the next window find the root folder of your project, select it, click New Folder, type Modules, click Create. Now you have your new folder Modules selected.
In the bottom of the window, find Add to and select your workspace there (in my case it’s DemoToDoList). In the Group choose the workspace too. Make sure you see something like this:

Click Create.
Now you can see your new framework near your project in the Project Navigator. You can choose its scheme and build it.

It should look as on the screenshot.
Now you have an empty (almost) project. You will create new files here and make public only those classes and functions you want your app to use. That scheme makes it easier to avoid tight coupling between classes and allows you to store all the code related to one particular feature in a separate place.
Now, let’s switch to the DBHelper scheme, click the name of the current scheme (probably DemoToDoList) on the right of the Stop button and choose the new one.
First, we’ll set the minimum iOS version to 13 (we’re using SwiftUI and Combine, no need to support earlier versions, but we could do that if we decided to use this framework in other projects.
Choose your framework in the Project Navigator, select DBHelper in Targets, in Deployment Info set Target to 13.0. After that, choose DBHelper under Project and set iOS Deployment Target to 13.0 too.
Now, expand DBHelper in the Project Navigator then expand the DBHelper folder. You should see DBHelper.h and Info.plist files. Create a new group by using right-click on the DBHelper folder, name it Sources. We’ll store all the files in that folder.
DBHelperProtocol
Create a new Swift file (Cmd+N), name it DBHelper. Now, let’s create a protocol for our future database helpers. It should look as follows:






