FileWrapper and duplicate children naming scheme

I have a FileWrapper that holds a bunch of child documents. FileWrapper automatically handles assigning unique filenames to duplicates, but it does so in a pretty ugly manner – rather than, for example, "Untitled", "Untitled 2", "Untitled 3" it gives me:

"Untitled", and then "1__#$!@%!#__Untitled", "2__#$!@%!#__Untitled"


Is there a better way to assign names to these? Ideally I'd be able to supply a desired scheme for unique-ifying filenames, like a format string. Otherwise, what's the best way to ensure a child wrapper gets a sane suffix when there's duplicates?

I don't think there's anything preventing you from setting "preferredFileName" to anything you want after creating a file wrapper. Can't you arrange to set your own unique names?


It's not really more work, because if you're relying on the uniquing being done for you, you have to retrieve the unique name after it's generated. If you set your own names, you do that instead of the retrieval step, right?

I can definitely add my own suffix. So, going with the simple example of "Untitled", if I just set that as the preferred name, the file name'll get set to something like "2__#$!@%!#__Untitled" when the wrapper is written. If this wasn't iCloud, I could very easily just check if a file already exists with that name, and add a suffix until it's clear. something like:

var filename = preferredName
while filemanager.fileExists(atPath: basePath.appendingPathComponent(filename)) {
     filename = "preferredName \(i)"
     i++
}


But since that's not an option, I'd have to replace the fileExists call with a loop through all the child wrappers comparing against keyForChildWrapper:. That'll certainly work, but it feels wrong. I feel like I'm missing a simpler/cleaner solution.


At the moment, I'm just looking at the case of creating new empty documents, thus the "Untitled" example. And I could probably come up with a way to work around this specific case. But I do forsee this coming up again, which is why I'm looking for a more general-purpose solution.

I'm a little confused by your use case. If we're talking about documents, at the moment you open or save a document you will be given or will provide a file wrapper hierarchy for all of the files in your document package. (And when you create a new document, you'll have a starter file wrapper hierarchy.) That puts the file wrapper naming — for things you add to the hierarchy — entirely under your control, because you can find out what names are used by iterating through the file wrapper hierarchy you already have. No trip to the file system is necessary.

That's true. That's what I currently do.


private func newFileName(_ title: String?) -> String {
  let title = (title ?? "Untitled")
  var filename = title.appendingPathExtension(NoteData.documentExtension)
  var i = 1
  repeat {
    filename = "\(title) \(i)".appendingPathExtension(NoteData.documentExtension)
    i += 1
  } while self.nameConflicts(filename);

  return filename;
}

private func nameConflicts(_ filename: String) -> Bool {
  if let children = self.wrapper.fileWrappers {
    for (key,_) in children {
      if key == filename {
        return true
      }
    }
  }
  return false
}


Which certainly works. But it sure seems like a lot of extra *work*, when there's an existing mechanism to ensure that new children get non-duplicate names. But that generates exceedingly ugly filenames – I was looking for a way to get clean names and *avoid* having to iterate through all the child documents.


As for the use case – I apologize, I should've included more information. This is for a text editor that lets the user open a folder of documents. I want the user to be able to create documents (potentially untitled) without having to worry about name conflicts.

FileWrapper and duplicate children naming scheme
 
 
Q