Tiercel: a pure Swift iOS download framework with background and relaunch recovery
Pure Swift iOS download framework with background downloads, relaunch recovery, resumable transfers, and task management.
At a glance
- What is it?
- Tiercel wraps URLSession in a higher-level manager and task model for iOS apps that need downloads to survive a relaunch. This looks at what it actually does, how to install it, and where it stops being the right tool.
- Who is it for?
- Adopt Tiercel if your iOS app needs downloads that resume after a relaunch and you want a manager-level API over URLSessionDownloadTask, with separate SessionManager instances per download domain. Do not adopt it if you are not on iOS, since the README sets a minimum of iOS 12.0, or if you only ever download one small file in the foreground, where raw URLSession is less machinery.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 36 days ago.
- What is it written in?
- Mainly Swift, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Tiercel solves for iOS download code
Raw URLSessionDownloadTask gives you the transfer primitive and little else. If a user backgrounds the app, or the process is killed and relaunched, the app has to persist enough state to know which downloads existed, which URLs they pointed at, and whether a resume data blob is still valid. That persistence layer is application-specific work, and it is the part teams usually get wrong first.
Tiercel targets that gap. The README describes it as a framework for background downloads, relaunch recovery, resumable transfers, and URLSession-based task orchestration, and the comparison table it publishes contrasts raw URLSession against Tiercel on exactly those axes: background downloads, relaunch recovery, batch operations, download domain isolation, and progress and validation hooks. The intended reader is an iOS developer who already understands URLSession and does not want to rebuild task bookkeeping on top of it.
The framework is not a networking stack replacement. It sits above Apple's native stack, which the README states explicitly when it lists the preference for a higher-level API over raw URLSessionDownloadTask while still using Apple's native stack underneath. That matters for anyone evaluating it against a fully custom networking layer.
How SessionManager and the task model fit together
The central object is SessionManager. The README's quick start constructs one with an identifier string and an optional SessionConfiguration:
var configuration = SessionConfiguration()
configuration.allowsCellularAccess = true
configuration.maxConcurrentTasksLimit = 3
let manager = SessionManager("downloads", configuration: configuration)
let task = manager.download("https://example.com/video.mp4")The identifier is not decoration. The README documents multiple SessionManager instances as the mechanism for keeping different download domains isolated, and the background-session callback example matches on manager.identifier against the identifier iOS passes into handleEventsForBackgroundURLSession. If you create two managers, you own two identifiers and two callback routes.
Task control is offered at two levels. You can address a download by URL string or by the task instance, and the README shows the same five verbs on both: start, suspend, cancel, remove, and remove with completely: false. Batch creation goes through multiDownload(urls), which returns an array of tasks.
Progress and completion are attached per task. The README's example chains progress(onMainQueue:), success and failure onto the task returned by manager.download, and prints task.progress.fractionCompleted and task.filePath. The onMainQueue parameter appears on both the progress and validation callbacks, which suggests the framework is aware that callers usually want UI updates on the main queue rather than dispatching manually.
Installing Tiercel and running a first download
Tiercel ships three ways: CocoaPods, Swift Package Manager, and manual source integration. The README's minimum platform is iOS 12.0, with a Swift 5.0+ language baseline.
For CocoaPods, add the pod to your Podfile and install:
platform :ios, '12.0'
use_frameworks!
target 'YourTargetName' do
pod 'Tiercel'
endThen run:
pod installFor Swift Package Manager, the README points at Xcode's File > Add Package Dependencies menu item and gives the repository URL:
https://github.com/Danie1s/Tiercel.gitFor manual integration, drag the Sources directory into your project and make sure those files are included in the target you want them in.
With the dependency in place, import the module and create a manager. The following is the README's quick start, which downloads one file, prints fractional progress on the main queue, and prints the saved path on success:
import Tiercel
var configuration = SessionConfiguration()
configuration.allowsCellularAccess = true
configuration.maxConcurrentTasksLimit = 3
let manager = SessionManager("downloads", configuration: configuration)
let task = manager.download("https://example.com/video.mp4")
task?.progress(onMainQueue: true) { task in
print("progress:", task.progress.fractionCompleted)
}.success { task in
print("saved to:", task.filePath)
}.failure { _ in
print("download failed")
}To explore the same behaviour interactively, the repository contains Demo/Tiercel-Demo.xcodeproj, and the README lists what the demo covers: single-file downloads, batch downloads, multiple isolated download managers, background session event handling, and validation and progress callbacks.
Relaunch recovery, background sessions and the AppDelegate contract
The recovery story depends on persistence. The README states that Tiercel persists task state and resume data to disk so downloads can be restored after the app relaunches, and it is explicit about the force-quit case: iOS stops background execution until the next launch, and once the app is opened again Tiercel can recover eligible downloads and continue from stored state. Note the word eligible. The README does not enumerate which tasks qualify for recovery, and that is the first thing worth checking against your own failure cases.
Native background session callbacks are not automatic. The app must forward the completion handler from AppDelegate to the manager whose identifier matches:
let downloadManagers = [managerA, managerB]
func application(_ application: UIApplication,
handleEventsForBackgroundURLSession identifier: String,
completionHandler: @escaping () -> Void) {
for manager in downloadManagers where manager.identifier == identifier {
manager.completionHandler = completionHandler
break
}
}This is a real integration constraint rather than a convenience. If your app creates managers lazily, or after the delegate callback fires, the completion handler has nowhere to go. The README's example keeps the managers in a top-level array precisely so the lookup can succeed at that point in the lifecycle.
Network policy, validation and where Tiercel is the wrong choice
SessionConfiguration carries the network policy knobs. Beyond maxConcurrentTasksLimit and allowsCellularAccess, the README documents allowsConstrainedNetworkAccess and allowsExpensiveNetworkAccess, which map onto the constrained and expensive connection concepts the README lists as supported.
Integrity checking is opt-in per task. The README shows validateFile(code:type:onMainQueue:) with an MD5 digest string and a completion that inspects task.validation for .correct or otherwise. Only MD5 appears in the example. If your distribution pipeline requires SHA-256, the README does not show it, and you should confirm what the type enumeration actually accepts before designing around it.
The clearest limitation is platform. The README sets a minimum of iOS 12.0 and describes the framework as an iOS download framework. There is no macOS, tvOS or Linux story in the README, so a multiplatform Swift package that happens to need downloads on the desktop is not a fit. The second limitation is architectural: Tiercel is a layer over URLSession, so it inherits URLSession's background-session semantics rather than replacing them. If your problem is not iOS background transfer at all, for example a server-side Swift job fetching files, you are carrying an iOS-shaped API for no benefit. A third gap is documentation depth. The README covers the happy path and the AppDelegate hook, but it does not document rollback behaviour, what happens to partially written files when a task is removed with completely: true, or how resume data is invalidated. Those are the questions to answer from the source before shipping.
Tiercel compared with hand-rolled URLSession management
The realistic alternative is not another framework. For most iOS teams it is writing the persistence and orchestration yourself on top of URLSessionDownloadTask, which is what the README's own comparison table assumes.
The difference is where the work sits. With raw URLSession you define your own task record, decide what to persist and when, write the resume data to disk yourself, and reconstruct state at launch. Tiercel moves that into a manager plus task model, with multiDownload for batch creation and manager-level start, suspend, cancel and remove. You give up some control over the persistence format and the recovery policy in exchange for not maintaining it.
The second alternative is staying at the URLSession level but adding only a thin persistence helper, keeping full control over the schema. That is a reasonable choice if your download set is small, or if your app already has a database layer you would rather store task metadata in. Tiercel's value grows with the number of queues and domains you manage, because multiple isolated SessionManager instances are the mechanism it offers for keeping them apart, and that is exactly the part that is tedious to build twice.
The trade-off to weigh honestly: adopting Tiercel means your download state lives in its format, and migrating away later means reading that state out. The README does not describe an export path.
Maintenance, licence and upgrade cost
The repository is not archived. The last push was on 2026-08-24, and the most recent release listed is 3.3.0 on the same date. The release before that, 3.2.10, is dated 2026-03-15, and 3.2.9 is dated 2026-01-16 with a Chinese release title mentioning multithreading fixes and optimisation. The cadence across those three releases is roughly every few months, not continuous.
The licence is MIT according to the repository metadata and the podspec badge, and a LICENSE file sits at the top level. MIT is permissive, so the practical implication for a closed-source app is attribution rather than source disclosure. This is not legal advice; read the LICENSE file itself, since that is the document that governs.
Upgrade cost is shaped by the API surface you touch. The README's examples use SessionConfiguration, SessionManager, manager.download, multiDownload, the task control verbs, progress, success, failure, validateFile and the AppDelegate completion handler. Those are the integration points, and a version bump that changes any of them lands in your download layer. The 3.2.9 release title suggests concurrency work has happened in recent versions, which is the category of change most likely to affect behaviour rather than signatures. Pinning a version and reading the release notes before moving is the cheap precaution.
Editorial conclusion
Adopt Tiercel if your iOS app needs downloads that resume after a relaunch and you want a manager-level API over URLSessionDownloadTask, with separate SessionManager instances per download domain. Do not adopt it if you are not on iOS, since the README sets a minimum of iOS 12.0, or if you only ever download one small file in the foreground, where raw URLSession is less machinery. Before committing, verify that the AppDelegate background-session wiring in the README matches your app's lifecycle, and confirm the licence text in LICENSE rather than relying on the MIT label in the podspec.
Frequently asked questions
How do I install Tiercel in an iOS project?
The README gives three routes: CocoaPods with pod 'Tiercel' followed by pod install, Swift Package Manager through Xcode's File > Add Package Dependencies using the repository URL, or manual integration by dragging the Sources directory into your target.
Does Tiercel support background downloads and recovery after the app relaunches?
Yes. The README states that Tiercel persists task state and resume data to disk so downloads can be restored after relaunch, and that once the app is opened again it can recover eligible downloads and continue from stored state. Native background session callbacks require wiring the AppDelegate completion handler to the matching SessionManager by identifier.
What platforms and Swift version does Tiercel require?
The README lists a minimum platform of iOS 12.0 and a Swift 5.0+ language baseline. Distribution is through CocoaPods, Swift Package Manager, and manual source integration.
Can Tiercel verify that a downloaded file is intact?
The README shows a per-task validateFile(code:type:onMainQueue:) call that takes an MD5 digest and a callback inspecting task.validation for .correct. Only MD5 appears in that example, so confirm what the type enumeration accepts before relying on another digest.
How do I run more than one download queue with Tiercel?
The README documents multiple SessionManager instances as the way to keep different download domains isolated. Each manager has its own identifier, and the AppDelegate background-session handler matches on that identifier to route the completion handler to the right manager.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/danie1s-tiercel)