How do I create an importable module in Swift?
Update
You can modularize a swift project using frameworks.
We modularize by creating separate framework projects for each module and link them via Xcode workspace. It looks more natural when we separate the components into different projects & it also makes sure that there is only a one-way communication between modules. Developers can work/test on isolation without thinking much about other modules.
By default classes/structs/etc created within a framework will have an internal
access control type so it is only visible within the modules. In order to make it visible outside the module, you can make it public
.
More info on access controll level here
The latest Xcode 6 beta update (beta 4) bring access control to swift
Swift Enables Access Control
Swift access control has three access levels:
- private entities can only be accessed from within the source file where they are defined.
- internal entities can be accessed anywhere within the target where they are defined.!
- public entities can be accessed from anywhere within the target and from any other context that imports the current target’s module.
How to create an importable Swift library with swiftc
I would recommend switching to the Swift Package Manager if you are only planning to make this library available on macOS or Linux. Currently, SPM only works on macOS and Linux, not on iOS/tvOS/watchOS. However, it makes library distribution much easier.
To convert your library to the Swift Package Manager, its source files need to be in this directory structure:
MyLibrary-package
├── Sources
│ └── MyLibrary
│ ├── File1.swift
│ └── File2.swift
├── Tests
│ └── MyLibraryTests
│ └── MyLibraryTests.swift
└── Package.swift
The top level folder can be called whatever you want, but the Sources
and Tests
folders should keep their names. Where I have MyLibrary
, you can put the name of your package, but it must match the name of your target in your Package.swift
. In addition, whatever you replace MyLibraryTests
with must match the name of your test target in Package.swift
.
You should put all of your source files in the MyLibrary
directory (or whatever you rename it).
Here's an example Package.swift
file that I think will match your project setup.
// swift-tools-version:4.0
import PackageDescription
let package = Package(
name: "MyLibrary",
products: [
.library(name: "MyLibrary", targets: ["MyLibrary"]),
],
targets: [
.target(name: "MyLibrary", dependencies: []),
.testTarget(name: "MyLibraryTests", dependencies: ["MyLibrary"]),
]
)
Once you have moved your source files and changed your Package.swift
, you can just run swift build
. Your library should be built somewhere in the .build
folder (which will be created). It varies by computer, but mine is .build/x86_64-apple-macosx10.10/debug/MyLibrary.build/
.
If you want specifically a static library, change this line:
.library(name: "MyLibrary", targets: ["MyLibrary"]),
to this:
.library(name: "MyLibrary", type: .static, targets: ["MyLibrary"]),
Create and import swift framework
I've done with the following steps.
- Create a framework project, for example named "FooKit". (
Cocoa Touch Framework
to be selected) - Create a ".swift" file and add a public symbol, for example
public func foo()
, to it. - Create an use-side (app) project. (I've chosen
Single View Application
) - Open the root directory of "FooKit" by Finder, drag "FooKit.xcodeproj" there and drop it into the app project via
Project Navigator
. - Add "FooKit" to
Target Dependencies
in the app'sBuild Phases
setting. - Add "FooKit.framework" to
Embedded Binaries
in the app'sGeneral
setting.
Now you can build like this code in the use-side app.
import FooKit
func bar() {
foo()
}
Import my custom module/framework Xcode Swift
Drag your module's x-code project into the left pane with all the files.
Then click on your main project file and go to general, scroll down to Embedded Binaries and add it through the menu there.
How to import module into xcode
When you clone or or download the socket io project you get a directory with multiple subdirectories. One of the subdirectories is named Source
. Simply drag that folder into Xcode (into the Project Navigator in the left sidebar).
You will then be presented with a screen like this:
Make sure the box for your app is ticked in the "Add to targets" list. This is what the instructions mean by "Make sure you add the files to your target(s)"
Related Topics
Can You Override Between Extensions in Swift or Not? (Compiler Seems Confused!)
Swift Spritekit Adding Button Programmatically
Why Use Required Initializers in Swift Classes
Find Difference in Seconds Between Nsdates as Integer Using Swift
Use Reserved Keyword a Enum Case
Ios11 Swift Silent Push (Background Fetch, Didreceiveremotenotification) Is Not Working Anymore
Convert Swift Array to Dictionary With Indexes
What Is the Real Benefit of Using Raycast in Arkit and Realitykit
Default Value For Optional Generic Parameter in Swift Function
In Swift 3, How to Calculate the Factorial When the Result Becomes Too High
Swift3 Optionals Chaining in If Conditions Bug
Projecting the Arkit Face Tracking 3D Mesh to 2D Image Coordinates
Swiftui Hierarchical Picker With Dynamic Data Crashes
Linker Command Failed with Exit Code 1 After Installing Cocoapods and Firebase Pod
Swift: 'Hashable.Hashvalue' Is Deprecated as a Protocol Requirement;
How to Reason When I Have to Choose Between a Class, Struct and Enum in Swift