How to Create Your Own Framework for Your iOS App

Andreea Andro
5 min readNov 18, 2022

We’ll see how to create a framework, which is the way to go for if you want to divide your app’s logic into independent modules and reuse your code in other apps.

Photo by Taras Shypka on Unsplash

Focusing on:

  • How to create frameworks inside of the project
  • How to add other frameworks as a dependency into an app or into another framework

I will be following this tutorial, made by Alex Zarr, and the supporting project I will start from is available here.

Create a Workspace

Let’s start by creating a workspace where we put our project and all the modules we’re going to create.

Choose FileNewWorkspace. 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.

Moving from A) A project “DemoToDoList” to B) A workspace containing a single project “DemoToDoList”

Create a framework `DBHelper`

Choose FileNewProject in the menu. Select Framework in the Framework & Library section on the iOS tab, then click Next. Type DBHelper in the Product Name, 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.

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:

import Foundation

public protocol DBHelperProtocol {
associatedtype ObjectType
associatedtype PredicateType

func create(_ object: ObjectType)
func fetchFirst(_ objectType: ObjectType.Type, predicate: PredicateType?) -> Result<ObjectType?, Error>
func fetch(_ objectType: ObjectType.Type, predicate: PredicateType?, limit: Int?) -> Result<[ObjectType], Error>
func update(_ object: ObjectType)
func delete(_ object: ObjectType)
}

public extension DBHelperProtocol {
func fetch(_ objectType: ObjectType.Type, predicate: PredicateType? = nil, limit: Int? = nil) -> Result<[ObjectType], Error> {
return fetch(objectType, predicate: predicate, limit: limit)
}
}
  • We make our protocol public because it should be visible outside of the framework;
  • We create associatedType ObjectType and PredicateType because these types are different depending on a particular database (for Core Data it’s NSManagedObject and NSPredicate. We need to specify these generic types so we can use this DBHelperProtocol universally;

You can try to build the framework to make sure everything’s correct.

That’s pretty much it for that framework. Not much of code, huh? But the point is to have DBHelperProtocol so all our database helpers will conform to them and the whole app won’t know about any changes, should we change database storage.

watchOS support for `DBProtocol`

How to add watchOS support to our framework? By creating a dedicated target:

Choose the DBHelper framework in the Project Navigator. Click File — New — Target, select the watchOS tab, find the Framework & Library section and choose Framework there, then click Next. Name it as DBHelper watchOS, make sure DBHelper is chosen as Project, then click Finish.

Now, choose DBHelper.h in the DBHelper folder, choose the File Inspector in the right panel, and select DBHelper watchOS in the Target Membership field. Then do the same for DBHelper.swift.

Then, delete the DBHelper watchOS folder with moving all the files to Trash.

Optional: choose the DBHelper framework in the Project Navigator, then choose the DBHelper watchOS scheme, go into Build Settings, and change Product Name to $(PROJECT_NAME).

Now, if you choose the watchOS scheme, it should build without errors.

Add the framework to your app

The last thing is to add the framework to the project. Choose the project in the Project Navigator (DemoToDoList or the name of your app), choose the target there, find the Frameworks, Libraries, and Embedded Content section there and add the framework using the plus button (make sure you add the iOS framework, not the watchOS one).

Now, you can choose the project’s scheme and try to build the app. Everything should work fine.

Using the framework

The framework we’ve just created only exposes an API Contract related to working with a database. The next step would be to add concrete implementations for our preferred databases — for instance CoreData or Realm. We’ll import the framework with import DBHelper .

import DBHelper
import Foundation
import CoreData

class CoreDataHelper: DBHelperProtocol {
typealias ObjectType = NSManagedObject
typealias PredicateType = NSPredicate

func create(_ object: NSManagedObject) {}

func fetchFirst(_ objectType: NSManagedObject.Type, predicate: NSPredicate?) -> Result<NSManagedObject?, Error> {
return .failure(CoreDataHelperErrors.notImplemented)
}

func update(_ object: NSManagedObject) {}

func delete(_ object: NSManagedObject) {}
}

enum CoreDataHelperErrors: Error {
case notImplemented
}

--

--