Search code examples
iosswiftreact-nativegzipreact-native-fs

React Native or Swift gzip unpack to Documents directory on iOS


I have a React Native app that needs to decompress a gzip file so that it can access the individual files that are inside the gzip file. Exactly like how it works when you tap on the file in the iOS Files app and it extracts everything into a folder in the same directory. I can read the gzip using RNFS but that is just a stream of the raw data. I need the actual files that have been zipped up.

I could also do this in native Swift but I don't see a way to do it. NSData has a decompress() func but that's also just raw data. It must be possible, any thoughts?

I tried react-native-zip-archive unzip(base64DecodedString, filePath) but it doesn't seem to support gzip.


Solution

  • Here's a way to do it in Swift - you need both Gzip and Light-Swift-Untar Swift packages:

    // JSON with base64 value which represents the tar.gz
    if let type = resultDict["resultsData"] as? String {
      // create Data from the base64 string
      if let gzipData = Data(base64Encoded: type, options: .ignoreUnknownCharacters) {
        // check if isGzipped, from Gzip Swift pkg
        if gzipData.isGzipped {
            let ddata = NSData(base64Encoded: type)
            let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
            let filePath = "\(documentsPath)/unpacked.tar"
            let url = URL(fileURLWithPath: filePath)
            do{
              // first decompress gzip and write the tar file, using Gzip Swift pkg
              try! gzipData.gunzipped().write(to: url, options: .atomic)
              // next use the Light-Swift-Untar FileManager extension to unarchive the tar
              try FileManager.default.createFilesAndDirectories(path: "\(documentsPath)/exxxtracted", tarPath: filePath)
            } catch let failedError {
              print("Failed to write the gzip data due to \(failedError.localizedDescription)")
            }
        }
      }
    }