Cross Platform iOS/macOS

 

I want to construct a Framework in Swift that I can use for both iOS and macOS applications.

Here is how I do it.

A) Creating the components

First, I create a workspace.  This is so that I can demonstrate using the same framework with both a macOS and iOS application.  The workspace will have three  targets — the afore-mentionned macOS and iOS applications, as well as the cross-platform framework that we are constructing.

So, the first few steps are:

  1. Launch XCode
  2. File > New > Workspace…
  3. File > New > Project… ( pick a macOS Cocoa Framework )
    Framework
  4. File > New > Project… ( pick a macOS Cocoa Application )
    CocoaApp
  5. File > New > Project… ( pick an iOS Single View App )
    IosApp
  6. Close the three project windows.
  7. Add the three projects to the workspace.

WorkspaceCorner

 

And now we have a workspace containing our soon-to-be-cross-platform framework and the two apps we will use to test to make sure it is working.

B) Making the Framework Cross-Platform

For the next series of steps, which are to make the framework be cross platform, make sure that the target selection dropdown (shown in the previous image) is set to Framework > My Mac

First, we plan to embed the framework in whatever app uses it, so we disable code signing for the framework.  After embedding in the app, the entire app will be signed, which will include the framework.  

NoTeam

To make the framework cross-platform, we need to modify two build settings.  First, we modify “Supported Platforms” to include both iOS (iphoneos) and macOS.  In addition, we’ll add “iphonesimulator” — that seems to be a separate platform, but required in order to use the simulator for testing.  One cannot type into the value field for “Supported Platforms” — we need to select Other from the drop down menu and then add a line for each value.

SupportedPlatforms

Immediately under “Supported Platforms” is “Valid Architectures”.  Once again, we extend the choices to include the iphone ARM architectures in addition to the mac Intel architectures.  The valid architectures should be: arm64 armv7 armv7s i386 x86_64

ValidArchitectures

 

C) Make sure it works

We now have a cross-platform framework.  To see that it works, we can add it to the two other projects.  To add it to the Cooca App, select it from the target drop-down in the toolbar, and also select the Cocoa application project.   Under Build Phases, add the cross platform framework to both the Link Binary With Libraries section and the Copy Bundle Resources section.   Then build the app.

EmbedCocoa

 

Do the same with the iOS application.

We have now built an iOS app and a macOS application both with the same framework.   Generic Swift code can now be added to the framework and be shared across both platforms.

For code which is specific to one platform or the other, one could choose to have platform specific frameworks, or — where the differences are minor, one can use conditional compilation to segregate the platform specific code.


#if os(iOS) 

// iOS code here

#elseif os(macOS)

// macOS code here

#endif


Now I can share code across platforms.  This technique might also work for tvOS and watchOS, but I haven’t tried it.