Skip to content
This repository was archived by the owner on Mar 7, 2026. It is now read-only.

Commit 0d4071f

Browse files
authored
Rewrite prostore.swift
1 parent d9de675 commit 0d4071f

1 file changed

Lines changed: 40 additions & 31 deletions

File tree

Sources/prostore/prostore.swift

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -164,45 +164,54 @@ struct ContentView: View {
164164

165165
// Zsign usually writes changes in-place inside the .app. Rezip Payload -> signed IPA
166166
let signedIpa = tmp.appendingPathComponent("signed_\(appName).ipa")
167-
// create archive with Payload directory
167+
// ensure output folder exists
168168
try fm.createDirectory(at: signedIpa.deletingLastPathComponent(), withIntermediateDirectories: true)
169169
let writeArchive = try Archive(url: signedIpa, accessMode: .create)
170170

171-
// recursively add Payload
172-
let enumerator = fm.enumerator(at: payload, includingPropertiesForKeys: nil)!
171+
// ===== Walk Payload and collect directories and files =====
172+
let enumerator = fm.enumerator(at: payload, includingPropertiesForKeys: [.isDirectoryKey], options: [], errorHandler: nil)!
173+
var directories: [URL] = []
174+
var filesList: [URL] = []
173175
for case let file as URL in enumerator {
174-
let relative = file.path.replacingOccurrences(of: tmp.path + "/", with: "")
175-
if file.hasDirectoryPath {
176-
try writeArchive.addEntry(
177-
with: relative + "/",
178-
type: .directory,
179-
uncompressedSize: 0,
180-
modificationDate: Date(),
181-
permissions: nil,
182-
compressionMethod: .deflate,
183-
bufferSize: 16 * 1024,
184-
progress: nil,
185-
provider: { _, _ in Data() }
186-
)
176+
// Skip the Payload root itself (we want entries relative to tmp)
177+
if file == payload { continue }
178+
let isDirResource = try file.resourceValues(forKeys: [.isDirectoryKey]).isDirectory ?? file.hasDirectoryPath
179+
if isDirResource {
180+
directories.append(file)
187181
} else {
188-
let data = try Data(contentsOf: file)
189-
try writeArchive.addEntry(
190-
with: relative,
191-
type: .file,
192-
uncompressedSize: UInt32(data.count),
193-
modificationDate: Date(),
194-
permissions: nil,
195-
compressionMethod: .deflate,
196-
bufferSize: 16 * 1024,
197-
progress: nil,
198-
provider: { (position, size) in
199-
data.subdata(in: Int(position)..<Int(position + size))
200-
}
201-
)
182+
filesList.append(file)
202183
}
203184
}
204185

205-
// share file (move to Documents to be easily accessible)
186+
// Sort directories so parent directories come before children (shorter path first)
187+
directories.sort { $0.path.count < $1.path.count }
188+
189+
// Base for relative paths is tmp
190+
let base = tmp
191+
192+
// Add directories first (use .none compression and trailing slash)
193+
for dir in directories {
194+
let relative = dir.path.replacingOccurrences(of: tmp.path + "/", with: "")
195+
// ensure trailing slash for directory entries inside zip
196+
let entryPath = relative.hasSuffix("/") ? relative : relative + "/"
197+
try writeArchive.addEntry(
198+
with: entryPath,
199+
relativeTo: base,
200+
compressionMethod: .none
201+
)
202+
}
203+
204+
// Add files (let ZIPFoundation read from disk)
205+
for file in filesList {
206+
let relative = file.path.replacingOccurrences(of: tmp.path + "/", with: "")
207+
try writeArchive.addEntry(
208+
with: relative,
209+
relativeTo: base,
210+
compressionMethod: .deflate
211+
)
212+
}
213+
214+
// Finalise: copy to Documents so user can share
206215
let docs = fm.urls(for: .documentDirectory, in: .userDomainMask).first!
207216
let outURL = docs.appendingPathComponent("signed_\(UUID().uuidString).ipa")
208217
if fm.fileExists(atPath: outURL.path) { try fm.removeItem(at: outURL) }

0 commit comments

Comments
 (0)