Rss

Follow-up: How to Build an Xcode Project that Builds for Both iOS and macOS

Since I talked about making multi-platform projects like it was no big deal in my blog yesterday, I figured I should at least back that up.

macandiosbuilddemo (GitHub link) is an Xcode project that builds an iOS master-detail app and a macOS windowed app from the same code base. It’s fairly trivial and unpolished, just fetching a JSON feed from this blog, showing recent entries in a table, and letting you drill into one.

Side by side iOS and macOS apps, built from the same Xcode project

The types to represent blog entries and a feed, as well as the JSON stuff, are the business logic of the app, and they are in a “common” group. These files are 100% compatible between macOS and iOS, being based on the Foundation framework and the Swift Standard Library.

The trick is just to use the “target membership” checkboxes in the File Inspector to have them build for both platforms (in this example, I put all supporting files in frameworks, so they build as part of either an iOS private framework or macOS private framework). You could also add them with the plus button in the Build Phases tab of each target’s settings.

There’s also a view model class that represents the blogs to be shown, which has a delegate it can call out to when the contents update. This is trivial, and barely an example of MVVM, but it allows me to keep even the view models cross-platform — all that the platform-specific view controllers need to do is to implement the delegate method and update themselves. In practice, this actually ended up being identical between platforms as well:


extension MasterViewController: BlogFeedPresenting {
  func blogFeedViewModelDidUpdate(_ model: BlogFeedViewModel) {
    DispatchQueue.main.async {
      self.tableView.reloadData()
    }
  }
}

I also made a quick one-off video walking through the project:

Finally, I don’t want to make this sound like news. It’s really not. It’s just using Xcode targets as they were meant to be used, something that just seems to have been overlooked a lot.

Anyways, there’s also an example of this coming in what should be the next update to Xcode Treasures, but that example is about adding tvOS to an iOS project, and I wanted to get a Mac example out there too. This took about three hours to write, evenly split between business logic, iOS UI, and macOS UI.

Anyways, point being: this is totally doable. No, it’s not just a checkbox, because it assumes you would want some level of control over what your Mac UI looks like and how it works. Y’know, like you care what you’re doing, and how your users experience your app.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.