Create Static Library in swift

Kanan Abilzada
6 min readAug 4, 2021

--

In this tutorial, I wanna show you how create static library for your reusable code.

Why do you need to Library? This way helps to you for reduce your reusing codes. You can use for network requests, extensions etc (your reuse codes in each your project). Let’s get started.

First step click: File > New > Project. You have to choose `Static Library` on here and hit next.

I’ll create it for my network requests, so called it “MyNetwork” and make sure was choose swift below side and hit next. Save it where you want.

Okay, we created our library and you can see files. Open MyNetwork.swift file. You’ll see empty “MyNetwork” class only and let’s start to changing MyNetwork class.

I was got MyNetwork code struct from Majid’s gist (https://gist.github.com/mecid/bfb7201b6436b68ba9a29a933ad91e05)

import UIKitpublic enum HTTPMethod: String {
case put = "PUT"
case post = "POST"
case get = "GET"
case delete = "DELETE"
case head = "HEAD"
}
public protocol Request {
var scheme: String { get }
var method: HTTPMethod { get }
var path: String { get }
var host: String { get }
var queryItems: [URLQueryItem] { get }
var headers: [String: String] { get }
var body: Data? { get }
}
public extension Request {
var scheme: String { return "https" }
var method: HTTPMethod { return .get }
var headers: [String: String] { return [:] }
var body: Data? { return nil }
}
public extension Request {
build() -> URLRequest {
var components = URLComponents()
components.scheme = scheme
components.host = host
components.path = path
components.queryItems = queryItems
guard let url = components.url else {
preconditionFailure("Invalid url components")
}
var request = URLRequest(url: url)
request.allHTTPHeaderFields = headers
request.httpMethod = method.rawValue
request.httpBody = body
return request
}
}public struct DataLoader {
public init () {}
public func request<T: Decodable>(_ request: Request, decodable: T.Type, then handler: @escaping (Result<T, NetworkError>) -> Void) { let urlSession = URLSession(configuration: .default)
let task = urlSession.dataTask(with: request.build()) { data, urlResponse, error in
if let _ = error {
handler(.failure(.cannotGetData))
} else {
if let data = data {
do {
let decodedData = try decoder(with: data, decodable: decodable)
handler(.success(decodedData))
} catch {
handler(.failure(.cannotDecode))
}
} else {
handler(.failure(.cannotGetData))
}
}
}

task.resume()
}
// Decoderpublic func decoder<T: Decodable>(_ decoder: JSONDecoder = JSONDecoder(), with data: Data, decodable: T.Type) throws -> T {
let decodedData = try decoder.decode(T.self, from: data)
return decodedData
}
}

In now our library is ready. I was created with public key because, we’ll add it to another project. We can build it now. And I was created NetworkError.swift and added this code

public enum NetworkError: Error {
case badURL
case cannotGetData
case networkConnectionFailed
case cannotDecode
}

Select any simulator and press Command + B.

Okay our library was ready. Then we was going to create a new project for add library into it.

Adding Library to Project

So, I created new project, firstly we need to add compiled library’s files to our new project. For this right click on the project name and click Show in Finder

Then create lib folder for all libraries with this root.

Okay and later go back MyNetwork Library again and right click on libNetwork.a file and Show in Finder

Now drag and drop libNetwork’s files inside lib folder

Later open Project and right click on it. Click to “Add files to {your project name}”

Make sure selected Create Groups and click to Add.

Okay, we added it successfully.

Next step I going to Select project target and General tab to make sure we added library.

You can see our libNetwork.a in the bottom area. Next open Build Phases and expand Link Binary with Libraries and make sure our library was added to here if you can’t see it in here click + button and add it.

So, last as a last step click to Build Settings and check All and Combined and type “search paths” in the right search side. And we must copy path from Library Search Paths and add it to Import Path in the below side.

To do that double click and copy it.

And do the same thing for this. Click + and paste it.

That’s all, we completed all of process. And in now we can import it to our project and use it.

Okay so we can use it. I’ll use this api for test my Library. So create PostNetwork.swift

And paste this codes inside PostNetwork.swift

import Foundation
import MyNetwork
struct PostModel: Decodable {
let userId: Int
let id: Int
let title: String
let body: String
}
struct PostNetwork: Request {
static let shared = PostNetwork()
var dataLoader = DataLoader() init() {
dataLoader = DataLoader()
}

var host: String = "jsonplaceholder.typicode.com"
var path: String = "/posts"
var queryItems: [URLQueryItem] = []
var method: HTTPMethod = .get
func loadPosts(completetion: @escaping () -> ()) {
dataLoader.request(self, decodable: [PostModel].self) { (result : Result<[PostModel],NetworkError>) in
switch result {
case .success(let data):
print(data)
case .failure(let e):
print(e)
}
}
}
}

Okay let’s explain above code. PostModel Struct is for our network model and it must be confirm Request protocol. I created dataLoader and use its request function and that’s all. Our network request only contains this line of codes :)

Response:

Static libraries cannot hold a resource and for that create a Bundle with our resources (we don’t created in here, because we worked only code, didn’t use xib, assets .etc)

I hope, I was able to help you.

See you next article, don’t forget smile :)

--

--