Porting iOS app to macOS

Harry Ng
macOS App Development
3 min readJul 19, 2016

I have been doing this for a while, in order to port our productivity app to macOS environment. This is currently the biggest ask from our users. So I have been learning, building and sharing how I build macOS apps.

When I look at the iOS counterparts, I first identified the code base that is sharable between the two platforms, and here is the list.

  • Models
  • Managers
  • Helpers
  • Extensions

In our case, we also use Advanced NSOperations to wrap the CloudKit code for data synchronisation. So I have a set of Operations code as well.

Throughout the process, I have several takeaways.

#1 Build Private Library

I use CocoaPods in both apps, thus I am going to build a shared private pod for both environments.

When we started the iOS app, it was not intended to share the code base to macOS applications. Thus, the logic is kind of coupled together. I shall first move the easy parts, which are the standalone managers and helpers. They should pretty much compilable in the shared project.

As we have been experiencing slow app launch problem due to loading too many dynamic frameworks, I am going to just use one private pod to share the code. In addition, I will want to include other 3rd party libraries using static frameworks.

#2 Using macro to identify iOS and macOS

iOS and macOS use different UI component frameworks, UIKit and AppKit (Cocoa) respectively. In some helpers, they are simply importing different frameworks and share most of the code. I will use macro in such case to run based on operating system. For instance, it looks like:

#3 Separating into platform specific source files

The next step is to port the models. In some value structures, like a class called HNColor, it’s defining the colours to be used in the app. In iOS, they are returning UIImage. However, macOS uses NSImage. In this one, as the whole file is consisted of UIImage/NSImage. It is not effective to use macro like previous setup. I’d rather make two separate files. I will only include the corresponding file based on the choice of framework. As I am setting up the framework using CocoaPods, I shall define it in the podspec file.

If you use Carthage instead, then you should add the different source files based on the target.

Conclusion

Porting to another platform is a big deal. I am doing this in Swift, so the main different is on the use of system framework. I would suggest to start porting the code only if it is getting stable in one platform.

In our case, the iOS version is pretty much done. We make sure the app is well tested and relatively stable. Also, we have plan to switching the iOS app to use the shared code base. In the meantime, if we make changes to iOS code base, it will mean that we need to update the code base twice.

--

--