@hanwha-ss1/plugin 0.7.3 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -48,8 +48,16 @@ public class DownloadPlugin: CAPPlugin {
|
|
|
48
48
|
let totalChunks = call.getInt("totalChunks") ?? 1
|
|
49
49
|
let isLastChunk = call.getBool("isLastChunk") ?? false
|
|
50
50
|
|
|
51
|
+
// ✅ Data URL 처리 (base64, 이후 부분만 추출)
|
|
52
|
+
let pureBase64: String
|
|
53
|
+
if let range = chunkData.range(of: "base64,") {
|
|
54
|
+
pureBase64 = String(chunkData[range.upperBound...])
|
|
55
|
+
} else {
|
|
56
|
+
pureBase64 = chunkData
|
|
57
|
+
}
|
|
58
|
+
|
|
51
59
|
// Base64 → Data 변환
|
|
52
|
-
guard let data = Data(base64Encoded:
|
|
60
|
+
guard let data = Data(base64Encoded: pureBase64, options: .ignoreUnknownCharacters) else {
|
|
53
61
|
call.resolve([
|
|
54
62
|
"result": false,
|
|
55
63
|
"message": "청크 데이터(Base64) 디코딩 실패"
|
|
@@ -4,7 +4,6 @@ import Capacitor
|
|
|
4
4
|
|
|
5
5
|
public class DownloadService: NSObject {
|
|
6
6
|
|
|
7
|
-
// MARK: - 내부 구조체 (안드로이드의 ChunkDownloadInfo 대응)
|
|
8
7
|
private class ChunkDownloadInfo {
|
|
9
8
|
var tempFile: URL
|
|
10
9
|
var totalChunks: Int
|
|
@@ -16,12 +15,10 @@ public class DownloadService: NSObject {
|
|
|
16
15
|
self.totalChunks = totalChunks
|
|
17
16
|
self.receivedChunks = 0
|
|
18
17
|
|
|
19
|
-
// 임시 파일이 없으면 생성
|
|
20
18
|
if !FileManager.default.fileExists(atPath: tempFile.path) {
|
|
21
19
|
FileManager.default.createFile(atPath: tempFile.path, contents: nil, attributes: nil)
|
|
22
20
|
}
|
|
23
21
|
|
|
24
|
-
// 파일 핸들 열기
|
|
25
22
|
do {
|
|
26
23
|
self.fileHandle = try FileHandle(forWritingTo: tempFile)
|
|
27
24
|
} catch {
|
|
@@ -36,13 +33,14 @@ public class DownloadService: NSObject {
|
|
|
36
33
|
}
|
|
37
34
|
}
|
|
38
35
|
|
|
39
|
-
// MARK: - 다운로드 상태 관리 (안드로이드의 ConcurrentHashMap 대응)
|
|
40
36
|
private static var chunkDownloads: [String: ChunkDownloadInfo] = [:]
|
|
41
37
|
private static let queue = DispatchQueue(label: "DownloadServiceQueue", attributes: .concurrent)
|
|
42
38
|
|
|
43
|
-
// MARK: - 다운로드 생성
|
|
39
|
+
// MARK: - 다운로드 생성 (Documents 경로에 .tmp 생성)
|
|
44
40
|
public static func createDownload(id: String, totalChunks: Int) -> URL? {
|
|
45
|
-
let
|
|
41
|
+
let docsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
|
42
|
+
let tempURL = docsURL.appendingPathComponent("\(id).tmp")
|
|
43
|
+
|
|
46
44
|
let info = ChunkDownloadInfo(tempFile: tempURL, totalChunks: totalChunks)
|
|
47
45
|
|
|
48
46
|
queue.async(flags: .barrier) {
|
|
@@ -81,14 +79,27 @@ public class DownloadService: NSObject {
|
|
|
81
79
|
return complete
|
|
82
80
|
}
|
|
83
81
|
|
|
84
|
-
// MARK: - 다운로드 마무리
|
|
82
|
+
// MARK: - 다운로드 마무리 (tmp → 최종 파일명으로 이동)
|
|
85
83
|
public static func finishDownload(id: String) -> URL? {
|
|
86
|
-
var
|
|
84
|
+
var finalURL: URL?
|
|
87
85
|
queue.sync(flags: .barrier) {
|
|
88
86
|
if let info = chunkDownloads.removeValue(forKey: id) {
|
|
89
|
-
|
|
87
|
+
let docsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
|
88
|
+
let targetURL = docsURL.appendingPathComponent(id) // 최종 파일 이름
|
|
89
|
+
|
|
90
|
+
do {
|
|
91
|
+
// 기존 파일 삭제
|
|
92
|
+
if FileManager.default.fileExists(atPath: targetURL.path) {
|
|
93
|
+
try FileManager.default.removeItem(at: targetURL)
|
|
94
|
+
}
|
|
95
|
+
// tmp → 최종 경로로 이동
|
|
96
|
+
try FileManager.default.moveItem(at: info.tempFile, to: targetURL)
|
|
97
|
+
finalURL = targetURL
|
|
98
|
+
} catch {
|
|
99
|
+
print("❌ 파일 이동 실패: \(error)")
|
|
100
|
+
}
|
|
90
101
|
}
|
|
91
102
|
}
|
|
92
|
-
return
|
|
103
|
+
return finalURL
|
|
93
104
|
}
|
|
94
105
|
}
|