iOS设计一个文件下载组件

37 阅读2分钟

以下是一个iOS端文件下载组件的设计方案,包含核心模块、功能实现和代码示例:

一、架构设计

采用分层架构,分为三大模块:

  1. DownloadManager(核心控制层)
  2. DownloadTask(任务模型层)
  3. PersistenceManager(持久化层)

二、核心功能实现

1. DownloadManager 核心类

swift

class DownloadManager: NSObject {
    static let shared = DownloadManager()
    
    private var session: URLSession!
    private var activeTasks = [String: DownloadTask]()
    private let queue = DispatchQueue(label: "com.download.queue", attributes: .concurrent)
    private let maxConcurrentDownloads = 3
    
    override init() {
        super.init()
        let config = URLSessionConfiguration.background(withIdentifier: "com.download.background")
        config.isDiscretionary = true
        config.sessionSendsLaunchEvents = true
        self.session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
    }
    
    // 添加下载任务
    func addDownloadTask(url: URL) -> DownloadTask {
        let task = DownloadTask(url: url)
        queue.async(flags: .barrier) {
            self.activeTasks[task.taskID] = task
            self.startNextTasksIfNeeded()
        }
        return task
    }
    
    // 控制并发逻辑
    private func startNextTasksIfNeeded() {
        // 实现并发控制逻辑
    }
}

2. 下载任务模型

swift

class DownloadTask: NSObject, Codable {
    enum State: String, Codable {
        case queued, downloading, paused, completed, failed
    }
    
    let taskID: String
    let url: URL
    var state: State = .queued
    var progress: Float = 0
    var resumeData: Data?
    var localFileURL: URL?
    
    init(url: URL) {
        self.taskID = UUID().uuidString
        self.url = url
    }
}

3. URLSession 委托实现

swift

extension DownloadManager: URLSessionDownloadDelegate {
    func urlSession(_ session: URLSession, 
                   downloadTask: URLSessionDownloadTask,
                   didFinishDownloadingTo location: URL) {
        // 文件转移逻辑
        saveDownloadedFile(from: location, for: downloadTask)
    }
    
    func urlSession(_ session: URLSession,
                   downloadTask: URLSessionDownloadTask,
                   didWriteData bytesWritten: Int64,
                   totalBytesWritten: Int64,
                   totalBytesExpectedToWrite: Int64) {
        // 进度更新逻辑
        updateProgress(for: downloadTask)
    }
    
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        // 错误处理与状态更新
        handleTaskCompletion(task: task, error: error)
    }
}

三、关键功能实现

1. 断点续传

swift

复制

下载

func resumeTask(_ task: DownloadTask) {
    if let resumeData = task.resumeData {
        task.downloadTask = session.downloadTask(withResumeData: resumeData)
    } else {
        task.downloadTask = session.downloadTask(with: task.url)
    }
    task.downloadTask?.resume()
}

func pauseTask(_ task: DownloadTask) {
    task.downloadTask?.cancel(byProducingResumeData: { data in
        task.resumeData = data
    })
}

2. 后台下载支持

swift

// AppDelegate 中处理
func application(_ application: UIApplication,
                 handleEventsForBackgroundURLSession identifier: String,
                 completionHandler: @escaping () -> Void) {
    DownloadManager.shared.backgroundCompletionHandler = completionHandler
}

3. 持久化存储

swift

class PersistenceManager {
    func saveTasks(_ tasks: [DownloadTask]) {
        // 使用CoreData/Realm/UserDefaults存储
    }
    
    func loadTasks() -> [DownloadTask] {
        // 从持久化存储加载
    }
}

四、高级功能扩展

1. 网络状态监听

swift

class NetworkMonitor {
    static let shared = NetworkMonitor()
    private let monitor = NWPathMonitor()
    
    func startMonitoring() {
        monitor.pathUpdateHandler = { path in
            DownloadManager.shared.handleNetworkChange(isReachable: path.status == .satisfied)
        }
    }
}

2. 智能重试策略

swift

struct RetryPolicy {
    let maxRetryCount: Int
    let retryIntervals: [TimeInterval]
    
    func shouldRetry(failureCount: Int) -> TimeInterval? {
        guard failureCount < maxRetryCount else { return nil }
        return retryIntervals[min(failureCount, retryIntervals.count-1)]
    }
}

五、使用示例

swift

// 开始下载
let task = DownloadManager.shared.addDownloadTask(url: fileURL)
task.progressHandler = { progress in
    DispatchQueue.main.async {
        progressView.progress = progress
    }
}

// 暂停/恢复
task.pause()
task.resume()

六、优化建议

  1. 内存管理:使用弱引用避免循环引用

  2. 线程安全:使用GCD barrier处理读写竞争

  3. 磁盘管理

    swift

    func checkStorageSpace() -> Bool {
        let freeSpace = DeviceStorage.freeDiskSpaceInBytes
        return estimatedSize < freeSpace * 0.8 // 保留20%空间
    }
    
  4. 安全校验

    swift

    func verifyFileIntegrity(fileURL: URL, expectedMD5: String) -> Bool {
        // 实现文件校验逻辑
    }
    

七、测试要点

  1. 模拟不同网络环境(100% Loss / 3G)
  2. 测试后台下载唤醒机制
  3. 验证断电/杀进程后的恢复能力
  4. 边界测试(超大文件/特殊字符文件名)

该设计方案充分考虑了iOS平台的特性,结合系统级API实现高效稳定的下载功能,同时提供了良好的扩展性。实际开发中需要根据具体业务需求调整并发策略、持久化方案和错误处理机制。