SwiftCrossPlatformFramework
SwiftCrossPlatformFramework copied to clipboard
Tutorial to create cross platform framework for Swift compatible with Carthage and SwiftPM
Swift Cross Platform Framework

Table of contents
- Introduction
- Use XcodeTool
- Create an empty project
- Add targets
- Target iOS
- Target watchOS
- Target tvOS
- Target macOS
- Add "Sources" folder
- Rename "info.plist"
- Info.plist for iOS
- Info.plist for watchOS
- Info.plist for tvOS
- Info.plist for macOS
- Move all plist on "Sources" folder
- Update "Build Settings"
- Set the product name
- Apply Product Name for all targets
- Update packaging
- For iOS target
- For watchOS target
- For tvOS target
- For macOS target
- One header file for all targets
- Change header file
- Move header file to "Sources"
- Update project
- Add class for all platforms
- Configure targets for Carthage
- Configure project for SwiftPM
Introduction
The purpose of this tutorial is to create a Swift Cross-Platform framework from the same sources for macOS, iOS, watchOS and tvOS platforms and use them in a project via Carthage. It will be also ready for SwiftPM.
Use XcodeTool
You can follow this tutorial or just use XcodeTool and look at the section: Create a new component cross-platform
Create an empty project
- Open Xcode
- Select
Create a new Xcode project

- Select
Cross platform - Click on
Empty - Click on
Next

- Enter the project name (for this tutorial we use
Template) - Click on
Next

You should have this screen

Add targets
We must add a target for each platform
Target iOS
- On the section PROJECT click on (+)

- Select
iOS - Select
Cocoa Touch Framework - Click
Next

- Enter the project name
Template iOS(replaceTemplateby your framework name). Don't forgetiOSit's important! - Click on
Next

You should have this screen

Target watchOS
- On the section PROJECT click on (+)

- Select
watchOS - Select
Watch Framework - Click
Next

- Enter the project name
Template watchOS(replaceTemplateby your framework name). Don't forgetwatchOSit's important! - Click on
Next

You should have this screen

Target tvOS
- On the section PROJECT click on (+)

- Select
tvOS - Select
TV Framework - Click
Next

- Enter the project name
Template tvOS(replaceTemplateby your framework name). Don't forgettvOSit's important! - Click on
Next

You should have this screen

Target macOS
- On the section PROJECT click on (+)

- Select
macOS - Select
Cocoa Framework - Click
Next

- Enter the project name
Template macOS(replaceTemplateby your framework name). Don't forgetmacOSit's important! - Click on
Next

You should have this screen

Add "Sources" folder
- Rigth click on
Templateand selectAdd Files to Template - Click on
New Folder - Enter
Sourcesand click onCreateandAdd

Rename "info.plist"
Info.plist for iOS
- Open folder
Template iOS - Rename
info.plisttoinfo-iOS.plist

Info.plist for watchOS
- Open folder
Template watchOS - Rename
info.plisttoinfo-watchOS.plist

Info.plist for tvOS
- Open folder
Template tvOS - Rename
info.plisttoinfo-tvOS.plist

Info.plist for macOS
- Open folder
Template macOS - Rename
info.plisttoinfo-macOS.plist

Move all plist on "Sources" folder
Select all on the folder

And move them to the "Sources" folder

On the project remove plists

Rigth click on the Sources folder and click on Add Files to "Template"...

Select all plist and click on Add. Be careful don't check a target.

Update "Build Settings"
Set the product name
- On section
PROJECTselectTemplate - Selection section
Build Settings - In search enter
product name - For the property
Product Nameenter$(PROJECT_NAME)

Apply Product Name for all targets
- Select all targets
- Click on
Product Name - Click on key
Delete. All targets will have the product nameTemplate.

Update packaging
For iOS target
- Select
Template iOStarget - Set property
info.plist FiletoSources/info-iOS.plist - Set property
Product Bundle Identifiertocom.<your company>.$(PROJECT_NAME)

For watchOS target
- Select
Template watchOStarget - Set property
info.plist FiletoSources/info-watchOS.plist - Set property
Product Bundle Identifiertocom.<your company>.$(PROJECT_NAME)

For tvOS target
- Select
Template tvOStarget - Set property
info.plist FiletoSources/info-tvOS.plist - Set property
Product Bundle Identifiertocom.<your company>.$(PROJECT_NAME)

For macOS target
- Select
Template macOStarget - Set property
info.plist FiletoSources/info-macOS.plist - Set property
Product Bundle Identifiertocom.<your company>.$(PROJECT_NAME)

One header file for all targets
Change header file
- Select
Template iOS.h - Change
#import <UIKit/UIKit.h>by#import <Foundation/Foundation.h> - Remove
iOS

Move header file to "Sources"
- Open Finder and Rename
Template iOS.htoTemplate.h - Move
Template.hto folderSources - Remove folders
Template iOS,Template macOS,Template tvOSandTemplate watchOS



Update project
- Remove folders
Template iOS,Template macOS,Template tvOSandTemplate watchOS - Add
Template.hinSourcesfolder - Select
Template.h - In
Target MembershipcheckTemplate iOS,Template watchOS,Template tvOSandTemplate macOS - For each target select
Public



Add class for all platforms
- Click on
Sources - Click on
New File...

- Select
macOS - Select
Swift File - Click
Nextbutton

- Enter the name of your class
- Select all targets
- Click
Createbutton

Your first class cross platform:

Configure targets for Carthage
- Click on
Template iOSoptionManage Schemes... - For all targets check
Shared


Configure project for SwiftPM
- Select the project
Template - Rigth click and select
New File...

- Select
macOS - Select
Swift File - Click
Nextbutton

- Enter
Package - Uncheck all targets
- Click on
Createbutton - On the
Package.swiftenter:
// swift-tools-version:4.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "Template",
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "Template",
targets: ["Template"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "Template",
dependencies: [])
]
)

