7

I have a zipped file, which i want to extract the contents of it. What is the exact procedure that i should do to achieve it. Is there any framework to unzip the files in cocoa framework or objective C.

boom
  • 5,856
  • 24
  • 61
  • 96

7 Answers7

7

If you are on iOS or don't want to use NSTask or whatever, I recommend my library SSZipArchive.

Usage:

NSString *path = @"path_to_your_zip_file";
NSString *destination = @"path_to_the_folder_where_you_want_it_unzipped";
[SSZipArchive unzipFileAtPath:path toDestination:destination];

Pretty simple.

Sam Soffes
  • 14,831
  • 9
  • 76
  • 80
6

On the Mac you can use the built in unzip command line tool using an NSTask:

- (void) unzip {
    NSFileManager* fm = [NSFileManager defaultManager];
    NSString* zipPath = @"myFile.zip";

    NSString* targetFolder = @"/tmp/unzipped"; //this it the parent folder
                                               //where your zip's content 
                                               //goes to (must exist)

    //create a new empty folder (unzipping will fail if any
    //of the payload files already exist at the target location)
    [fm createDirectoryAtPath:targetFolder withIntermediateDirectories:NO 
                                           attributes:nil error:NULL];


    //now create a unzip-task
    NSArray *arguments = [NSArray arrayWithObject:zipPath];
    NSTask *unzipTask = [[NSTask alloc] init];
    [unzipTask setLaunchPath:@"/usr/bin/unzip"];
    [unzipTask setCurrentDirectoryPath:targetFolder];
    [unzipTask setArguments:arguments];
    [unzipTask launch];
    [unzipTask waitUntilExit]; //remove this to start the task concurrently

}

That is a quick and dirty solution. In real life you will probably want to do more error checking and have a look at the unzip manpage for fancy arguments.

codingFriend1
  • 6,487
  • 6
  • 45
  • 67
4

Here's a Swift 4 version similar to Sven Driemecker's answer.

func unzipFile(at sourcePath: String, to destinationPath: String) -> Bool {
    let process = Process.launchedProcess(launchPath: "/usr/bin/unzip", arguments: ["-o", sourcePath, "-d", destinationPath])
    process.waitUntilExit()
    return process.terminationStatus <= 1
}

This implementation returns a boolean that determines if the process was successful or not. Is considering the process successful even if warnings were encountered.

The return condition can be changed to return process.terminationStatus == 0 to not even accept warnings.

See unzip docs for more details on diagnostics.

You can also capture the output of the process using a Pipe instance.

func unzipFile(at sourcePath: String, to destinationPath: String) -> Bool {
    let process = Process()
    let pipe = Pipe()

    process.executableURL = URL(fileURLWithPath: "/usr/bin/unzip")
    process.arguments = ["-o", sourcePath, "-d", destinationPath]
    process.standardOutput = pipe

    do {
        try process.run()
    } catch {
        return false
    }

    let resultData = pipe.fileHandleForReading.readDataToEndOfFile()
    let result = String (data: resultData, encoding: .utf8) ?? ""
    print(result)

    return process.terminationStatus <= 1
}
Alejandro Cotilla
  • 2,501
  • 1
  • 20
  • 35
3

If you just want to unzip the file, I would recommend using NSTask to call unzip(1). It's probably smart to copy the file to a directory you control -- probably in /tmp -- before unzipping.

Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140
Colin Barrett
  • 4,451
  • 1
  • 26
  • 33
  • 5
    You don't control /tmp, anyone can write to it. –  Feb 20 '10 at 07:47
  • Graham: But it's a fine place to do temporary work to avoid clobbering an existing folder. – Colin Barrett Feb 20 '10 at 08:03
  • 4
    Use `NSTemporaryDirectory()` instead of `/tmp`, although be careful, it behaves a little more like `/var/tmp`. It will get cleaned out, but it is not always at a reboot. – dreamlax Feb 21 '10 at 23:10
2

Here's a more concise version based on codingFriend1's approach

+ (void)unzip {
    NSString *targetFolder = @"/tmp/unzipped";
    NSString* zipPath = @"/path/to/my.zip";
    NSTask *task = [NSTask launchedTaskWithLaunchPath:@"/usr/bin/unzip" arguments:@[@"-o", zipPath, @"-d", targetFolder]];
    [task waitUntilExit];
}

-d specifies the destination directory, which will be created by unzip if not existent

-o tells unzip to overwrite existing files (but not to deleted outdated files, so be aware)

There's no error checking and stuff, but it's an easy and quick solution.

Sven Driemecker
  • 3,421
  • 1
  • 20
  • 22
1

Try Zip.framework.

1

-openFile: (NSWorkspace) is the easiest way I know.

Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50