Skip to content

Commit 2fbffa4

Browse files
authored
feat(iOS): Support ZIP format (#383)
* decompose extraction functions * check for manifest
1 parent 4bea10c commit 2fbffa4

File tree

1 file changed

+52
-4
lines changed

1 file changed

+52
-4
lines changed

react-native-mcu-manager/ios/DeviceUpgrade.swift

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,56 @@ class DeviceUpgrade {
3636
self.logDelegate = UpdateLogDelegate()
3737
}
3838

39+
func extractImageFrom(from url: URL) throws -> [ImageManager.Image] {
40+
switch url.pathExtension.lowercased() {
41+
case "bin":
42+
return try extractImageFromBinFile(from: url)
43+
case "zip":
44+
return try extractImageFromZipFile(from: url)
45+
default:
46+
throw Exception(name: "UnsupportedFileType", description: "File must be .bin or .zip")
47+
}
48+
}
49+
50+
func extractImageFromBinFile(from url: URL) throws -> [ImageManager.Image] {
51+
let binData = try Data(contentsOf: url)
52+
let binHash = try McuMgrImage(data: binData).hash
53+
return [ImageManager.Image(image: 0, hash: binHash, data: binData)]
54+
}
55+
56+
func extractImageFromZipFile(from url: URL) throws -> [ImageManager.Image] {
57+
let fileManager = FileManager.default
58+
let tempDirectory = fileManager.temporaryDirectory.appendingPathComponent(UUID().uuidString)
59+
60+
try fileManager.createDirectory(at: tempDirectory, withIntermediateDirectories: true, attributes: nil)
61+
62+
defer {
63+
try? fileManager.removeItem(at: tempDirectory)
64+
}
65+
66+
try fileManager.unzipItem(at: url, to: tempDirectory)
67+
let unzippedURLs = try fileManager.contentsOfDirectory(at: tempDirectory, includingPropertiesForKeys: nil, options: [])
68+
69+
guard let dfuManifestURL = unzippedURLs.first(where: { $0.pathExtension == "json" }) else {
70+
throw McuMgrPackage.Error.manifestFileNotFound
71+
}
72+
let manifest = try McuMgrManifest(from: dfuManifestURL)
73+
let images = try manifest.files.compactMap { manifestFile -> ImageManager.Image in
74+
guard let imageURL = unzippedURLs.first(where: { $0.absoluteString.contains(manifestFile.file) }) else {
75+
throw McuMgrPackage.Error.manifestImageNotFound
76+
}
77+
let imageData = try Data(contentsOf: imageURL)
78+
let imageHash = try McuMgrImage(data: imageData).hash
79+
return ImageManager.Image(manifestFile, hash: imageHash, data: imageData)
80+
}
81+
82+
try unzippedURLs.forEach { url in
83+
try fileManager.removeItem(at: url)
84+
}
85+
86+
return images
87+
}
88+
3989
func startUpgrade(_ promise: Promise) {
4090
self.promise = promise
4191

@@ -49,9 +99,7 @@ class DeviceUpgrade {
4999
}
50100

51101
do {
52-
let binData = try Data(contentsOf: fileUrl)
53-
let binHash = try McuMgrImage(data: binData).hash
54-
let image = ImageManager.Image(image: 0, hash: binHash, data: binData)
102+
let images = try extractImageFrom(from: fileUrl)
55103

56104
self.bleTransport = McuMgrBleTransport(bleUuid)
57105
self.dfuManager = FirmwareUpgradeManager(transport: self.bleTransport!, delegate: self)
@@ -64,7 +112,7 @@ class DeviceUpgrade {
64112

65113
DispatchQueue.main.async {
66114
do {
67-
try self.dfuManager!.start(images: [image], using: config)
115+
try self.dfuManager!.start(images: images, using: config)
68116
} catch {
69117
promise.reject(UnexpectedException(error))
70118
}

0 commit comments

Comments
 (0)