title: Swift only way to prevent NSKeyedUnarchiver.decodeObject crash?
body: <p><code>NSKeyedUnarchiver.decodeObject</code> will cause a crash / <code>SIGABRT</code> if the original class is unknown. The only solution I have seen to catching this issue dates from Swift's early history and required using Objective C (also pre-dated Swift 2's implementation of <code>guard</code>, <code>throws</code>, <code>try</code> &amp; <code>catch</code>). I could figure out the Objective C route - but I would prefer to understand a Swift-only solution if possible.</p>
  
  <p>For example - the data has been encoded with <code>NSPropertyListFormat.XMLFormat_v1_0</code>. The following code will fail at <code>unarchiver.decodeObject()</code> if the class of the encoded data is unknown.</p>
  
  <pre><code>//...
  let dat = NSData(contentsOfURL: url)!
  let unarchiver = NSKeyedUnarchiver(forReadingWithData: dat)
  
  //it will crash after this if the class in the xml file is not known
  
  if let newListCollection = (unarchiver.decodeObject()) as? List {
      return newListCollection
  } else {
      return nil
  }
  //...
  </code></pre>
  
  <p>I am looking for a Swift 2 only way to test whether the data is valid before attempting <code>.decodeObject</code> - since <code>.decodeObject</code> has no <code>throws</code> - which means that <code>try</code> - <code>catch</code> does not seem to be an option in Swift (methods without <code>throws</code> cannot be wrapped AFAIK). Or else an alternative way of decoding the data which will throw an error I can catch if the decode fails. I want the user to be able to import a file from iCloud drive or Dropbox - therefore it needs to be properly validated. I cannot assume that the encoded data is safe.</p>
  
  <p>The <code>NSKeyedUnarchiver</code> methods <code>.unarchiveTopLevelObjectWithData</code> &amp; <code>.validateValue</code> both have <code>throws</code>. Is there perhaps some way that these could be used? I cannot work out how to even begin to attempt to implement <code>validateValue</code> in this context. Is this even a possible route? Or should I be looking to one of the other methods for a solution?</p>
  
  <p>Or does anyone know an alternative Swift 2 only way of addressing this issue? I believe that the key I am interested in is probably entitled <code>$classname</code> - but TBH I am out of my depth with respect to trying to work out how to implement <code>validateValue</code> - or even whether that would be the correct route to persevere with. I have the sense that I am missing something obvious.</p>
  
  <hr>
  
  <p><strong>EDIT: Here is a solution - thanks to rintaro's great answer(s) below</strong></p>
  
  <p>The initial answer solved the issue for me - i.e. implementing a delegate.</p>
  
  <p>For now however I have gone with a solution built around rintaro's additional edited response as follows:</p>
  
  <pre><code>//...
  let dat = NSData(contentsOfURL: url)!
  let unarchiver = NSKeyedUnarchiver(forReadingWithData: dat)
  
  do {
      let decodedDataObject = try unarchiver.decodeTopLevelObject()
      if let newListCollection = decodedDataObject as? List {
          return newListCollection
      } else {
          return nil
      }
  }
  catch {
      return nil
  }
  //...
  </code></pre>