Cannot decode object of class - ios

I am trying to send a "Class" to my Watchkit extension but I get this error.
* Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '*
-[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (MyApp.Person)
Archiving and unarchiving works fine on the iOS App but not while communicating with the watchkit extension. What's wrong?
InterfaceController.swift
let userInfo = ["method":"getData"]
WKInterfaceController.openParentApplication(userInfo,
reply: { (userInfo:[NSObject : AnyObject]!, error: NSError!) -> Void in
println(userInfo["data"]) // prints <62706c69 7374303...
if let data = userInfo["data"] as? NSData {
if let person = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? Person {
println(person.name)
}
}
})
AppDelegate.swift
func application(application: UIApplication!, handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]!,
reply: (([NSObject : AnyObject]!) -> Void)!) {
var bob = Person()
bob.name = "Bob"
bob.age = 25
reply(["data" : NSKeyedArchiver.archivedDataWithRootObject(bob)])
return
}
Person.swift
class Person : NSObject, NSCoding {
var name: String!
var age: Int!
// MARK: NSCoding
required convenience init(coder decoder: NSCoder) {
self.init()
self.name = decoder.decodeObjectForKey("name") as! String?
self.age = decoder.decodeIntegerForKey("age")
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(self.name, forKey: "name")
coder.encodeInt(Int32(self.age), forKey: "age")
}
}

According to Interacting with Objective-C APIs:
When you use the #objc(name) attribute on a Swift class, the class is made available in Objective-C without any namespacing. As a result, this attribute can also be useful when you migrate an archivable Objective-C class to Swift. Because archived objects store the name of their class in the archive, you should use the #objc(name) attribute to specify the same name as your Objective-C class so that older archives can be unarchived by your new Swift class.
By adding the annotation #objc(name), namespacing is ignored even if we are just working with Swift. Let's demonstrate. Imagine target A defines three classes:
#objc(Adam)
class Adam:NSObject {
}
#objc class Bob:NSObject {
}
class Carol:NSObject {
}
If target B calls these classes:
print("\(Adam().classForCoder)")
print("\(Bob().classForCoder)")
print("\(Carol().classForCoder)")
The output will be:
Adam
B.Bob
B.Carol
However if target A calls these classes the result will be:
Adam
A.Bob
A.Carol
To resolve your issue, just add the #objc(name) directive:
#objc(Person)
class Person : NSObject, NSCoding {
var name: String!
var age: Int!
// MARK: NSCoding
required convenience init(coder decoder: NSCoder) {
self.init()
self.name = decoder.decodeObjectForKey("name") as! String?
self.age = decoder.decodeIntegerForKey("age")
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(self.name, forKey: "name")
coder.encodeInt(Int32(self.age), forKey: "age")
}
}

I had to add the following lines after setting up the framework to make the NSKeyedUnarchiver work properly.
Before unarchiving:
NSKeyedUnarchiver.setClass(YourClassName.self, forClassName: "YourClassName")
Before archiving:
NSKeyedArchiver.setClassName("YourClassName", forClass: YourClassName.self)

NOTE: While the information in this answer is correct, the way better answer is the one below by #agy.
This is caused by the compiler creating MyApp.Person & MyAppWatchKitExtension.Person from the same class. It's usually caused by sharing the same class across two targets instead of creating a framework to share it.
Two fixes:
The proper fix is to extract Person into a framework. Both the main app & watchkit extension should use the framework and will be using the same *.Person class.
The workaround is to serialize your class into a Foundation object (like NSDictionary) before you save & pass it. The NSDictionary will be code & decodable across both the app and extension. A good way to do this is to implement the RawRepresentable protocol on Person instead.

I had a similar situation where my app used my Core framework in which I kept all model classes. E.g. I stored and retrieved UserProfile object using NSKeyedArchiver and NSKeyedUnarchiver, when I decided to move all my classes to MyApp NSKeyedUnarchiver started throwing errors because the stored objects were like Core.UserProfile and not MyApp.UserProfile as expected by the unarchiver. How I solved it was to create a subclass of NSKeyedUnarchiver and override classforClassName function:
class SKKeyedUnarchiver: NSKeyedUnarchiver {
override open func `class`(forClassName codedName: String) -> Swift.AnyClass? {
let lagacyModuleString = "Core."
if let range = codedName.range(of: lagacyModuleString), range.lowerBound.encodedOffset == 0 {
return NSClassFromString(codedName.replacingOccurrences(of: lagacyModuleString, with: ""))
}
return NSClassFromString(codedName)
}
}
Then added #objc(name) to classes which needed to be archived, as suggested in one of the answers here.
And call it like this:
if let unarchivedObject = SKKeyedUnarchiver.unarchiveObject(withFile: UserProfileServiceImplementation.archiveURL.path) as? UserProfile {
currentUserProfile = unarchivedObject
}
It worked very well.
The reason why the solution NSKeyedUnarchiver.setClass(YourClassName.self, forClassName: "YourClassName") was not for me because it doesn't work for nested objects such as when UserProfile has a var address: Address. Unarchiver will succeed with the UserProfile but will fail when it goes a level deeper to Address.
And the reason why the #objc(name) solution alone didn't do it for me was because I didn't move from OBJ-C to Swift, so the issue was not UserProfile -> MyApp.UserProfile but instead Core.UserProfile -> MyApp.UserProfile.

I started facing this after the App Name change,
The error I got was - ".....cannot decode object of class (MyOldModuleName.MyClassWhichISerialized) for key....."
This is because code by default saves Archived object with ModuleName prefix, which will not be locatable after ModuleName changes. You can identify the old Module Name from the error message class prefix, which here is  "MyOldModuleName". 
I simply used the old names to locate the old Archived objects.
So before Unarchieving add line,
NSKeyedUnarchiver.setClass(MyClassWhichISerialized.self, forClassName: "MyOldModuleName.MyClassWhichISerialized")
And before Archieving add line
NSKeyedArchiver.setClassName("MyOldModuleName.MyClassWhichISerialized", for: MyClassWhichISerialized.self)

Related

Crash when adopting NSSecureUnarchiveFromDataTransformer for a Transformable property

In iOS 12 Apple introduced NSSecureUnarchiveFromDataTransformerName for use on CoreData model entities' Transformable properties. I used to keep the Transformer Name field empty, which implicitly used NSKeyedUnarchiveFromDataTransformerName. This transformer is now deprecated, and keeping the field empty in the future will mean NSSecureUnarchiveFromDataTransformerName instead.
In iOS 13, if that field is empty, you now get a runtime warning telling you the aforementioned. I couldn't find any documentation on this anywhere, the only reference I got was a WWDC 2018 Core Data Best Practices talk which briefly mentioned what I just said.
Now I have a model with an entity which directly stores HTTPURLResponse objects in a Transformable property. It conforms to NSSecureCoding, and I checked in runtime that supportsSecureCoding is true.
Setting NSSecureUnarchiveFromDataTransformerName for the Transformer Name crashes with this message:
Object of class NSHTTPURLResponse is not among allowed top level class list (
NSArray,
NSDictionary,
NSSet,
NSString,
NSNumber,
NSDate,
NSData,
NSURL,
NSUUID,
NSNull
) with userInfo of (null)
So it sounds like Transformable properties can only be of these top level objects.
I tried subclassing the secure transformer and override the allowedTopLevelClasses property as suggested by the documentation:
#available(iOS 12.0, *)
public class NSSecureUnarchiveHTTPURLResponseFromDataTransformer: NSSecureUnarchiveFromDataTransformer {
override public class var allowedTopLevelClasses: [AnyClass] {
return [HTTPURLResponse.self]
}
}
Then I'd imagine I can create a custom transformer name, set it in the model and call setValueTransformer(_:forName:) for that name, but I couldn't find API to set the default NSKeyedUnarchiveFromDataTransformer for my custom name in case I'm on iOS 11.
Keep in mind, I'm using Xcode 11 Beta 5, but this doesn't seem to be related if I am to accept the meaning of the error I'm getting as stated.
Appreciate any thoughts.
I wrote a simple template class which makes it easy to create and register a transformer for any class that implements NSSecureCoding. It works fine for me in iOS 12 and 13, at least in my simple test using UIColor as the transformable attribute.
To use it (using UIColor as an example):
// Make UIColor adopt ValueTransforming
extension UIColor: ValueTransforming {
static var valueTransformerName: NSValueTransformerName {
.init("UIColorValueTransformer")
}
}
// Register the transformer somewhere early in app startup.
NSSecureCodingValueTransformer<UIColor>.registerTransformer()
The name of the transformer to use in the Core Data model is UIColorValueTransformer.
import Foundation
public protocol ValueTransforming: NSSecureCoding {
static var valueTransformerName: NSValueTransformerName { get }
}
public class NSSecureCodingValueTransformer<T: NSSecureCoding & NSObject>: ValueTransformer {
public override class func transformedValueClass() -> AnyClass { T.self }
public override class func allowsReverseTransformation() -> Bool { true }
public override func transformedValue(_ value: Any?) -> Any? {
guard let value = value as? T else { return nil }
return try? NSKeyedArchiver.archivedData(withRootObject: value, requiringSecureCoding: true)
}
public override func reverseTransformedValue(_ value: Any?) -> Any? {
guard let data = value as? NSData else { return nil }
let result = try? NSKeyedUnarchiver.unarchivedObject(
ofClass: T.self,
from: data as Data
)
return result
}
/// Registers the transformer by calling `ValueTransformer.setValueTransformer(_:forName:)`.
public static func registerTransformer() {
let transformer = NSSecureCodingValueTransformer<T>()
ValueTransformer.setValueTransformer(transformer, forName: T.valueTransformerName)
}
}
I tried to use NSSecureUnarchiveFromDataTransformer also (although I don't need secure coding, see below), but I did not have success. Thus I used a custom value transformer instead. My steps were:
I implemented my custom value transformer class:
#objc(MyTransformer)
class MyTransformer: ValueTransformer {
override class func setValueTransformer(_ transformer: ValueTransformer?, forName name: NSValueTransformerName) {
ValueTransformer.setValueTransformer(transformer, forName: name)
}
override func transformedValue(_ value: Any?) -> Any? {
guard let value = value else { return nil }
let data = serialize(value) // A custom function, e.g. using an NSKeyedArchiver
return data as NSData
}
override class func allowsReverseTransformation() -> Bool {
return true
}
override func reverseTransformedValue(_ value: Any?) -> Any? {
guard let value = value else { return nil }
guard let data = value as? Data else { return nil }
let set = deserialize(data) // A custom function, e.g. using an NSKeyedUnarchiver
return set as NSSet // Or as an NSArray, or whatever the app expects
}
}
extension NSValueTransformerName {
static let myTransformerName = NSValueTransformerName(rawValue: „MyTransformer")
}
The 1st line (#objc) is required, see this post! Otherwise coreData does not recognise the custom transformer!
Next, I implemented a computed property in the app delegate, according to this post:
private let transformer: Void = {
MyTransformer.setValueTransformer(MyTransformer(), forName: .myTransformerName)
}()
It is important to do this early, e.g. in the app delegate, so that coreData does recognise the transformer when it is initialised.
Eventually, I set in the attribute inspector of the transformable attribute in the xcdatamodeld file the Transformer value to MyTransformer.
Then the code run correctly without run time logs.
Please note: In my case, it was not necessary to do secure coding, but the code above can easily be modified to use secure coding instead. Just modify the functions serialize and deserialize accordingly.
EDIT (due to the comment of kas-kad below):
Sorry, my code was unfortunately not complete.
In the app delegate, I used the following computed property (see this link). This ensures that the value transformer is registered very early, even before init is run.
private let transformer : Void = {
let myTransformer = MyValueTransformer()
ValueTransformer.setValueTransformer(myTransformer, forName:NSValueTransformerName("MyValueTransformer"))
}()
And to override class func setValueTransformer does in my implementation obviously nothing. I copied it from somewhere (cannot remember). So one can surely omit it.
The extension of NSValueTransformerName does nothing more than to allow to use .myTransformerName as the transformer name.

error within custom initialiser in extension of class

Here is my sample code which brings my questions:
protocol Decodable {
init?(json: [String: AnyObject]) // remove this line will solve the problem
}
extension UIFont: Decodable { // remove `Decodable` will also solve the problem
convenience init?(json: [String: AnyObject]) { // Error: Initialiser requirement 'init(json:)' can only be satisfied by a `required` initializer in the definition of non-final class 'UIFont'
self.init(name: "whatever", size: 10)
}
}
The code above tested with Xcode 7.3 & Swift 2.2
Anyone have an idea about this error, why there is somehow a relation with protocol defined method ?

Using `InterfaceController` logic for `ComplicationController'

I'm doing an Apple Watch App, with a Complication.
I've got the WatchKit App part working great with this Ev class...
class Ev {
var evTColor:String
var evMatch:String
init(dataDictionary:Dictionary<String,String>) {
evTColor = dataDictionary["TColor"]!
evMatch = dataDictionary["Match"]!
}
class func newEv(dataDictionary:Dictionary<String,String>) -> Ev {
return Ev(dataDictionary: dataDictionary)
}
}
... and this InterfaceController
func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) {
if let tColorValue = userInfo["TColor"] as? String, let matchValue = userInfo["Match"] as? String {
receivedData.append(["TColor" : tColorValue , "Match" : matchValue])
evs.append(Ev(dataDictionary: ["TColor" : tColorValue , "Match" : matchValue]))
doTable()
} else {
print("tColorValue and matchValue are not same as dictionary value")
}
}
func doTable() {
self.rowTable.setNumberOfRows(self.evs.count, withRowType: "rows")
for (index, evt) in evs.enumerate() {
if let row = rowTable.rowControllerAtIndex(index) as? TableRowController {
row.mLabel.setText(evt.evMatch)
row.cGroup.setBackgroundColor(colorWithHexString(evt.evTColor))
} else {
print("nope")
}
}
}
I'm having a hard time getting the same sort of thing to work in my Complication, any ideas?
I'm not sure if I can just use the same Ev code for my ExtensionDelegate, and then what exactly to put in my ComplicationController.
If I use the same Ev code in my ExtensionDelegate I'm getting a fatal error: use of unimplemented initializer init().
And in my ComplicationController I'm not sure how to go about best using the data I already have from InterfaceController to fill out the getCurrentTimelineEntryForComplication &getTimelineEntriesForComplication methods in ComplicationController.
Will post any extra code as needed, thanks!
EDIT:
Per a question, my data comes from CloudKit to the iPhone App (which I then pass to the Watch App via WCSession, so my problem is accessing that data in my Watch App for my Complication)
Instead of having your InterfaceController implement and receive the WCSession messages, I would set up a singleton class that receives those messages instead. That class can parse and organize your user info data from the WCSession. That singleton class can/will be accessible in your ComplicationController and your InterfaceController
Singletons are fairly easy to setup in swift:
class DataManager : WCSessionDelegate {
// This is how you create a singleton
static let sharedInstance = DataManager()
override init() {
super.init()
if WCSession.isSupported() {
self.watchConnectivitySession?.delegate = self
self.watchConnectivitySession?.activateSession()
}
}
// This is where you would store your `Ev`s once fetched
var dataObjects = [Ev]()
// This is the method that would fetch them for you
func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) {
//parse your userInfoDictionary
self.dataObjects = evs
}
}
Then in your InterfaceController you can reference it using DataManager.sharedInstance.dataObjects to build your InterfaceController or ComplicationsController
The idea with a singleton is that you have a one global reference. DataManager only gets instantiated once and only once.

Use of undeclared type 'AppDelegate' Swift

I've just spent half a day trying to solve next problem.
I am testing the CoreData using Swift language.
Follow this tutorial everything works fine.
But after titorial I've tried to modify the structure and my code. The 'src' and groups inside it is folders, not just groups created by xCode.
NSSExpense.swift
import Foundation
import CoreData
class NSSExpense: NSManagedObject {
#NSManaged var name: String
#NSManaged var descr: String
#NSManaged var value: NSNumber
#NSManaged var isMonthly: NSNumber
#NSManaged var payDayInMonth: NSNumber
class func createInManagedObjectContext(moc: NSManagedObjectContext, name: String, value: Double, payDayInMonth: Int16, isMonthly: Bool, descr: String!) -> NSSExpense {
let newExpense = NSEntityDescription.insertNewObjectForEntityForName("NSSExpense", inManagedObjectContext: moc) as NSSExpense
newExpense.name = name
newExpense.value = NSNumber(double: value)
newExpense.payDayInMonth = NSNumber(short: payDayInMonth)
newExpense.isMonthly = NSNumber(bool: isMonthly)
if let expenseDesctiption = descr {
newExpense.descr = expenseDesctiption
} else {
newExpense.descr = ""
}
return newExpense
}
}
NSSDataManager.swift
import UIKit
import CoreData
class NSSDataManager: NSObject {
class var sharedDataManager: NSSDataManager {
struct Static {
static var instance: NSSDataManager?
static var token: dispatch_once_t = 0
}
dispatch_once(&Static.token) {
Static.instance = NSSDataManager()
}
return Static.instance!
}
lazy var managedObjectContext : NSManagedObjectContext? = {
// Error at the next line "Use of undeclared type 'NSSAppDelegate'"
let appDelegate = UIApplication.sharedApplication().delegate as NSSAppDelegate
if let managedObjectContext = appDelegate.managedObjectContext {
return managedObjectContext
} else {
return nil
}
}()
var expensesInMemory : [NSSExpense] {
get {
let fetchRequest = NSFetchRequest(entityName: "NSSExpense")
if let fetchResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [NSSExpense] {
return fetchResults
} else {
return [NSSExpense]()
}
}
}
func addExpenseWithName(name: String, value: Double, payDayInMonth: Int16, isMonthly: Bool, descr: String!) -> NSSExpense {
return NSSExpense.createInManagedObjectContext(managedObjectContext!, name: name, value: value, payDayInMonth: payDayInMonth, isMonthly: isMonthly, descr: descr?)
}
}
I've tried to solve this problem different ways:
1) Create new project (Swift main language) and make the same structure again (failed)
2) Create new project (Objective-C main language). So I have the AppDelegate.h and AppDelegate.m. Add it to Swift files using Bridging-Header. The same problem. (failed)
Really interesting next thing. If I put next code to the ViewController.swift which creates automatically with new project everything works fine. But when I put this code to any other class. I've code this error.
lazy var managedObjectContext : NSManagedObjectContext? = {
// Error at the next line "Use of undeclared type 'NSSAppDelegate'"
let appDelegate = UIApplication.sharedApplication().delegate as NSSAppDelegate
if let managedObjectContext = appDelegate.managedObjectContext {
return managedObjectContext
} else {
return nil
}
}()
[UPDATE 1]
I've tried to create another class right at the same folder as NSSAppDelegate.swift and now everything works fine. However it's still an issue, how can I use the classes which stored in other folders?
[UPDATE 2]
Just tried to do the same thing in other project.
If the file structure is like this so the AppDelegate.swift and NGDataManager.swift are in the same folder everything works great.
BUT, if I put the NGDataManager.swift inside the 'src' folder like this (not just group, folder) the error occurs. May be I should create the other question for this.
[UPDATE 3]
I don't know how, but you can forget all I've said in UDATE 2. Because Now thats all not work. I even create a new project with CoreData named "Test" and just create a new class named "TestClass". The magic is in the next thing: if I put this code inside the TestClass.swift
import UIKit
class TestClass: NSObject {
func someFunc() {
let appDel = UIApplication.sharedApplication().delegate as AppDelegate
}
}
the error occurs. But if I put this line in viewDidLoad in ViewController.swift which was generated automatically by xCode
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let appDel = UIApplication.sharedApplication().delegate as AppDelegate
}
}
their is no error and everything works great. I don't know what to say...
You may see the AppDelegate code here but I didn't modify anything generated automatically by xCode. I've created a Single View Application with this settings.
Chances are when you created your project you also created a '{ProjectName}Tests' target. The problem is AppDelegate is not assigned membership in the '{ProjectName}Tests' target.
Select AppDelegate.swift then in the right-hand inspector click on the File Inspector (the paper icon) then make sure in the "Target Membership" both your project and the test target checkmarks are set to ON.
Clean, rebuild.
If trying to access an Objective-C AppDelegate in Swift code, make sure you have #import "AppDelegate.h" in your bridging header file.
This had me stuck for about an hour :-/
I had a similar problem that was resolved when I did a "Clean" option in the Product menu
Ran into this issue in Xcode 8 and this was the first result when I searched on google so adding my solution.
If your project has UI and Unit Tests, make sure your AppDelegate is added to both target memberships. Once I added it to my Tests I was able to access any variables I had in my AppDelegate without having to use UIApplication.shared regardless of how my files were grouped.
To check, go to your AppDelegate, click on the file inspector, and look at Target Membership.
Make sure the Target Memberships are set the same in each file. Target memberships can be found in the properties inspector when you click on a specific file.
It suppose to be like this.
let appDelegate: AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
Instead of:
let appDelegate = UIApplication.sharedApplication().delegate as NSSAppDelegate
try:
let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate

Why am I getting "Swift Dynamic Cast Failed" ?? :/

I was wondering if someone could explain the concept of "cast" or "casting" to me regarding programming and also help me with the issue of getting "Swift dynamic cast failed" when trying to execute this code:
import UIKit
import CoreData
class vcMain: UIViewController {
#IBOutlet var txtUsername: UITextField!
#IBOutlet var txtPassword: UITextField!
#IBAction func btnSave(){
//println("Save button pressed \(txtUsername.text)")//Adds the text written, in the console
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext
var newUser = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) as NSManagedObjectContext
newUser.setValue("Test Username", forKey: "username")
newUser.setValue("Test Password", forKey: "password")
context.save(nil)
println(newUser)
println("Object Saved.")
}
#IBAction func btnLoad(){
//println("Load button pressed \(txtPassword.text)")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I'm following a tutorial on YouTube but cant figure out why its not working for me!
This line looks wrong:
var newUser = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) as NSManagedObjectContext
You're casting to a NSManagedObjectContext when you probably meant to cast to a NSManagedObject, so the line should be:
var newUser = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) as NSManagedObject
I agree with Jack Lawrence's answer.
We are looking at the function NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) which, from the documentation, will return a objC type, id, which kinda translates to Swift as an AnyObject. This is to say the computer doesn't know what it is, but we do, because we read the documentation:
insertNewObjectForEntityForName:inManagedObjectContext:
Creates, configures, and returns an instance of the class for the entity with a given name.
Return Value
A new, autoreleased, fully configured instance of the class for the entity named entityName. The instance has its entity description set and is inserted it into context.
Anyway, you can be safe to assume it is returning a type NSManagedObject, or some subclass of it.
Now about casting:
Most of this is from the Swift iBook. So you already know that type casting / downcasting in swift is done by the as operator. Because downcasting can fail, the type cast operator comes in two forms. 1) Forced as and 2) Optional as?
Basically the differnce is, use as? when you are not sure if the downcast will succeed, and use as when you are certain it will. Here is an example, where I have an array of type AnyObject called Vehicles..., which contains two different classes, Car and Truck, of which there are 5 cars and 2 trucks.
var carCount = 0
var truckCount = 0
for vehicle in vehicles{
if let car = car as? Car
{
carCount++
} else
if let truck = truck as? Truck
{
truckCount++
}
}
At the end of this my counts are correct, and I have not thrown an error. But, trying to access any one of the elements of vehicles, like vehicles[i] as Car would be dangerous, because it might be a truck, and you are forcefully saying that it is a car. Runtime error!
Anyway I hope that explains it a bit. If not, check out the chapter on type casting in the Swift iBook, page 391.
For anyone else out there with a similar problem. There is a little gotcha here.
If you are trying to generate a custom NSManagedObject subclass using the NSEntityDescription.insertNewObjectForEntityForName(Entity, inManagedObjectContext: context) method, then make sure that the swift class has the #objc() header added to the class. Otherwise you'll encounter a dynamic class cast failure also.

Resources