fix(ios): add directory array items recursively in zip/zipWithPassword (#339)#362
Conversation
#339) Passing a directory in a zip(string[]) array produced an empty entry on iOS (SSZipArchive withFilesAtPaths: writes directories as empty entries), while Android adds the directory's contents recursively. iOS now expands directory items itself and writes each contained file with its path relative to the listed directory via SSZipArchive's instance API, matching Android's entry names and behavior. Existing behaviors are preserved: per-entry progress events, AES:YES writes for zipWithPassword (as before via withFilesAtPaths:), and compressionLevel remaining ignored for file arrays on iOS. One residual divergence: empty directories are preserved on Android only; documented in the README.
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
| NSUInteger total = entries.count, complete = 0; | ||
| for (NSArray<NSString *> *entry in entries) { | ||
| success &= [zipArchive writeFileAtPath:entry[0] withFileName:entry[1] compressionLevel:compressionLevel password:password AES:aes]; | ||
| if (self.progressHandler) { | ||
| complete++; | ||
| self.progressHandler(complete, total); | ||
| } |
There was a problem hiding this comment.
🔍 Progress event denominator differs from Android for directory inputs
The new iOS writeZipEntriesToPath precomputes total = entries.count where entries are the fully recursively-expanded files (ios/RNZipArchive.mm:202). Android's processZip instead accumulates totalFiles incrementally and, for a directory item, counts only the immediate children (android/.../RNZipArchiveModule.java:381-393), calling addFolder once per immediate subdirectory while still incrementing the counter by 1. This means for directory inputs the two platforms emit a different number of intermediate progress ticks and different intermediate progress fractions. REVIEW.md states the progress contract was aligned in v9 and that divergence should be treated as a bug. In practice the iOS side is arguably more correct (monotonic, precomputed denominator), while Android's incremental denominator can jump around, so I did not flag this as a hard bug — but reviewers relying on strict cross-platform progress parity should be aware the tick counts diverge for directory array items.
Was this helpful? React with 👍 or 👎 to provide feedback.
|
Re: Devin's comment on the progress denominator — acknowledged, and we're leaving it as-is in this PR on purpose. The iOS side (precomputed, monotonic denominator over fully expanded entries) is the more correct behavior and closer to the v9 progress contract; Android's |
Fixes #339.
Problem
zip(string[])behaved inconsistently across platforms when an array item is a directory:a.txt,sub/b.txt).createZipFileAtPath:withFilesAtPaths:, which writes a directory as an empty entry — contents were silently dropped.Fix
iOS now expands the array itself before writing, using SSZipArchive's public instance API (
initWithPath:/open/writeFileAtPath:withFileName:.../close`):Applied to both
zipFilesandzipFilesWithPassword.Preserved behaviors
zipFilesWithPasswordstill writes with AES:YES, matching the previouswithFilesAtPaths:code pathcompressionLevelremains ignored for file arrays on iOS (pre-existing; already documented)Residual divergence
Android preserves empty directories (zip4j folder entries); iOS skips directory entries. Documented in the README along with the aligned behavior.
Verification
npx jest— 27/27 pass