问题描述
在花了太多时间寻找最佳做法后,我再次要求您提供一些帮助,希望我不是唯一一个与此有关的人:
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
}
与成员实体的关系:
import Foundation
import CoreData
类成员: 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
}
我想做什么是使用NSJSONSerialization.dataWithJSONObject将我的Credential对象序列化为JSON以生成我的JSON并POST到服务器。
但是,序列化我的对象时出现错误,我相信这是因为我的对象不尊重这一点(从苹果文档):
可以转换为JSON的对象必须具有以下属性:
- 顶层对象是NSArray或NSDictionary。
- 所有对象都是NSString,NSNumber, NSArray,NSDictionary或NSNull。
- 所有字典键都是NSString的实例。
- 数字不是NaN或无穷大。
那么如何将我的对象序列化为JSON?我应该找到某种方法将会员转换为字典,然后尝试找到一种方法来设置这个字典作为我与证书的关系的值?
有我错过了处理它的内置映射器?
对不起,如果不清楚,任何帮助将是非常好的。
提前,谢谢。
Hugo
>:
如答案中所示,我试图获取字典而不是NSManagedObject,但记录的字典是空的(但是,相同的代码工作非常简单类有几个字符串属性,没有关系),这里是代码:
/ ********* **********************
TEST:Fetch字典,而不是NSManagedObject
* /
// create Credential entity
let newCredential = NSEntityDescription.insertNewObjectForEntityForName(Credential,inManagedObjectContext:self.managedObjectContext!)as! Credential
//创建凭据实体
let newMember = NSEntityDescription.insertNewObjectForEntityForName(Member,inManagedObjectContext:self.managedObjectContext!)as!会员
//实例化一些字段
newCredential.credentialId =44444
newMember.memberFirstName =TEST
//设置关系
newCredential.credentialMember = newMember
//检索currentCredential
让requestGuest = NSFetchRequest(entityName:Credential)
//获取字典NSManagedObject
requestGuest.resultType = NSFetchRequestResultType.DictionaryResultType
let fetchedGuest =(managedObjectContext!.executeFetchRequest(requestGuest,error:nil))! //不需要在这里投?
println(fetchedGuest.description)
/ ************************* **** /
没有成功与一对一和一对多的关系。所以我写了一个解析器来将托管对象转换为字典和数组。
//在xCode 6.4上测试 - Swift 1.2
让requestGuest = NSFetchRequest(entityName: Credential)
let fetchedGuest =(managedObjectContext!.executeFetchRequest(requestGuest,error:nil))!
let dataInArr:NSArray = ManagedParser.convertToArray(fetchedGuest);
NSLog(dataInArr \(dataInArr));
// -
//
// ManagedParser.swift
//由Shoaib于7/29/15创建。
//
import UIKit
import CoreData
class ManagedParser:NSObject {
class func convertToArray (managedObjects:NSArray ?, parentNode:String?= nil) - > NSArray {
var rtnArr:NSMutableArray = NSMutableArray();
// -
如果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;
让属性:[String] =(entity.propertiesByName as NSDictionary).allKeys as! [串];
// -
let parentNode:String = parentNode? managedObject.entity.name !;
for property:属性中的字符串{
if(property.caseInsensitiveCompare(parentNode)!= NSComparisonResult.OrderedSame)
{
让值:AnyObject? = managedObject.valueForKey(property);
// -
如果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
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:
- The top level object is an NSArray or NSDictionary.
- All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.
- All dictionary keys are instances of NSString.
- Numbers are not NaN or infinity.
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
这篇关于iOS-Swift:将NSManagedObject序列化为JSON(使用关系)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!