Compare your Objective-C and Swift code through time with Swoop

At Songkick, we’re busy converting our iOS app Objective-C codebase to Swift, and we built a tool called Swoop to help us track our progress.

We started to use Swift for our iOS app since November last year. That means new features and new tests are written in Swift. But how about our existing Objective-C code? We approached the conversion from Objective-C to Swift carefully. We have a small team and wanted to keep shipping new features, so we could not afford the risk of having major code changes. Instead, we started with smaller changes to the most problematic Objective-C code.

Our models and networking code were the first two areas that we actively convert into Swift, mainly because we use an old and unsupported network library. Early 2016, we pushed quite hard on these conversions and progressed excellently.

At that time, I was curious to understand the velocity of our progress. Maybe seeing it as a graph would be cool. This idea was then realized into a Ruby gem I named, Swoop.

Swift and Objective-C comparison reporter

Swoop compares and reports your Swift and Objective-C code through time. It goes through your git history, reads your Xcode project, compares them, and presents the information in a digestible representation.

To use Swoop, just install the gem using `’gem install swoop_report’`, and use the command with 2 required parameters :

  • Path to your Xcode project, and
  • Directory of your interest (the directory inside Xcode project)

Call the swoop command from your terminal like so :

`$ swoop –path ~/your_project/project.xcodeproj –dir Classes`

By default, it will present you a table of the last eight tags of your project, similar to the table below.

How it works

The diagram below explains how Swoop’s main classes work together.

sw_diagram

  1. It creates a `Project` using the path parameter.
  2. `TimeMachine` uses the project, and then figures out which git commits should be used based on the options provided.
  3. Once `TimeMachine` got the list of commits, it checkouts each one and starts the comparison process, which is broken down into :
    1. Selects the files that are inside the specified directory.
    2. `EntityParser` parses filtered Swift or Objective-C files and counts its classes, structs and extensions.
    3. Collates file information into a `Report`.
  4. All of the `Report`s are rendered by a chosen subclass of `Renderer`.

Below is the snippet of the Swoop’s main program :

# 1) create project with path
project = Project.new(@project_path, @dir_path)

# 2) create time machine with project and options
delorean = TimeMachine.new(project, @time_machine_options)

# 3) time machine checkouts for each commit
reports = []
delorean.travel do |proj, name, date|
  # 3.a) filter interested files
  files = proj.filepaths
  
  # 3.b) parse information from files
  entities = EntityParser.parse_files(files)
  
  # 3.c) put information in a report
  reports << Report.new(entities, name, date)
end

# 4) render array of reports as a table
renderer = TableRenderer.new(reports, "Swoop Report : '#{@dir_path}'")
renderer.render

Result

This is what our iOS app’s comparison report looks like :

sw_chart

Until now, our Swift code constitute roughly 35% of our whole codebase. From the graph, we can see that the number was vastly improved because of the work done around February until March. At that time, we were actively converting code to Swift. Then, the past three months it stagnated a bit because we changed our team goals and changed our focus to other projects.

After it worked for our iOS app, I ran Swoop on two other open source projects: Artsy’s eigen and WordPress’ iOS app.

Artsy’s Eigen

Last 8 minor versions of eigen :
`$ swoop –path eigen/Artsy.xcodeproj –dir Artsy –filter_tag ‘\d\.\d\.\d(-0)?$’ –render chart`

sw_artsy

WordPress for iOS

Last 12 major version of WordPress for iOS :
`$ swoop –path WordPress-iOS/WordPress/WordPress.xcodeproj –dir Classes –tags 12 –filter_tag ‘^\d.\d+$’ –render chart`

sw_wordpress

All in all, it works pretty well for our app and we plan to incorporate this into our continuous integration pipeline.

Onwards

We will need to test Swoop using more Xcode projects because sometimes it fails to do the job for projects that have directory changes in their git history. Also, we will aim for 100% coverage in the near future.

Any form of contributions are welcomed! Let us know if it doesn’t work for your project (it’ll be better if the project is publicly accessible). For more information on how to use and improve Swoop, please visit : https://github.com/ikhsan/swoop.

Posted in iOS