After spending too much time trying to find the best practices, here I am once again asking for some help, hoping I am not the only one struggling with this :
I have NSManaged Objects like these :
import Foundation
import CoreData
class Credential: NSManagedObject {
@NSManaged var credentialArrivalDate: String?
@NSManaged var credentialBarCode: String?
@NSManaged var credentialComment: String?
@NSManaged var credentialCountCheckIn: Int
@NSManaged var credentialCountCheckOut: Int
@NSManaged var credentialDepartureDate: String?
@NSManaged var credentialId: String?
@NSManaged var credentialIsArrived: Bool
@NSManaged var credentialIsCheckedOut: Bool
@NSManaged var credentialIsHost: Bool
@NSManaged var credentialLastModificationDate: String?
@NSManaged var credentialMemberControlled: String?
@NSManaged var credentialNumberOfPeople: Int
@NSManaged var credentialRSVP: Int
@NSManaged var credentialTypeId: String?
@NSManaged var credentialTypeName: String?
@NSManaged var credentialZoneId: String?
@NSManaged var credentialZoneName: String?
@NSManaged var credentialHosts: Set<Host>?
@NSManaged var credentialMember: Member
@NSManaged var credentialExtensionFields: Set<ExtensionFields>?
@NSManaged var credentialDeltaFirstCheckIn: String?
@NSManaged var credentialDeltaFirstCheckOut: String?
@NSManaged var credentialIsCheckedIn: Bool
}
I have a relationship with a Member Entity :
import Foundation
import CoreData
class Member: NSManagedObject {
@NSManaged var memberCompany: String
@NSManaged var memberEMail: String
@NSManaged var memberFirstName: String
@NSManaged var memberId: String
@NSManaged var memberJob: String
@NSManaged var memberLastModificationDate: String
@NSManaged var memberLastName: String
@NSManaged var memberPhoneNumber: String
@NSManaged var memberTitle: String
@NSManaged var memberCredential: Credential
}
What I am trying to do is to serialize my Credential object to JSON using NSJSONSerialization.dataWithJSONObject to generate my JSON and POST it to a Server.
However, I've got an error while serializing my object, and I believe this is because my object does not respect this (from Apple documentation) :
An object that may be converted to JSON must have the following properties:
So how can I Serialize my Object to JSON ? Should I find some way to convert a Member to a Dictionary, then try to find a way to set this dictionary as the value for my relationship with a credential ?
Have I missed a built-in mapper that handles it ?
I am sorry if that is not clear but any help would be very nice.
In advance, thank you.
Hugo
EDIT :
As suggested in an answer, I tried to fetch a dictionary instead of a NSManagedObject but the logged dictionary is empty (however, the same code worked for a very simple class with a few string attributes and no relationship), here is the code :
/*******************************
TEST : Fetch dictionary instead of NSManagedObject
*/
// create Credential entity
let newCredential = NSEntityDescription.insertNewObjectForEntityForName("Credential", inManagedObjectContext: self.managedObjectContext!) as! Credential
// create Credential entity
let newMember = NSEntityDescription.insertNewObjectForEntityForName("Member", inManagedObjectContext: self.managedObjectContext!) as! Member
// instanciate some fields
newCredential.credentialId = "44444"
newMember.memberFirstName = "TEST"
// set the relationship
newCredential.credentialMember = newMember
// retrieve currentCredential
let requestGuest = NSFetchRequest(entityName: "Credential")
// get a dictionary instead of NSManagedObject
requestGuest.resultType = NSFetchRequestResultType.DictionaryResultType
let fetchedGuest = (managedObjectContext!.executeFetchRequest(requestGuest, error:nil))! // no need to cast here ?
println(fetchedGuest.description)
/*******************************/
I tried the same but could not get succeed with one to one and one to many relationships. So I wrote a parser to convert managed objects to dictionary and array. You may use it;
//Tested on xCode 6.4 - Swift 1.2
let requestGuest = NSFetchRequest(entityName: "Credential")
let fetchedGuest = (managedObjectContext!.executeFetchRequest(requestGuest, error:nil))!
let dataInArr:NSArray = ManagedParser.convertToArray(fetchedGuest);
NSLog("dataInArr \(dataInArr)");
//--
//
// ManagedParser.swift
// Created by Shoaib on 7/29/15.
//
import UIKit
import CoreData
class ManagedParser: NSObject {
class func convertToArray(managedObjects:NSArray?, parentNode:String? = nil) -> NSArray {
var rtnArr:NSMutableArray = NSMutableArray();
if let managedObjs:[NSManagedObject] = managedObjects as? [NSManagedObject] {
for managedObject:NSManagedObject in managedObjs {
rtnArr.addObject(self.convertToDictionary(managedObject, parentNode: parentNode));
}
}
return rtnArr;
} //F.E.
class func convertToDictionary(managedObject:NSManagedObject, parentNode:String? = nil) -> NSDictionary {
var rtnDict:NSMutableDictionary = NSMutableDictionary();
let entity:NSEntityDescription = managedObject.entity;
let properties:[String] = (entity.propertiesByName as NSDictionary).allKeys as! [String];
let parentNode:String = parentNode ?? managedObject.entity.name!;
for property:String in properties {
if (property.caseInsensitiveCompare(parentNode) != NSComparisonResult.OrderedSame)
{
let value: AnyObject? = managedObject.valueForKey(property);
if let set:NSSet = value as? NSSet {
rtnDict[property] = self.convertToArray(set.allObjects, parentNode: parentNode);
} else if let vManagedObject:NSManagedObject = value as? NSManagedObject {
if (vManagedObject.entity.name != parentNode) {
rtnDict[property] = self.convertToDictionary(vManagedObject, parentNode: parentNode);
}
} else if let vData:AnyObject = value {
rtnDict[property] = vData;
}
}
}
return rtnDict;
} //F.E.
} //CLS END
You could achieve this using a third-party framework like Groot or Sync.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With