仅返回并导出NSManagedObject的值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了仅返回并导出NSManagedObject的值相关的知识,希望对你有一定的参考价值。
我的应用程序可以选择创建几个唯一的事件,其值保存在核心数据中。按下表格单元格时,它会加载该事件的值。我需要的是能够只将该事件信息导出到NSData,然后可以导出然后通过自定义UTI导入。下面的代码工作,除了它加载所有事件并导出数据。我怎样才能这样做,只有选择的索引路径,它的保存值,导出而不是实体中的所有事件?
-(void)exportclick:(UIButton *)sender
{
mainview.hidden = YES;
NSInteger index = exportevent.tag;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
NSManagedObject *rawRecord = [self.fetchedResultsController objectAtIndexPath:indexPath];
TSPItem *record = [TSPItem castObject:rawRecord];
CDSurveyItem *surveyItem = [CDSurveyItem castObject:rawRecord];
[self setSelection:indexPath];
NSString *eventName = nil;
if (record.eventname) {
eventName = record.eventname;
}
else if (surveyItem.eventname) {
eventName = surveyItem.eventname;
}
[self setSelection:indexPath];
if (self.selection)
{
[self exportContext:self.managedObjectContext objectmodel:record];
}
}
- (void)exportContext:(NSManagedObjectContext *)context objectmodel:(NSManagedObject *)object {
NSPersistentStoreCoordinator *coordinator = context.persistentStoreCoordinator;
NSManagedObjectModel *model = coordinator.managedObjectModel;
NSArray *entitites = [model entities];
NSMutableDictionary *data = [NSMutableDictionary dictionaryWithCapacity:[entitites count]];
for(NSEntityDescription *entity in entitites) {
@autoreleasepool {
NSArray *properties = [entity properties];
NSArray *allObjects = ({
NSFetchRequest *fetchReq = [NSFetchRequest fetchRequestWithEntityName:[entity name]];
fetchReq.includesSubentities = NO; // important
[context executeFetchRequest:fetchReq error:nil];
});
NSMutableArray *items = [NSMutableArray arrayWithCapacity:[allObjects count]];
for(object in allObjects) {
NSMutableDictionary *attrs = [NSMutableDictionary dictionaryWithCapacity:[entity.attributesByName count]];
NSMutableDictionary *relations = [NSMutableDictionary dictionaryWithCapacity:[entity.relationshipsByName count]];
for(NSPropertyDescription *property in properties) {
// attributes
if([property isKindOfClass:[NSAttributeDescription class]]) {
// types that can be directly represented in JSON
NSAttributeType attrType = [(NSAttributeDescription *)property attributeType];
id val = [object valueForKey:[property name]];
if(val == nil)
[attrs setValue:[NSNull null] forKey:[property name]];
else if(attrType < NSDateAttributeType) {
[attrs setValue:val forKey:[property name]];
}
else {
if(attrType == NSDateAttributeType) {
NSDate *dateVal = (NSDate *)val;
[attrs setValue:@{kValueKey: [NSNumber numberWithInt:[dateVal timeIntervalSinceReferenceDate]],
kClassKey:[(NSAttributeDescription *)property attributeValueClassName]}
forKey:[property name]];
}
else if(attrType == NSBinaryDataAttributeType) {
NSData *dat = (NSData *)val;
NSString *klassName = [(NSAttributeDescription *)property attributeValueClassName];
if(klassName == nil) klassName = @"NSData"; // TODO: not tested whether this is needed.
[attrs setValue:@{kValueKey:[dat base64EncodedString],
kClassKey:klassName}
forKey:[property name]];
}
else if(attrType == NSTransformableAttributeType) {
NSValueTransformer *transformer = ({
NSString *transformerName = [(NSAttributeDescription *)property valueTransformerName];
(transformerName == nil ?
[[CodingValueTransformer alloc] init] :
[NSValueTransformer valueTransformerForName:transformerName]);
});
NSData *transformed = [transformer transformedValue:val];
[attrs setValue:@{kValueKey:[transformed base64EncodedString]} // a dictionary as value without a value for kClassKey implies a transformed val
forKey:[property name]];
}
else {
NSLog(@"WARNING: Can't serialize %@ value to JSON.", [(NSAttributeDescription *)property attributeValueClassName]);
}
}
}
// relantionships
else if([property isKindOfClass:[NSRelationshipDescription class]]) {
NSRelationshipDescription *relationship = (NSRelationshipDescription *)property;
if(! [relationship isToMany]) { // to-one
NSManagedObject *targetObject = [object valueForKey:[property name]];
if(targetObject == nil) {
[relations setValue:[NSNull null] forKey:[property name]];
}
else {
NSManagedObjectID *objID = [targetObject objectID];
if([objID isTemporaryID]) {
[context obtainPermanentIDsForObjects:@[targetObject] error:nil];
objID = [object objectID];
}
NSString *objIDString = [[objID URIRepresentation] path];
[relations setValue:@{kItemKey:objIDString,
kEntityKey:[[relationship destinationEntity] name]}
forKey:[property name]];
}
}
else { // to-many
id<NSFastEnumeration> targetObjects = [object valueForKey:[property name]];
{
NSMutableArray *tempObjects = [NSMutableArray array];
for(NSManagedObject *targetObject in targetObjects) {
if([targetObject.objectID isTemporaryID])
[tempObjects addObject:targetObject];
}
if([tempObjects count] > 0)
[context obtainPermanentIDsForObjects:tempObjects error:nil];
}
NSMutableArray *targetItems = [NSMutableArray array];
for(NSManagedObject *targetObject in targetObjects) {
NSManagedObjectID *objID = [targetObject objectID];
NSString *objIDString = [[objID URIRepresentation] path];
[targetItems addObject:objIDString];
}
[relations setValue:@{kItemsKey:targetItems,
kEntityKey:[[relationship destinationEntity] name]}
forKey:[property name]];
}
}
}
NSString *objIDString = ({
NSManagedObjectID *objID = [object objectID];
if([objID isTemporaryID]) {
[context obtainPermanentIDsForObjects:@[object] error:nil];
objID = [object objectID];
}
[[objID URIRepresentation] path];
});
[items addObject:@{kObjectIDKey: objIDString,
kAttrsKey: attrs,
kRelationshipsKey: relations}];
[data setObject:items forKey:[entity name]];
[context reset]; // save memory!
}
}
}
NSData *export = [NSJSONSerialization dataWithJSONObject:data options:0 error:nil];
MFMailComposeViewController *composeVC1 = [[MFMailComposeViewController alloc] init];
composeVC1 = [[MFMailComposeViewController alloc] init];
composeVC1.mailComposeDelegate = self;
[composeVC1 setSubject:[NSString stringWithFormat:@"Settings From %@ Event", [NSString stringWithFormat:@"tester_Export"]]];
[composeVC1 setMessageBody:[NSString stringWithFormat:@"Here are the event settings. Simply press on the attachment and then choose Open in my app"] ishtml:NO];
[composeVC1 addAttachmentData:export mimeType:@"application/octet-stream" fileName:[NSString stringWithFormat:@"tester_Export.myapp"]];
[self presentViewController:composeVC1 animated:NO completion:^(void){}];
答案
您的exportclick
方法似乎具有您要导出的对象,但是在exportContext:objectModel:
中,您继续并获取每个对象。它正在导出所有内容,因为这是您的代码编写的内容。
我不确定你为什么在这里做一个获取请求。您已经拥有了要导出的对象,那么获取请求的用途是什么?你已经有了结果。您还拥有知道如何查看对象并查找要导出的数据的代码。因此,获取您拥有的对象,并获取您拥有的代码,并将两者放在一起,而无需执行新的获取请求。
以上是关于仅返回并导出NSManagedObject的值的主要内容,如果未能解决你的问题,请参考以下文章
willSave 或 validateForUpdate 中的 NSManagedObject 动态属性更新
xml 导出 php 代码仅返回 xml 文件的一个父级,我需要它们
如何更正错误“无法将 [NSManagedObject] 类型的值分配给 [String] 类型
无法将 String 类型的值转换为预期的参数类型 NSManagedObject