Open Source

Yet Another Covid-19 App

In the past few weeks I’ve had a lot free time, and thought to myself why not another Covid-19 app? Only for Canada. You can get it from here

I tried to practice having a clean, readable and modular code. I hope I achieved these goals. Three external libraries are used in the app. CSV to decode CSV data, Charts and MBProgressHUB to show an activity indicator (I really could avoid this one and use the native one).

Data which feeds the app comes from website. The main challenge here was the input data were not consistent. From the URL to data structure. I fix the first problem I added a helper function to retrieve the file URL from an alternative when the primary function fails to fetch the file, you can getAlternativeAddress() from DeliveryManager class. To overcome to the data structure inconsistency I declared most of the columns as optional string and through two failable initializers converted them to Int and Double.

Another thing I practiced was using custom UIViews, it is a good way to modularize the code and avoid having fat view controllers.

KeyPath was another thing I used here. I guess most of us don’t care to use them, but they are really cool. Imagine you have a structure which consists of several Int type and you want to manipulate some of the numbers and show different output for different purpose. In my case I wanted to feed the chart with two different set of data, one for confirmed cases and one for number of deaths. I could create two almost identical functions to generate required data or one generic function which knew what element of the structure should be used. KeyPath was the silver bullet here:

func setChartData(data: [CSVDecodable], keyPath: KeyPath<CSVDecodable, Int>){}

Now I can call it like setChartData(data: data, keyPath: \.confirmed) or setChartData(data: data, keyPath: \.deaths) and it knows how to generate the data set.

You can download the project from

Snap to edge for UIView

For Tahrir I wanted to add a new feature in the new major update. I thought implementing a snap to edge might help users to align texts with each other, on small screen and with fingers it would be difficult without it.

The general idea is storing edges (frame.origin) of all existing views in an array, then calculate the distance of current view’s edges, which the user is moving, and if it’s smaller than a threshold you activate the snap.

The snap works, as you surely have noticed in apps like Instagram, like this: when the view gets near an edge it grips the edge until you push it further to release the grip and move freely again. Sounds simple, right?

I post pieces of the code here and you can get the rest from github.

var squareItems = [Int: CGPoint]()

This variable keeps record of the edges of the existing views. The key is hash value of the view, which is unique. We update it every time a new view is added or when the user is done with moving the view.

Let’s calculate the distances:

for item in squareItems { if item.key != senderView.hash { let leftDistance = abs(senderView.frame.origin.x + translation.x - item.value.x) if leftDistance < 5 { snapOnLeftEdge = true shouldSnap = true horizontalDifference = senderView.frame.origin.x + translation.x - item.value.x } let topDistance = abs(senderView.frame.origin.y + translation.y - item.value.y) if topDistance < 5 { snapOnTopEdge = true shouldSnap = true verticalDiffecence = senderView.frame.origin.y + translation.y - item.value.y } } }

leftDistance and topDistance do the trick, the griping part.

And here it applies the trick, shows a line on the screen and actives the haptic, lightly.

if snapOnLeftEdge { var _frame = senderView.frame _frame.origin.x = _frame.origin.x + translation.x - horizontalDifference _frame.origin.y = _frame.origin.y + translation.y senderView.frame = _frame if feedbackIsAllowed { feedbackIsAllowed = false let generator = UIImpactFeedbackGenerator(style: .light) generator.impactOccurred() if let _rulersGuid = setupRulerGuidesView(.horizontal(_frame.origin.x)) { self.view.addSubview(_rulersGuid) _rulersGuid.layer.zPosition = 2 } } } else if snapOnTopEdge { var _frame = senderView.frame _frame.origin.x = _frame.origin.x + translation.x _frame.origin.y = _frame.origin.y + translation.y - verticalDiffecence senderView.frame = _frame if feedbackIsAllowed { feedbackIsAllowed = false let generator = UIImpactFeedbackGenerator(style: .light) generator.impactOccurred() if let _rulersGuid = setupRulerGuidesView(.vertical(_frame.origin.y)) { self.view.addSubview(_rulersGuid) _rulersGuid.layer.zPosition = 2 } } }

I think you have grasped the idea about how snap works, you can download the whole code, as an app, from the github repo. 

Fibonacci Sequence with Swift

The aim of this post is showing how to conform to Sequence protocol and create a custom sequence. To make it less boring, we can create a new type and call it FibonacciSequence which gets nth desired number then iterate over values.

The requirement to conform to Sequence protocol is fairly simple, you need to provide a makeIterator() method that returns an iterator. The code should look like this:

struct FibsSequence: Sequence {
    private var upTo: Int
    init(upTo: Int) {
        self.upTo = upTo
    func makeIterator() -> FibsIterator {
        return FibsIterator(upTo: upTo)

Our makeIterator() returns another custom type which conforms to IteratorProtocol. This type obliges the conformer to provide a method to supply the values of the sequence one at a time. The only method should be implemented is next() which advances to the next element and returns it, or returns nil if no next element exists:

struct FibsIterator: IteratorProtocol {
    private var state:(UInt, UInt) = (0, 1)
    private var upTo: Int
    private var counter = 0
    init(upTo: Int) {
        self.upTo = upTo
    mutating func next() -> UInt? {
        guard upTo > counter else {return nil}
        guard upTo > 0 else {return nil}
        let upcomingNumber = state.0
        state = (state.1, state.0 + state.1)
        counter += 1
        return upcomingNumber

In this type we have three private variables, which are clearly named, and a mutating function. Being mutating is not strictly necessary in general but since we want to keep track of iterator and update it, it is required here. The next() function returns optional UInt, optional because at some point we want to exit the function unless we deliberately want to make the code crash!

There are two exit points in the function, first one checks against nth element, if it is bigger than what user initially asked, it quits. The other one is to makes sure the nth element is a positive one.

Now we have a custom type which returns Fibonacci sequence up to a certain index in the series, indicated during initialization.

for (index, fib) in FibsSequence(upTo: 15).enumerated() {
    print("fib: \(fib), index: \(index + 1)")

fib: 0, index: 1
fib: 1, index: 2
fib: 1, index: 3
fib: 2, index: 4
fib: 3, index: 5
fib: 5, index: 6
fib: 8, index: 7
fib: 13, index: 8
fib: 21, index: 9
fib: 34, index: 10
fib: 55, index: 11
fib: 89, index: 12
fib: 144, index: 13
fib: 233, index: 14
fib: 377, index: 15

Whole code is available on github.


After posting this on reddit a user, Nobody_1707, suggested a shorter version of the code which is:

public struct FibSequence: Sequence, IteratorProtocol {
    private var state: (UInt, UInt) = (0, 1)
    public init() { }
    public mutating func next() -> UInt? {
        guard state.1 >= state.0 else { return nil }
        defer { state = (state.1, state.0 &+ state.1) }
        return state.0

for (i, fib) in zip(0..., FibSequence().prefix(15)) {
    print("fib(\(i)) = \(fib)")

Swift: An app to search through movie titles using The Open Movie Database API

This demo app uses OMDb APIs to search in movie titles and show details of the selected movie. First of all, you need to get your API key, it’s free. All right, this is the plan:

  • Create a class to make network requests using URLSession
  • Test the class
  • Create the UI

NetworService will handle the network requests. This is a singleton class which uses the builtin URLSession with a handful of configuration options. An extension to this class contains the required methods to search. Since I have created this as a reusable utility class, there are some extra features which won’t be used in this tutorial, maybe you need them later.

class NetworkService {
    //MARK: - Internal structs
    private struct authParameters {
        struct Keys {
            static let accept = "Accept"
            static let apiKey = "apikey"
        static let apiKey = "YOURKEY"
    //An NSCach object to cache images, if necessary
    private let cache = NSCache()
    //Default session configuration
    private let urlSessionConfig = URLSessionConfiguration.default
    //Additional headers such as authentication token, go here
    private func configSession(){
        self.urlSessionConfig.httpAdditionalHeaders = [
            AnyHashable(authParameters.Keys.accept): MIMETypes.json.rawValue
    private static var sharedInstance: NetworkService = {
        return NetworkService()
    //MARK: - Public APIs
    class func shared() -> NetworkService {
        return sharedInstance

    //MARK: - Private APIs
    private func createAuthParameters(with parameters:[String:String]) -> Data? {
        guard parameters.count > 0 else {return nil}
        return {"\($0.key)=\($0.value)"}.joined(separator: "&").data(using: .utf8)

This is the skeleton of our class, shared() function returns a static instance of the class after running the internal configSession() function. authParameters structure is used to store keys and values for authentication, just to prevent writing a messy code. Now we can create an instance of the class using, let networkService = NetworkService.shared().

Now the we need another public method to make network requests:

    private func request(url:String,
                 cachePolicy: URLRequest.CachePolicy = .reloadRevalidatingCacheData,
                 httpMethod: RequestType,
                 body: [String:String]?,
                 parameters: [URLQueryItem]?,
                 useSharedSession: Bool = false,
                 handler: @escaping (Data?, URLResponse?, Int?, Error?) -> Void){
        if var urlComponent = URLComponents(string: url) {
            urlComponent.queryItems = parameters
            var session = URLSession(configuration: urlSessionConfig)
            if useSharedSession {
                session = URLSession.shared
            if let _url = urlComponent.url {
                var request = URLRequest(url: _url)
                request.cachePolicy = cachePolicy
                request.allHTTPHeaderFields = headers
                if let _body = body {
                    request.httpBody = createAuthParameters(with: _body)
                request.httpMethod = httpMethod.rawValue
                session.dataTask(with: request) { (data, response, error) in
                    let httpResponsStatusCode = (response as? HTTPURLResponse)?.statusCode
                    handler(data, response, httpResponsStatusCode, error)
                handler(nil, nil, nil, Failure.invalidURL)
            handler(nil, nil, nil, Failure.invalidURL)

This method has the basic functionality of a request session, getting parameters and headers and returning response, data, status code and an error object if exists, asynchronously. For the httpPart, you can replace createAuthParameters(:_) with an array of URLQueryItems.

For errors, I’m using a enumerator which is inherited from Error protocol, here is it:

import Foundation
public enum Failure:Error {
    case invalidURL
    case invalidSearchParameters
    case invalidResults(String)
    case invalidStatusCode(Int?)

extension Failure: LocalizedError {
    public var errorDescription: String? {
        switch self {
        case .invalidURL:
            return NSLocalizedString("The requested URL is invalid.", comment: "")
        case .invalidSearchParameters:
            return NSLocalizedString("The URL parameters is invalid.", comment: "")
        case .invalidResults(let message):
            return NSLocalizedString(message, comment: "")
        case .invalidStatusCode(let message):
            return NSLocalizedString("Invalid HTTP status code:\(message ?? -1)", comment: "")

OMDb works with simple queries, it doesn’t have many end points! but to keep everything structured, let’s create another enumerator:

import Foundation

enum EndPoints {
    case Search

extension EndPoints {
    var path:String {
        let baseURL = ""
        struct Section {
            static let search = "/?"
        switch(self) {
        case .Search:
            return "\(baseURL)\("


The next step is testing:

import XCTest
@testable import OpenMovie

class OpenMovieTests: XCTestCase {
    private let networkService = NetworkService.shared()
    func testSearch() {
        let promise = expectation(description: "Search for batman movies") "batman", page: 1) { (searchObject, error) in
            XCTAssertTrue(searchObject?.response == "True")
        waitForExpectations(timeout: 2, handler: nil)
    func testSearchByIMDBID() {
        let promise = expectation(description: "Search for Batman: Dark Night Returns")
        networkService.getMovie(with: "tt2313197") { (movieObject, error) in
            XCTAssertTrue(movieObject?.imdbID == "tt2313197")
        waitForExpectations(timeout: 2, handler: nil)

And the results:

Now the last step, isn’t it better you look at it yourself? It’s TL;DR sort of thing, download it from github and give it a try.

This is how it looks:

iOS: Show activity indicator in UISearchBar

Updated for iOS 13 and Swift 5

When you are using a search controller, most probably it’s a network call. Isn’t it nice to show a tiny loading animation instead of the magnifier icon on the left side of the search while your app is still waiting for data from the internet? Indeed.

To do this, you can use either use private API, which is frowned upon, or use UITextField‘s built-in methodsetImage(), I go for the latter one.

First of all, let’s see how it looks:

To show the loading animation we have to:

  1. find the search bar within the search controller
  2. remove the magnifier icon
  3. add an UIActivityIndicatorView to the search bar’s leftView

And to hide it it’s almost the same steps but in reverse.

To make the code reusable, let’s do it as an extension:

import Foundation
import UIKit

extension UISearchBar {

First of all, we need to find the text field which is basically a UITextField within UISearchBar subviews. this computed property does the job for us and returns an option UItextField:

private var textField: UITextField? {
    let subViews = self.subviews.flatMap { $0.subviews }
    if #available(iOS 13, *) {
        if let _subViews = subViews.last?.subviews {
            return (_subViews.filter { $0 is UITextField }).first as? UITextField
            return nil
    } else {
        return (subViews.filter { $0 is UITextField }).first as? UITextField

The next step is finding the current magnifier image, it’s similar to the previous step:

    private var searchIcon: UIImage? {
        let subViews = subviews.flatMap { $0.subviews }
        return  ((subViews.filter { $0 is UIImageView }).first as? UIImageView)?.image

Let’s get hold of our loading animation, which is an UIActivityIndicatorView:

   private var activityIndicator: UIActivityIndicatorView? {
        return textField?.leftView?.subviews.compactMap{ $0 as? UIActivityIndicatorView }.first

Now let’s add a public variable to show/hide the loading animation:

    var isLoading: Bool {
        get {
            return activityIndicator != nil
        } set {
            let _searchIcon = searchIcon
            if newValue {
                if activityIndicator == nil {
                    let _activityIndicator = UIActivityIndicatorView(style: .gray)
                    _activityIndicator.backgroundColor = UIColor.clear
                    let clearImage = UIImage().imageWithPixelSize(size: CGSize.init(width: 14, height: 14)) ?? UIImage()
                    self.setImage(clearImage, for: .search, state: .normal)
                    textField?.leftViewMode = .always
                    let leftViewSize = CGSize.init(width: 14.0, height: 14.0)
           = CGPoint(x: leftViewSize.width/2, y: leftViewSize.height/2)
            } else {
                self.setImage(_searchIcon, for: .search, state: .normal)

This piece of code looks for an existing activity indicator and if there is none, first creates one, cleans the default image for seach mode, the magnifier image, sets a new transparent image with 14 point in 14 point in size then adds the recently created UIActivityIndicatorView to left search bar’s leftView; And to hide it, smiple removes the  UIActivityIndicatorView and set back the image for search mode.

To use it simple set searchController.searchBar.isLoading = true  but be careful if you are using it inside another block, call it withing the main queue.

You can download the whole code from github. The UIImage extension, imageWithPixelSize(), is also available on github