Skip to content

Latest commit

 

History

13 Commits

Folders and files

Repository files navigation

FTPServerKit

A lightweight, read-only FTP server for iOS and macOS apps, built on Network.framework with no dependencies.

Use it to share files from your app with any FTP client on the local network: FileZilla, Cyberduck, Finder, curl, or embedded devices that download files over FTP.

Features

  • Serves a whole directory (including subdirectories) or a single file, or your own source through the FTPFileProvider protocol
  • Passive mode (PASV and EPSV), resume (REST), SIZE and MDTM
  • Files are streamed in chunks, so large files aren't loaded into memory
  • Username and password or anonymous login
  • async start that reports errors such as a port already in use
  • Server events as an AsyncStream, a Combine publisher or a delegate, so it fits any codebase, plus a log handler
  • Opt-in workarounds for older and embedded FTP clients
  • Swift 6 language mode, safe to use from any thread

Requirements

  • iOS 15 or macOS 12
  • Swift 6 (Xcode 16 or later)

Installation

Add the package in Xcode with File → Add Package Dependencies…, or in Package.swift:

dependencies: [
    .package(url: "https://github.com/CodeInstinctAI/FTPServerKit.git", from: "0.1.0"),
],
targets: [
    .target(name: "MyApp", dependencies: ["FTPServerKit"]),
]

On iOS, add NSLocalNetworkUsageDescription to your app's Info.plist. iOS shows its text when it asks the user for local network access.

Quick start

import FTPServerKit

let documents = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]

let server = FTPServer(
    configuration: FTPServerConfiguration(
        port: 2121,
        authentication: .credentials(username: "user", password: "pass")
    ),
    fileProvider: FTPDirectoryProvider(rootURL: documents)
)

let port = try await server.start()
let address = IPAddressHelper.getLocalIPAddress() ?? "localhost"
print("Connect to ftp://\(address):\(port)")

// Later
server.stop()

Use FTPSingleFileProvider(fileURL:) to serve a single file instead.

Documentation

The full documentation is on the Swift Package Index. You can also build it in Xcode with Product → Build Documentation.

Good to know

  • Read-only. Uploads, deletes and renames get 550. Clients have to use passive mode, which they do by default.
  • Plain FTP only. There's no TLS, so usernames, passwords and files travel unencrypted. Use it on networks you trust.
  • Background. iOS suspends an app's network listeners soon after it goes to the background. Stop the server when your app does, and start it again when the app becomes active.

Example app

Example/FTPServerKitExample.xcodeproj is a SwiftUI app that shares files you pick with any FTP client on the network. It uses the package from this folder and isn't part of the package product, so it's never built into apps that depend on FTPServerKit.

To run it on a device, create Example/Signing.local.xcconfig (ignored by git) with your own team and a bundle ID you own:

DEVELOPMENT_TEAM = ABCDE12345
PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.FTPServerKitExample

Running the tests

swift test

The transfer tests run real downloads through /usr/bin/curl and only run on macOS.

License

FTPServerKit is available under the MIT license. See LICENSE for details.

About

Embeddable read-only FTP server for iOS and macOS apps, written in Swift 6.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages