Every iOS developer that watches Worldwide Developers Conference, or watched it in 2019 at least, heard about something called “Swift Package Manager”. It has a big potential for a very useful tool for managing dependencies. Moreover, it is a big step further in making the coding easier, especially if we will think about iOS apps modularly.

 

swift package manager tutorial

 

What is a Modular iOS App?


If you have ever built a big application that was fetching data from a server, saving data on the device, or calculating a lot - you know, that it requires many lines of code. And also - many files to do it properly, using the principles of clean code. I bet you know from your own experience, how having too many files messes the whole project in terms of its clarity. Modular programming is what you need then to clean this all up!

Modular programming is the process of subdividing a computer program into separate sub-programs.

In other words, this approach makes our codebase cleaner by separating the independent parts of our code into modules. And, as you hopefully already know, a cleaner codebase means faster work in the future.

 

Swift Package Manager Introduction


As we can read on the official Swift website:

The Swift Package Manager is a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.



You might have heard of CocoaPods or Carthage. SPM (Swift Package Manager) is built to do exactly the same thing but is written in Swift and its purpose is to make it easier to manage dependencies in a project.

It is evolving and in 2019 it was integrated into Xcode - the main tool for Apple platforms development. Thanks to this, fetching and installing dependencies is now an automated process. You just need to open the project in Xcode and then it is automatically fetching and installing all required dependencies. Thankfully, more and more frameworks are available to use with SPM.

 

Swift Package Manager Tutorial: Creating a Modular iOS App Step by Step


I’ve divided this tutorial into two main sections. In the first one, you probably won’t learn anything new because we will create and set up a project to use it in the next section. In the second section, I will explain how to create modules for your app using SPM.

 

Section 1 - Start a New Project


1. Let’s create an empty iOS project in Xcode (we’re using Xcode 11.6 on macOS 10.15.6 in this tutorial).



swift package manager tutorial9

We will name the app “BitcoinValue” where we will display the current Bitcoin value in USD.

2. Open Main.storyboard and create a label there in the center and add constraints to center it in the superview.

swift package manager tutorial11
swift package manager tutorial7

3. Hook it to the ViewController class by clicking the ViewController.swift file with Option/Alt key and dragging it using the right mouse button.



swift package manager tutorial8

4. For now, on viewDidLoad() write a static value to it for example 100. So the class looks like this:


class ViewController: UIViewController {
    @IBOutlet private var label: UILabel!
  
    override func viewDidLoad() {
        super.viewDidLoad()
        label.text = "100"
    }
}


Section 2: Creating a module


Here we will create our first module which will contain our models. Since models are required by many parts of your app you will need to separate them. Moreover, if you use a backend in Swift using Vapor, it can be a good practice to always keep them in a separate module and import it from a separate repository.


1. Open your project in a Terminal.

 

The command for it varies depending on where you saved the project but it’s something similar to this:


  cd BitcoinValue

2. Create a swift package.


To do it simply run a few commands:


mkdir ModelsModule
cd ModelsModule
swift package init --name ModelsModule --type library


These commands will:
a) create “ModelsModule” folder
b) open the folder
c) create a Swift Package library named “ModelsModule” in the current folder.

3. Open the project folder in Finder.


You can do it quickly from the terminal:


open ..

The two dots “..” state for the parent directory. If you want to open a current directory simply write one dot instead of two.


4. Drag the “ModelsModule” folder to the Xcode project like this:

 

swift package manager tutorial5


The folder will then appear in this way:

swift package manager tutorial1

5. Link the module to the main app.

You can do it by opening the “General” tab in the project settings and clicking the plus button in section “Frameworks, Libraries and Embedded Content” and adding the “ModelsModule” library.

swift package manager tutorial10

 

swift package manager tutorial4


You just added an SPM module to the app. The project should compile without any problem at this moment. Also, it should compile the module, so if you mess something up in there, you will get a compiler error.


6. Create file “CoinsResponse.swift” in the sources of the ModelsModule

swift package manager tutorial2-2


and replace its content with this:


import Foundation

public struct CoinsResponse: Decodable {
    public let data: CoinsSuccessfulResponseData
}

public struct CoinsSuccessfulResponseData: Decodable {
    public let coins: [CoinData]
}

public struct CoinData: Decodable {
    public let id: Int
    public let name: String
    public let price: String
}

 

It’s important to make all of this public because we want to access it in the whole application.


7. Now by yourself create a module named “NetworkingModule” (steps 1-5).

8. Select NetworkingModule in Xcode

swift package manager tutorial12



end edit its content to import Restler (you can read about it here) and our ModelsModule.

So content of the Package.swift looks like this:


// swift-tools-version:5.2
import PackageDescription

let package = Package(
    name: "NetworkingModule",
    platforms: [
        .iOS(.v11),
    ],
    products: [
        .library(
            name: "NetworkingModule",
            targets: ["NetworkingModule"]),
    ],
    dependencies: [
        .package(name: "Restler", url: "https://github.com/railwaymen/restler.git", .upToNextMinor(from: "0.6.0")),
        .package(path: "../ModelsModule"),
    ],
    targets: [
        .target(
            name: "NetworkingModule",
            dependencies: ["Restler", "ModelsModule"]),
        .testTarget(
            name: "NetworkingModuleTests",
            dependencies: ["NetworkingModule"]),
    ]
)


9. Add function for downloading data from the server in “NetworkingModule” structure.

 


import Foundation
import Restler
import ModelsModule
 
public class NetworkingModule {
    public init() {}
    
    public func getBitcoinValue(handler: @escaping (Result<coinsresponse, error="">) -> Void) {
        guard let url = URL(string: "https://api.coinranking.com/v1/public/coins") else { return }
        Restler(baseURL: url)
            .get("")
            .query(["symbols": "BTC"])
            .decode(CoinsResponse.self)
            .onCompletion(handler)
            .start()
    }
}

10. Import ModelModule and NetworkingModule in our ViewController.swift file.

11. Fetch data in the ViewController. Add at the end of viewDidLoad function:


NetworkingModule().getBitcoinValue { [weak self] result in
    switch result {
    case let .success(response):
        self?.label.text = response.data.coins.first?.price
    case let .failure(error):
        debugPrint(error)
    }
}



Conclusion

 

Learning and exploring new solutions is a part of every programmer’s life. Without evolving we would stay in place while the whole world is running forward. I don’t mean we always have to run if the world is running but we cannot stop even if we would take a walk in our career temporarily.

This walk should happen every now and then to look for potential solutions for problems we are facing every day and maybe don’t even realize they are problematic until we see a solution for it. SPM I presented is a tool with great potential for being very useful in the development of mobile applications in the future.

At the same time, let's not forget, that the most valuable programmer is someone who not only knows how to code well but is also business oriented. The one, who will be able to tell the client, that this functionality might be done in a different way, to bring him higher revenue.

To become that person it's good to follow the newest infos from the development world - both technological and business. Sign up for our newsletter below, to stay on the top of the game!

 

PDF industry dedicated app examples
banner blog
Protenders banners-1

Recent Posts

FE_IR_rgb-4-kopia