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
(replaceTemplate
by your framework name). Don't forgetiOS
it'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
(replaceTemplate
by your framework name). Don't forgetwatchOS
it'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
(replaceTemplate
by your framework name). Don't forgettvOS
it'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
(replaceTemplate
by your framework name). Don't forgetmacOS
it's important! - Click on
Next
You should have this screen
Add "Sources" folder
- Rigth click on
Template
and selectAdd Files to Template
- Click on
New Folder
- Enter
Sources
and click onCreate
andAdd
Rename "info.plist"
Info.plist for iOS
- Open folder
Template iOS
- Rename
info.plist
toinfo-iOS.plist
Info.plist for watchOS
- Open folder
Template watchOS
- Rename
info.plist
toinfo-watchOS.plist
Info.plist for tvOS
- Open folder
Template tvOS
- Rename
info.plist
toinfo-tvOS.plist
Info.plist for macOS
- Open folder
Template macOS
- Rename
info.plist
toinfo-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
PROJECT
selectTemplate
- Selection section
Build Settings
- In search enter
product name
- For the property
Product Name
enter$(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 iOS
target - Set property
info.plist File
toSources/info-iOS.plist
- Set property
Product Bundle Identifier
tocom.<your company>.$(PROJECT_NAME)
For watchOS target
- Select
Template watchOS
target - Set property
info.plist File
toSources/info-watchOS.plist
- Set property
Product Bundle Identifier
tocom.<your company>.$(PROJECT_NAME)
For tvOS target
- Select
Template tvOS
target - Set property
info.plist File
toSources/info-tvOS.plist
- Set property
Product Bundle Identifier
tocom.<your company>.$(PROJECT_NAME)
For macOS target
- Select
Template macOS
target - Set property
info.plist File
toSources/info-macOS.plist
- Set property
Product Bundle Identifier
tocom.<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.h
toTemplate.h
- Move
Template.h
to folderSources
- Remove folders
Template iOS
,Template macOS
,Template tvOS
andTemplate watchOS
Update project
- Remove folders
Template iOS
,Template macOS
,Template tvOS
andTemplate watchOS
- Add
Template.h
inSources
folder - Select
Template.h
- In
Target Membership
checkTemplate iOS
,Template watchOS
,Template tvOS
andTemplate macOS
- For each target select
Public
Add class for all platforms
- Click on
Sources
- Click on
New File...
- Select
macOS
- Select
Swift File
- Click
Next
button
- Enter the name of your class
- Select all targets
- Click
Create
button
Your first class cross platform:
Configure targets for Carthage
- Click on
Template iOS
optionManage 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
Next
button
- Enter
Package
- Uncheck all targets
- Click on
Create
button - On the
Package.swift
enter:
// 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: [])
]
)