SwiftSMB is a Swift Package Manager library for talking to SMB2 and SMB3 file shares from Swift. It wraps the proven libsmb2 client library in a Swift-first API with typed configuration, friendly path handling, file and directory handles, share discovery, metadata operations, and convenience helpers for common upload and download workflows.
Use it when your app or service needs to browse Windows, Samba, NAS, or other SMB-compatible shares without shelling out to system tools.
The examples below list shares and transfer local files through an SMB share:
import Foundation
import SwiftSMB
let server = SMB.Server(host: "RASPBERRYPI.local") // IP or hostname
let credentials = SMB.Credentials(user: "Anna", password: "1987")listShares(server:credentials:...) connects to the server, asks it for its disk shares, and disconnects before returning:
let shares = try SMB.listShares(
server: server,
credentials: credentials
)
for share in shares {
print(share.name)
}By default, hidden shares are filtered out. Pass includeHidden: true if you need to inspect them too.
Use one of the returned share names to open a connection:
let connection = try SMB.connect(
server: server,
credentials: credentials,
share: "Documents"
)
defer { try? connection.disconnect() }listDirectory(at:) returns an array with the entries in a directory:
let entries = try connection.listDirectory(at: "Anna/Inbox")In this library, just like libsmb2 uses forward slash for separating directories. You don't need to add "/" to indicate the root of the file share.
uploadFile(local:remote:...) copies a local file to the connected share. It can create missing parent directories and, by default, stages the upload through a temporary remote file before renaming it into place:
let localURL = URL(fileURLWithPath: "/Users/Anna/Desktop/report.pdf")
try connection.uploadFile(
local: localURL,
remote: "Anna/Inbox/report.pdf"
) { completed, total, lastBlockSpeed, averageSpeedSinceTheStartOfTheTransfer in
let speed = 0.5 * lastBlockSpeed + 0.5 * averageSpeedSinceTheStartOfTheTransfer
print("Uploaded \(completed) of \(total) bytes at \(round(speed/1000.0)) kB/s")
return true
}Return false from the progress closure to cancel the upload.
downloadFile(remote:local:...) copies a file from the connected share to local storage. The download is written to a temporary local file first and then moved into place after the transfer succeeds:
let localURL = URL(fileURLWithPath: "/Users/alice/Downloads/report.pdf")
try connection.downloadFile(
remote: "Anna/Inbox/report.pdf",
local: localURL
) { completed, total, latestSpeed, averageSpeed in
print("Downloaded \(completed) of \(total) bytes")
return true
}Return false from the progress closure to cancel the download.
Longer examples belong in docs/:
- File Management
- Using convenience methods for uploads/downloads
- Working with file handles and directory handles
- Changing properties of files
- Watching file system changes
Add SwiftSMB to your package dependencies:
dependencies: [
.package(url: "https://github.com/RuiNelson/SwiftSMB.git", from: "1.0.0"),
]Then add SwiftSMB to the target that uses it:
.target(
name: "YourTarget",
dependencies: [
.product(name: "SwiftSMB", package: "SwiftSMB"),
]
)SwiftSMB currently declares support for macOS 10.15+, iOS 13+, macCatalyst 13+, tvOS 13+, visionOS 1+, and watchOS 6+. The package uses Swift tools version 6.2.
- Open your project in Xcode.
- Choose File -> Add Package Dependencies....
- Enter
https://github.com/RuiNelson/SwiftSMB.git. - Choose the version rule you want to use.
- Add the
SwiftSMBproduct to your app or framework target. - Import the library where you need it:
import SwiftSMBJust enter:
swift buildSome tests are integration tests and expect the Docker-based Samba test server to be running:
docker ps --filter ancestor=swiftsmb-testserver
source TestServer/up.sh
swift testOpen the folder, then disable Code Coverage on the test plan:
- Menu: Product -> Scheme -> SwiftSMB-Package
- Menu: Product -> Scheme -> Edit Scheme...
- Test Plans list should have an Autocreated test plan, click on the little encircled arrow
- Tab Configurations
- Set Code Coverage to Off
- If it still doesn't compile, do the same thing on the other schemes
SwiftSMB and the bundled libsmb2 sources are distributed under the GNU Lesser General Public License, version 2.1. A copy of the license is included in LICENSE.
The LGPL v2.1 permits use of the library from both open source and commercial software, including software distributed under different licenses, as long as the LGPL requirements for the library are respected. In practice, if you distribute an app or product that links with SwiftSMB/libsmb2, make sure you preserve license notices, provide access to the LGPL-covered source, and allow users to replace or relink the LGPL-covered library as required by the license.
This section is only a project summary, not legal advice. Review the LGPL v2.1 terms for your distribution model.