1

I have two types of files in iCloud's Docs folder:

  1. Text files
  2. Encoded files with NSCoding protocol

Both types uses .txt extension. How can I know whether a file was encoded?

Since I don't know whether a file is a text file or an encoded file, first I try to open any file as if it were encoded, hoping that any error will be caught on the open's completion handler:

var doc = MyCloudDocumentType1(fileURL: url)
doc.openWithCompletionHandler { (success: Bool) -> Void in
    if success {
        println("Doc. opened")
    }
}

When UIDocument tries to load the content of the file, I get an exception when trying to unarchive the text file:

override func loadFromContents(contents: AnyObject!, ofType typeName: String!, error outError: NSErrorPointer) -> Bool {
    if (contents as NSData).length == 0 {
        return false
    }
    NSKeyedUnarchiver.unarchiveObjectWithData(contents as NSData)
    return true
}

the exception is fired by NSKeyedUnarchiver.unarchiveObjectWithData(contents as NSData), indicating that there is an invalid argument:

'NSInvalidArgumentException', reason: '*** -[NSKeyedUnarchiver initForReadingWithData:]: incomprehensible archive

This exception makes sense, since I'm trying to decode a text file (a file that isn't encoded). The problem is that I can't catch the exception in swift, and by the time I know that the file is not an encoded one, is too late to do something.

How can I know whether a file was encoded? What's the best approach to detect if a file is encoded and thus do the encoding?

Thanks!

****** SOLUTION ******

Based on comments from @AlainCollins, I read the first 4 bytes of an encoded file as this would be my magic number:

var magicNumber = [UInt](count: 4, repeatedValue: 0)
data.getBytes(&magicNumber, length: 4 * sizeof(UInt))

Then, I compared the first 4 bytes of each file in Docs folder against this magic number.

Aнгел
  • 1,361
  • 3
  • 17
  • 32
  • Regarding why there's no try-catch in swift, here is the [link](http://stackoverflow.com/questions/24023112/try-catch-exceptions-in-swift) – Aнгел Sep 03 '14 at 18:24

1 Answers1

1

If you really want to know what format the file is in, check the magic number: http://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files

If you just want to survive the error, follow AJGM's try/catch advice.

Alain Collins
  • 16,268
  • 2
  • 32
  • 55
  • Please, may you elaborate a little more on this? – Aнгел Sep 03 '14 at 19:29
  • You can read the first few bytes of the file and match it against the list of "registered" magic numbers. For example, a zip'ed file will start with the hex digits "50 4b"; a gzip'ed file with "1f 8b". This will be more precise, if that's of use. – Alain Collins Sep 03 '14 at 19:45
  • Thanks, this point me in the right direction although I didn't know how to read only 4 bytes :P I'm posting full solution in my question. – Aнгел Sep 05 '14 at 17:21