4
votes

I have this problem. I am developing app in Swift and using RestKit to retrieve and post data back to API. However I have hit road block. If retrieved JSON payload contains some null value, the app wil crash with message:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance 0x1994faba0'

What do I do? The mapped properties are Strings.

Mapped object:

public class User: NSObject {

    public var id: Int? = 0
    public var email: String?
    public var firstName: String?
    public var lastName: String?
    public var name: String?
    public var office: String?
    public var phone: String?
    public var company: String?

}

Mapping:

let userMapping = RKObjectMapping(forClass: User.self)
userMapping.addAttributeMappingsFromDictionary([
    "id": "id",
    "email": "email",
    "first_name": "firstName",
    "last_name": "lastName",
    "name": "name",
    "company": "company",
    "phone": "phone",
    "office": "office",
])
let responseDescriptor = RKResponseDescriptor(mapping: userMapping, pathPattern: currentUserPath, keyPath: "data", statusCodes: NSIndexSet(index: 200))
objectManager.addResponseDescriptor(responseDescriptor)

JSON response:

{
  "status": "ok",
  "data": {
    "id": 1,
    "email": "[email protected]",
    "created_at": 1418832714451,
    "updated_at": 1421077902126,
    "admin": true,
    "first_name": "John",
    "last_name": "Doe",
    "company": null,
    "office": null,
    "phone": null,
    "name": "John Doe"
  }
}

It crashes on each of these: office, phone and name.

2
Show the JSON and your mapping. Improve the JSON. Add handling for NSNull to your code.Wain
I have edited my question to satisfy your request :) How do I handle NSNull myself with RestKit?Zdeněk Topič
What version are you using (it should convert to nil really)Wain
RestKit 0.24.0, Xcode 6.1.1, iOS 8.1Zdeněk Topič
If i remove company, office and phone from mapping, it works just fine.Zdeněk Topič

2 Answers

0
votes

Try to use another version of RestKit. There were changes in RestKit codebase regarding the null value bindings.

0
votes

@Hotlicks is right, nulls should be handled by the client. I believe the reason for this crash is that Restkit cannot properly introspect class property types in Swift. We solved this in our project by adding explicit targetClass to our RKObjectMapping. So, instead of using the addAttributeMappingsFromDictionary method, try:

let userMapping = RKObjectMapping(forClass: User.self)
let simpleMapping = RKAttributeMapping(fromKeyPath: "first_name", toKeyPath: "firstName")
simpleMapping.propertyValueClass = NSString.classForCoder() // we used class for coder when we did our project, but you might have success with something else.
userMapping.addPropertyMapping(simpleMapping)

You have to do the same for relationships as well, like so:

let relationshipMapping = RKRelationshipMapping(fromKeyPath: "person", toKeyPath: "person", withMapping: Person.self)
relationshipMapping.propertyValueClass = Person.classForCoder()
userMapping.addPropertyMapping(relationshipMapping)

This allows an automatic conversion from NSNull to an Swift optional.