0

I am trying to programmatically create an ePub file. I am following this tutorial. The tutorial says to "make the .epub container that all these files go in" by:

  1. Create an empty .zip file with whatever name you like (See notes below for detailed instructions on how to do this.)
  2. Copy the mimetype file into the zip file (don't use compression on this file)
  3. Copy the rest of the files and folders mentioned above into the zip file *
  4. Re-name the .zip extension to .epub

These are the last few steps of the process. I have all the files that need to go into the zip ready. I know the files work because I used a third party program (eCanCrusherMac.1.2.1) to do these finals steps and the product it creates is an ePub file that loads in the Books eReader (made by Apple).

I used the below code to zip the desired directory. I found this code on here Stack Overflow

func zip(itemAtURL itemURL: URL, in destinationFolderURL: URL, zipName: String) throws {
    var error: NSError?
    var internalError: NSError?
    NSFileCoordinator().coordinate(readingItemAt: itemURL, options: [.forUploading], error: &error) { (zipUrl) in
        // zipUrl points to the zip file created by the coordinator
        // zipUrl is valid only until the end of this block, so we move the file to a temporary folder
        let finalUrl = destinationFolderURL.appendingPathComponent(zipName)
        do {
            try FileManager.default.moveItem(at: zipUrl, to: finalUrl)
        } catch let localError {
            internalError = localError as NSError
        }
    }
    
    if let error = error {
        throw error
    }
    if let internalError = internalError {
        throw internalError
    }
}

I took the file this function gives me, made sure it had the epub extension and tried to open it using the Books app but it fails to load. The code produces a zip file that I can interact with normally in Finder so I know the function works.

I believe the issue is with the "mimetype" file getting compressed. I have taken a valid ePub, changed the file's extension to zip, unzipped it and then rezipped it using Finder and tried to open it again with no other changes and it doesn't work. As you can see in the instructions from the tutorial at the top of this post the "mimetype" file can't be compressed.

This is a Swift app on Mac.

I looked into the different NSFileCoordinator.ReadingOptions and NSFileCoordinator.WritingOptions and searched on Stack Overflow and elsewhere online but I can't find anything on how to create a zip file in Swift without compressing a file contained in the zip file.

TylerP
  • 9,600
  • 4
  • 39
  • 43
KevinF
  • 57
  • 9
  • 1
    The only way to make it work is if the zip library you are using lets you specify that a file should be added uncompressed. – HangarRash Nov 06 '22 at 23:23
  • @HangarRash Oh, that's a bummer. Do you know of any libraries that can do this? – KevinF Nov 07 '22 at 00:10

1 Answers1

0

I was able to get the ePub to open using ZIPFoundation:

try FileManager.default.zipItem(
  at: bookURL,
  to: ePubURL,
  shouldKeepParent: false,
  compressionMethod: .none,
  progress: nil
)
KevinF
  • 57
  • 9