【问题标题】:Return and export only the values of NSManagedObject仅返回和导出 NSManagedObject 的值
【发布时间】:2018-03-09 03:19:06
【问题描述】:

我的应用可以选择创建几个独特的事件,其值保存在核心数据中。当按下表格单元格时,它会加载该事件的值。我需要的是能够仅将该事件信息导出到 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){}];

【问题讨论】:

  • 你有没有尝试过,比如使用object而不是获取所有对象?
  • 在上面的代码中我不知道要更改什么来调用单个对象。

标签: objective-c core-data nsmanagedobject nsmanagedobjectcontext


【解决方案1】:

您的exportclick 方法似乎有您要导出的对象,但随后在exportContext:objectModel: 中您继续获取每个对象。它导出所有内容,因为这就是您编写代码的目的。

我不确定您为什么要在此处执行提取请求。您已经有了要导出的对象,那么获取请求的目的是什么?你已经有了结果。您还拥有知道如何查看对象并找到要导出的数据的代码。因此,获取您拥有的对象,并获取您拥有的代码,然后将两者放在一起,而无需执行新的 fetch 请求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-06
    • 1970-01-01
    • 2011-08-03
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-08
    相关资源
    最近更新 更多