Skip to content

Commit

Permalink
feat: download处理403错误 & upload最大分片限制
Browse files Browse the repository at this point in the history
  • Loading branch information
yanmu-why committed Oct 15, 2024
1 parent 60e5371 commit dbfc4e2
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 25 deletions.
2 changes: 1 addition & 1 deletion AliyunpanSDK.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = "AliyunpanSDK"
spec.version = "0.3.4"
spec.version = "0.3.5"
spec.summary = "Aliyunpan OpenSDK-iOS"

spec.description = <<-DESC
Expand Down
4 changes: 2 additions & 2 deletions Demo/Demo/Demo-iOS/FileListViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ extension FileListViewController: UICollectionViewDelegate {

extension FileListViewController: FileCellDelegate {
func fileCell(_ cell: FileCell, willDownload item: DisplayItem) {
guard let url = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first else {
guard let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
return
}

Expand All @@ -188,7 +188,7 @@ extension FileListViewController: FileCellDelegate {
} else {
let file = item.file
let filename = file.name.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? ""
let destination = url.appendingPathComponent(filename)
let destination = url.appendingPathComponent("Download").appendingPathComponent(filename)
client.downloader.download(file: file, to: destination)
}
}
Expand Down
4 changes: 2 additions & 2 deletions Demo/Demo/Demo-iOS/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class ViewController: UIViewController {
let file = try await client.uploader
.upload(
fileURL: url,
fileName: "test_\(Date().timeIntervalSince1970).pdf",
fileName: url.lastPathComponent,
driveId: driveId,
folderId: "root",
useProof: true)
Expand Down Expand Up @@ -186,7 +186,7 @@ extension ViewController: UICollectionViewDelegate {
}
}
case .uploadFileToRoot:
let documentPickerController = UIDocumentPickerViewController(forOpeningContentTypes: [.item])
let documentPickerController = UIDocumentPickerViewController(forOpeningContentTypes: [.item], asCopy: true)
documentPickerController.delegate = self
present(documentPickerController, animated: true)
case .createFolderOnRoot:
Expand Down
4 changes: 4 additions & 0 deletions Sources/AliyunpanSDK/AliyunpanError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ public struct AliyunpanError {
case userCancelled
/// 缺少 client
case invalidClient
/// 服务器错误
case serverError
/// 未知错误
case unknownError
}

/// 上传错误
Expand Down
2 changes: 1 addition & 1 deletion Sources/AliyunpanSDK/AliyunpanSDK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ public class Aliyunpan {
}
}

let version = "0.3.4"
let version = "0.3.5"
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,21 @@

import Foundation

public struct AliyunpanDownloadChunk: Equatable {
public struct AliyunpanDownloadChunk: Equatable, CustomStringConvertible {
public let start: Int64
public let end: Int64
public let index: Int

init(start: Int64, end: Int64) {
self.start = start
self.end = end
self.index = -1
}

init(start: Int64, end: Int64, index: Int) {
self.start = start
self.end = end
self.index = index
}

init?(rangeString: String, fileSize: Int64) {
Expand All @@ -29,6 +37,10 @@ public struct AliyunpanDownloadChunk: Equatable {
} else {
end = fileSize
}
self = Self(start: start, end: end)
self = Self(start: start, end: end, index: -1)
}

public var description: String {
"[chunk-\(index)]: \(start)-\(end)"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ extension AliyunpanDownloadTask {

var chunks: [AliyunpanDownloadChunk] {
stride(from: 0, to: totalSize, by: Int64.Stride(chunkSize)).map {
AliyunpanDownloadChunk(start: $0, end: min($0 + Int64(chunkSize), totalSize))
AliyunpanDownloadChunk(start: $0, end: min($0 + Int64(chunkSize), totalSize), index: Int($0 / chunkSize))
}
}

Expand Down Expand Up @@ -270,9 +270,11 @@ extension AliyunpanDownloadTask: DownloadChunkOperationDelegate {
}
} catch AliyunpanError.DownloadError.downloadURLExpired {
Logger.log(.error, msg: "[Downloader][\(file.name)], \(chunkIndex)/\(chunks.count) error, downloadURLExpired")

// 下载链接过期
retry(chunk: operation.chunk)
// 等待1s重试
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
guard let self else { return }
self.retry(chunk: operation.chunk)
}
} catch let error as NSError where error.domain == NSURLErrorDomain {
Logger.log(.error, msg: "[Downloader][\(file.name)], \(chunkIndex)/\(chunks.count) error, \(error)")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,18 @@ extension DownloadChunkOperation: URLSessionDownloadDelegate {
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if let error {
chunkOperationDidCompleteWithError(error)
} else if let response = task.response as? HTTPURLResponse,
response.statusCode == 403,
// https://help.aliyun.com/zh/oss/support/0002-00000069
response.value(forHTTPHeaderField: "x-oss-ec") == "0002-00000069" {
chunkOperationDidCompleteWithError(
AliyunpanError.DownloadError.downloadURLExpired)
} else if let response = task.response as? HTTPURLResponse {
if response.statusCode == 403 {
// https://help.aliyun.com/zh/oss/support/0002-00000069
chunkOperationDidCompleteWithError(
AliyunpanError.DownloadError.downloadURLExpired)
} else if response.statusCode < 200 || response.statusCode >= 300{

Check warning on line 175 in Sources/AliyunpanSDK/HTTPRequest/Download/DownloadChunkOperation.swift

View workflow job for this annotation

GitHub Actions / build (macOS)

Opening Brace Spacing Violation: Opening braces should be preceded by a single space and on the same line as the declaration (opening_brace)

Check warning on line 175 in Sources/AliyunpanSDK/HTTPRequest/Download/DownloadChunkOperation.swift

View workflow job for this annotation

GitHub Actions / build (macOS)

Opening Brace Spacing Violation: Opening braces should be preceded by a single space and on the same line as the declaration (opening_brace)

Check warning on line 175 in Sources/AliyunpanSDK/HTTPRequest/Download/DownloadChunkOperation.swift

View workflow job for this annotation

GitHub Actions / build (iOS Simulator,name=iPhone 14)

Opening Brace Spacing Violation: Opening braces should be preceded by a single space and on the same line as the declaration (opening_brace)

Check warning on line 175 in Sources/AliyunpanSDK/HTTPRequest/Download/DownloadChunkOperation.swift

View workflow job for this annotation

GitHub Actions / build (tvOS Simulator,name=Apple TV)

Opening Brace Spacing Violation: Opening braces should be preceded by a single space and on the same line as the declaration (opening_brace)

Check warning on line 175 in Sources/AliyunpanSDK/HTTPRequest/Download/DownloadChunkOperation.swift

View workflow job for this annotation

GitHub Actions / build (tvOS Simulator,name=Apple TV)

Opening Brace Spacing Violation: Opening braces should be preceded by a single space and on the same line as the declaration (opening_brace)
chunkOperationDidCompleteWithError(AliyunpanError.DownloadError.serverError)
} else {
/// 200 - 300 之间的不认为是错误
}
} else {
chunkOperationDidCompleteWithError(AliyunpanError.DownloadError.unknownError)
}
}

Expand All @@ -183,7 +189,11 @@ extension DownloadChunkOperation: URLSessionDownloadDelegate {
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
do {
let data = try Data(contentsOf: location)
chunkOperatioDidFinishDownload(data)
if data.count == chunk.end - chunk.start {
chunkOperatioDidFinishDownload(data)
} else {
/// 大小不一致时,会触发 urlSession的 didCompleteWithError方法,这里不做处理
}
} catch {
chunkOperationDidCompleteWithError(error)
}
Expand Down
14 changes: 9 additions & 5 deletions Sources/AliyunpanSDK/HTTPRequest/Upload/AliyunpanUploader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,12 @@ fileprivate extension Array where Element == AliyunpanFile.PartInfo {
/// 上传器
public class AliyunpanUploader: NSObject {
weak var client: AliyunpanClient?
/// 每 2G 分片
private static let chunkSize: Int64 = 2_000_000_000
/// 默认每 2G 分片,最大1000片
private static let defaultMaxChunkCount: Int64 = 1000
private static let defaultChunkSize: Int64 = 2_000_000_000
private static func realChunkSize(fileSize: Int64) -> Int64 {
max(defaultChunkSize, fileSize / defaultMaxChunkCount)
}

/// 创建上传任务,并适当分片
private func createUploadTask(
Expand All @@ -51,7 +55,7 @@ public class AliyunpanUploader: NSObject {
folderId: String,
checkNameMode: AliyunpanFile.CheckNameMode
) async throws -> AliyunpanScope.File.CreateFile.Response {
let partInfoList = [AliyunpanFile.PartInfo](fileSize: fileSize, chunkSize: Self.chunkSize)
let partInfoList = [AliyunpanFile.PartInfo](fileSize: fileSize, chunkSize: Self.realChunkSize(fileSize: fileSize))

let task = try await client.send(
AliyunpanScope.File.CreateFile(
Expand Down Expand Up @@ -118,7 +122,7 @@ public class AliyunpanUploader: NSObject {
throw AliyunpanError.AuthorizeError.accessTokenInvalid
}

let partInfoList = [AliyunpanFile.PartInfo](fileSize: fileSize, chunkSize: Self.chunkSize)
let partInfoList = [AliyunpanFile.PartInfo](fileSize: fileSize, chunkSize: Self.realChunkSize(fileSize: fileSize))

var isPreHashMatched = false
// 大于 10M 的文件先预校验
Expand Down Expand Up @@ -232,7 +236,7 @@ public class AliyunpanUploader: NSObject {
"Content-Length": "\(partInfo.part_size ?? 0)",
"Content-Type": "" // 不能传 Cotent-Type,否则会失败
]
let beginOffset = Int64(index) * Self.chunkSize
let beginOffset = Int64(index) * Self.realChunkSize(fileSize: fileSize)
let endOffset = beginOffset + Int64(partInfo.part_size ?? 0)
let data = try FileManager.default.dataChunk(at: fileURL, in: Int(beginOffset)..<Int(endOffset))
_ = try await session.upload(for: urlRequest, from: data)
Expand Down
2 changes: 1 addition & 1 deletion Sources/AliyunpanSDK/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.3.4</string>
<string>0.3.5</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down

0 comments on commit dbfc4e2

Please sign in to comment.