The difference is that instead of calling the contentsOfDirectoryAtPath method, the subpathsAtPath method is called, which will list all the files and subdirectories under sourcePath, and then in the following loop, write the file to the compressed file without processing the folder. Note that subPath should be used directly for newname, which will automatically retain the full path of the file in the subdirectory in the compressed file
NSArray *subPaths = [fileManager subpathsAtPath:sourcePath];// The key is the subpathsAtPath method for(NSString *subPath in subPaths){ NSString *fullPath = [sourcePath stringByAppendingPathComponent:subPath]; BOOL isDir; if([fileManager fileExistsAtPath:fullPath isDirectory:&isDir] && !isDir)// Only process files { [zipArchive addFileToZip:fullPath newname:subPath]; } }