SwiftCrossPlatformFramework
                                
                                 SwiftCrossPlatformFramework copied to clipboard
                                
                                    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: [])
    ]
)

