Sitemap

Swiftify

Swiftify.com

Press enter or click to view image in full size

Converting SVProgressHUD to Swift Using Swiftify

5 min readNov 27, 2018

--

Swift is loved by developers and is the future of development in the Apple Ecosystem. More so now, as we find out in our study, that 90% of the top 100 non-game applications by revenue apps on the App Store use Swift in their main binary.

Swift is faster, readable, natural, and fun, like a scripting language.
Objective-C is very powerful, and many third-party frameworks and Apple Frameworks are written in Objective-C.

SVProgressHUD is a very popular library widely used by developers. It is elegant in its simplicity to use and clean, minimalistic design.

Swiftify for Xcode is a potent tool. It converted the entire project instantaneously, but fixing the issues with conversions and debugging was tricky as I did not understand the original code very well initially.

If you are converting code not written by you or code that you do not have a deep understanding of, I would strongly recommend migrating one class at a time, testing with the existing code, and then repeating the process, as fixing the issues with conversion and debugging the entire project later would be very difficult. It is always better to divide and conquer.

This flowchart can summarise my overall approach:

Press enter or click to view image in full size

Looking at the code structure in SVProgressHUD, the order in which I converted the files is as follows:-

The first class I converted was SVRadialGradientLayer. This class is used for adding the gradient mask type and is called from only one place. The conversion is simple and happens in a snap. A single fix is needed, and it can be done with just a simple Google Search. After this, I replaced this Objective-C class from the target with the new Swift file and ran the project. The project compiled and ran as expected, so I moved on to the next file.

The next class to be converted was SVProgressIndefiniteAnimatedView. This class is used for showing an indefinite animated view of two types which are native design and flat design. In native design, the ProgressHud shows this animated view, and in flat design, it shows the UIActivityIndicatorView. I converted the code to Swift, made the properties private, and added functions for setting and getting the properties.

As you may have noticed, the setter functions declaration in the code above has the @objc keyword as the functions are being called from SVProgressHUD.m, a class that hasn’t been converted till now.

You may also add the objcMembers attribute to your class instead.

Later I added properties to show and hide the activity indicator as in Objective-C implementation this class SVProgressIndefiniteAnimatedView was being cast to UIActivityIndicatorView. So I added the code to show and hide the ActivityIndicator into the class as in the extension below:

While working on this class, I also opened up the SVProgressHUD.bundle, extracted the files, and added the images to the IHProgressHUD.bundle

Image Assets Used in the Project

Next, I started with SVProgressAnimatedView class which is responsible for showing the HUD with a progress indicator ring. It supports only flat style and does not support UIActivityIndicatorView.

Now comes the project's main class(SVProgressHUD), which coordinates with the outside code. This class is voluminous and complex. I used the earlier techniques, such as using setters and getters functions and placing all the class functions in a different class extension. This class uses a single instance of itself, i.e., it is a self-contained Singleton class. All the class functions eventually use this Single Instance.

I also cleaned up the deprecated functions after the completion. I started with the class functions and converted them all in one go. Then came the bigger instance methods, which are the meat of the library. Slowly the file got converted by looking up the source code in the assistant editor and using Swiftify’s Xcode Extension. The code conversion took some time, and there were a few issues for which I ran the project with the original SVProgressHUD file and the Swift version file and debugged it by looking at the value difference at runtime.

That is why I do not delete the original Objective-C file in the flowchart above until the code conversion is complete and the Swift Code is tested.

Now, if we want, we can maintain compatibility with Objective-C by not removing the @objc prefix and adding the @objc prefix to the functions and properties that act as an interface for our code.

After testing, I removed the @objc from functions, and self, enhanced the library to make it thread-safe. You can now use the library from any thread. The Single Instance is always created and assessed from the main thread.

Code for using IHProgressHUD from any thread

If you used SVProgressHUD in the past you had to set the SV_APP_EXTENSIONS flag manually to determine if the framework is running in an App Extension. Now it is not handled inside the code and the end user does not have to set it for the AppExtension target.

Swiftify has been a great help; without it, the process would have been cumbersome and unimaginable. The conversions are reliable and accurate and do most of the work for you. The desktop app is easy to use. I only used the Swiftify web app to convert small Objective-C code snippets from StackOverflow to Swift. Now, I just converted SVProgressHUD to Swift using their desktop application.

You can check out the converted project here.

Conclusion

The major takeaway for developers converting Objective-C code to Swift would be to start with the less complex parts and convert them to Swift while maintaining compatibility with the remaining Objective-C code and repeating the process over and over again until the project is fully converted to Swift.

Swiftify may not be perfect, but it saves time and is reliable. I would recommend Swiftify for developers who are migrating Objective-C code to Swift.

You can connect with us on Twitter, LinkedIn, Facebook, and GitHub.

--

--

No responses yet