Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 139 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ A lightweight Kotlin Multiplatform download manager for Android and iOS. Uses pl

## Features

- Simple, unified API across platforms
- Kotlin DSL for easy configuration
- Progress tracking with callbacks
- Error handling with detailed information
- Cancel downloads by ID
- MIME type detection
- Platform-native implementations (Android `DownloadManager`, iOS `NSURLSession`)
- State management (pending, downloading, paused, completed, failed, cancelled)
- Authentication support (Bearer token, Basic auth)
- Custom headers
- Network type restrictions (WiFi only)
- Platform-native implementations:
- Android: `DownloadManager` (system-managed, survives app kill, shows notifications)
- iOS: `NSURLSession` (background download support)

## Installation

Expand All @@ -37,42 +40,118 @@ dependencyResolutionManagement {
kotlin {
sourceSets {
commonMain.dependencies {
implementation("dev.onexeor.kdownloader:shared:0.1.0")
implementation("dev.onexeor.kdownloader:shared:0.2.0")
}
}
}
```

### Android Setup

Initialize KDownloader in your Application class:

```kotlin
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
KDownloader.init(this)
}
}
```

## Usage

### Basic Download

```kotlin
val downloader = KDownloader(context) // Android requires Context

val downloadId = downloader.downloadFile(
url = "https://example.com/file.pdf",
fileName = "document.pdf",
progressListener = { uri, status ->
println("Download progress: $uri, status: $status")
},
errorListener = { error ->
println("Error: ${error.description} (${error.statusCode})")
val downloader = KDownloader()

downloader.download("https://example.com/file.pdf") {
fileName = "document.pdf"

onProgress { progress ->
println("${progress.percentage}%")
}
)

onComplete { filePath ->
println("Downloaded to: $filePath")
}

onError { error ->
println("Failed: ${error.message}")
}
}
```

### Cancel Download
### With Authentication

```kotlin
downloader.cancelDownloadById(downloadId)
downloader.download("https://api.example.com/private/file.zip") {
fileName = "data.zip"

auth {
bearer("your-access-token")
}

onComplete { println("Done: $it") }
}
```

### Get Download Info
### With Custom Headers

```kotlin
val mimeType = downloader.getMimeTypeById(downloadId)
val url = downloader.getUrlById(downloadId)
downloader.download("https://example.com/file.pdf") {
headers {
"X-Custom-Header" to "value"
"Accept" to "application/octet-stream"
}
}
```

### WiFi Only Download

```kotlin
downloader.download("https://example.com/large-file.zip") {
wifiOnly()

onStateChange { state ->
when (state) {
is DownloadState.Paused -> println("Waiting: ${state.reason}")
is DownloadState.Downloading -> println("Progress: ${state.progress.percentage}%")
is DownloadState.Completed -> println("Done!")
else -> {}
}
}
}
```

### Task Control

```kotlin
val task = downloader.download("https://example.com/file.zip")

// Add listeners after creation (fluent API)
task.onProgress { println("${it.percentage}%") }
.onComplete { println("Done: $it") }
.onError { println("Error: ${it.message}") }

// Check current state
println("State: ${task.currentState}")
println("Progress: ${task.currentProgress.percentage}%")

// Cancel if needed
task.cancel()
```

### Configuration

```kotlin
val downloader = KDownloader(
KDownloaderConfig(
defaultDirectory = "MyApp/Downloads",
defaultNetworkType = NetworkType.ANY
)
)
```

## API Reference
Expand All @@ -81,35 +160,57 @@ val url = downloader.getUrlById(downloadId)

| Method | Description |
|--------|-------------|
| `downloadFile(url, fileName?, progressListener?, errorListener?)` | Start a download, returns download ID |
| `cancelDownloadById(downloadId)` | Cancel an active download |
| `getMimeTypeById(downloadId)` | Get MIME type of downloaded file |
| `getUrlById(downloadId)` | Get original URL of download |

### DownloadError
| `download(url, builder)` | Start a download with DSL configuration |
| `download(request)` | Start a download with pre-built request |
| `getTask(id)` | Get an existing download task by ID |
| `cancelAll()` | Cancel all active downloads |

### DownloadState

| State | Description |
|-------|-------------|
| `Pending` | Download is queued |
| `Downloading(progress)` | Download is in progress |
| `Paused(reason)` | Download is paused |
| `Completed(filePath)` | Download completed successfully |
| `Failed(error)` | Download failed with an error |
| `Cancelled` | Download was cancelled |

### DownloadError Types

| Type | Description |
|------|-------------|
| `Network` | Connection failed, timeout, etc. |
| `Http` | HTTP error response (4xx, 5xx) |
| `Storage` | Disk full, permission denied, etc. |
| `InvalidUrl` | Malformed URL |
| `Cancelled` | User cancelled the download |
| `Unknown` | Unexpected error |

### Auth

```kotlin
data class DownloadError(
val url: String, // Original download URL
val status: Int, // Download manager status code
val description: String,// Human-readable error description
val statusCode: Int // HTTP status code
)
auth {
bearer("token") // Bearer token authentication
basic("user", "password") // Basic authentication
}
```

## Platform Requirements

| Platform | Minimum Version |
|----------|-----------------|
| Android | API 24 (7.0) |
| iOS | Supported via KMP |
| iOS | 13.0 |

## Roadmap

- [ ] Authentication support (Basic, Token)
- [ ] Cookie handling
- [ ] Custom headers
- [x] Authentication support (Bearer, Basic)
- [x] Custom headers
- [x] Kotlin DSL API
- [ ] Download queue management
- [ ] Resume/pause support
- [ ] Download speed tracking

## License

Expand Down
2 changes: 1 addition & 1 deletion shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
}

group = "dev.onexeor.kdownloader"
version = "0.1.0"
version = "0.2.0"

kotlin {
androidTarget {
Expand Down
Loading