仅返回并导出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

Swift:无法将“NSManagedObject”类型的值转换为“data Model.Entity”

为啥 insertNewObjectForEntityForName 只返回一个 NSManagedObject?