How to convert Realm object to JSON with nested NSDate properties?

I have a nested Realm Object with multiple nested NSDate properties within the nested objects. I am using this answer to transform the nested Realm Object to an NSDictionary, but I do not know how to convert that NSDictionary to actual JSON.

When I use NSJSONSerialization.dataWithJSONObject(), I get the error: 'Invalid type in JSON write (__NSTaggedDate)'

  • How retrieve an index of an NSArray using a NSPredicate?
  • Getting Image URLs in a Web Directory
  • Use of external C++ headers in Objective-C
  • Compiling external C++ library for use with iOS project
  • Swift 3 weird crashes (type inference)
  • Core Data: Error when deleting/adding objects
  • From what I understand, I must first convert the NSDate properties to NSString. The problem is I don’t know how to reach into the deeply nested objects to do this.

    This code generates the 'Invalid type in JSON write (__NSTaggedDate)' error:

        let exercises = realm.objects(ExerciseProgram).first
    
        let dic = exercises!.toDictionary()
    
        do {
            if let postData: NSData = try NSJSONSerialization.dataWithJSONObject(dic, options: NSJSONWritingOptions.PrettyPrinted) {
                let json = NSString(data: postData, encoding: NSUTF8StringEncoding)! as String
                print(json)
            }
    
        } catch let error as NSError {
            print(error)
    

    A simplified version of my object:

    final class ExerciseProgram: Object {
    
        dynamic var name: String = ""
        dynamic var startDate = NSDate()
        dynamic var userProfile: User?
        var program = List<Exercise>()
    
    }
    
    final class Exercise: Object {
    
        dynamic var name = ""
        dynamic var notes: String?
        var workoutDiary = List<Workout>()
        dynamic var goal = 0
    
    }
    
    final class Workout: Object {
    
        dynamic var date = NSDate()
        var sets = List<WorkSet>()
    
    }
    

    Solutions Collect From Internet About “How to convert Realm object to JSON with nested NSDate properties?”

    JSON Serialisation with iOS’ default serialiser is pretty strict, and most types (including NSDate) can’t be directly serialised.

    I had a look at the awesome code example Eugene posted in that question (Which looks like was actually derived from another original question). The depth of the object doesn’t seem to matter since it appears this extension was smartly set up to recursively call itself on lower levels.

    As it stands, it simply copies the NSDate value straight to the dictionary, but you could easily add another case to the conditional list there to detect any NSDate objects, and convert them to a string. This will automatically override the NSDate value that would already be in there with a string version:

    extension Object {
    func toDictionary() -> NSDictionary {
        let properties = self.objectSchema.properties.map { $0.name }
        let dictionary = self.dictionaryWithValuesForKeys(properties)
    
        let mutabledic = NSMutableDictionary()
        mutabledic.setValuesForKeysWithDictionary(dictionary)
    
        for prop in self.objectSchema.properties as [Property]! {
            // find lists
            if let nestedObject = self[prop.name] as? Object {
                mutabledic.setValue(nestedObject.toDictionary(), forKey: prop.name)
            } else if let nestedListObject = self[prop.name] as? ListBase {
                var objects = [AnyObject]()
                for index in 0..<nestedListObject._rlmArray.count  {
                    let object = nestedListObject._rlmArray[index] as AnyObject
                    objects.append(object.toDictionary())
                }
                mutabledic.setObject(objects, forKey: prop.name)
            }
            else if let dateObject = self[prop.name] as? NSDate {
                let dateString = ... ; //Perform the conversion you want here
                mutabledic.setValue(dateString, forKey: prop.name)
            }    
        }
        return mutabledic
    }
    
    }