使用 Restkit 上传图像 - 向 UITableView 添加两行而不是一行

Posted

技术标签:

【中文标题】使用 Restkit 上传图像 - 向 UITableView 添加两行而不是一行【英文标题】:Uploading image with Restkit - adding two rows to UITableView instead of one 【发布时间】:2014-07-21 04:44:13 【问题描述】:

我正在尝试将带有图像的新托管对象发布到 Web 数据库,如下所示,除了那个奇怪的小错误之外,一切对我来说都很好。当托管对象上传成功时,UITableView 会添加 2 行而不是 1 行。当我刷新 UITableView 之前添加的 UITableViewCell 之一正在填充上传的图像。当我重建应用程序时,一切正常。以前添加的托管对象正确显示,没有重复。有谁可以查看我的代码并告诉我该错误的原因是什么以及如何修复它?如果您需要更多代码,请告诉我。

 -(void)postRequest
NSEntityDescription *watchEntityDesc = [NSEntityDescription entityForName:@"Watches" inManagedObjectContext:[[RKObjectManager sharedManager]managedObjectStore].mainQueueManagedObjectContext];

Watches *watch = [[Watches alloc]initWithEntity:watchEntityDesc insertIntoManagedObjectContext:[[RKObjectManager sharedManager]managedObjectStore].mainQueueManagedObjectContext];
watch.phonewatchno = @"124512";
watch.latitude = [NSNumber numberWithDouble:-33.856870];
watch.longitude  = [NSNumber numberWithDouble:151.215279];


NSEntityDescription *wearersEntityDesc = [NSEntityDescription entityForName:@"Wearers" inManagedObjectContext:[[RKObjectManager sharedManager]managedObjectStore].mainQueueManagedObjectContext];

Wearers *wearer = [[Wearers alloc]initWithEntity:wearersEntityDesc insertIntoManagedObjectContext:[[RKObjectManager sharedManager]managedObjectStore].mainQueueManagedObjectContext];
wearer.name =_nameTextField.text,
wearer.watches =[NSSet setWithObject:watch];

RKEntityMapping *watchesMapping = [RKEntityMapping mappingForEntityForName:@"Watches" inManagedObjectStore:[[EFDateModel sharedDataModel]objectStore]];
[watchesMapping addAttributeMappingsFromDictionary:@

                                                     @"id": @"watch_id",
                                                     @"latitude":@"latitude",
                                                     @"longitude":@"longitude",
                                                     @"phonewatchno":@"phonewatchno",

                                                     
 ];

[watchesMapping addConnectionForRelationship:@"wearer" connectedBy:@
                                                                     @"wearer_id":@"wearer_id"
                                                                     ];
[watchesMapping setIdentificationAttributes:@[@"watch_id"]];

RKResponseDescriptor *responseDescr = [RKResponseDescriptor responseDescriptorWithMapping:watchesMapping method:RKRequestMethodPOST pathPattern:@"/watches.json" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];


[[RKObjectManager sharedManager]addResponseDescriptor:responseDescr];

RKEntityMapping *wearersMapping = [RKEntityMapping mappingForEntityForName:@"Wearers" inManagedObjectStore:[[EFDateModel sharedDataModel] objectStore]];

[wearersMapping addAttributeMappingsFromDictionary:@
                                                     @"id":@"wearer_id",
                                                     @"name":@"name",

                                                     
 ];
wearersMapping.identificationAttributes = @[@"wearer_id"];

[wearersMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"watch" toKeyPath:@"watches" withMapping:watchesMapping]];


RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:wearersMapping method:RKRequestMethodPOST pathPattern:@"/wearers.json" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];


RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[wearersMapping inverseMapping]  objectClass:[Wearers class] rootKeyPath:nil method:RKRequestMethodPOST ];

[[RKObjectManager sharedManager]addResponseDescriptor:responseDescriptor];
[[RKObjectManager sharedManager]addRequestDescriptor:requestDescriptor];

[[RKObjectManager sharedManager]setRequestSerializationMIMEType:RKMIMETypeJSON];
[[RKObjectManager sharedManager]setAcceptHeaderWithMIMEType:@"application/json"];




UIImage *image =[UIImage imageWithCGImage:_wearerImage.CGImage scale:0.4 orientation:UIImageOrientationUp];
NSMutableURLRequest *request = [[RKObjectManager sharedManager] multipartFormRequestWithObject:wearer method:RKRequestMethodPOST path:@"/wearers.json" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) 
    [formData appendPartWithFileData:UIImagePNGRepresentation(image)
                                name:@"wearer_photo"
                            fileName:@"photo.png"
                            mimeType:@"image/png"];
];

NSManagedObjectContext *moc =[[[RKObjectManager sharedManager]managedObjectStore]mainQueueManagedObjectContext];
RKManagedObjectRequestOperation *managedObjectOperation = [[RKObjectManager sharedManager]managedObjectRequestOperationWithRequest:request managedObjectContext:moc success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) 
    NSLog(@"Mapping result  = %@",mappingResult.array);
    [[RKObjectManager sharedManager]removeResponseDescriptor:responseDescriptor];
    [[RKObjectManager sharedManager]removeRequestDescriptor:requestDescriptor];
    [[NSNotificationCenter defaultCenter]
     postNotificationName:@"ReloadTable"
     object:self];
    [self dismissViewControllerAnimated:YES completion:nil];
 failure:^(RKObjectRequestOperation *operation, NSError *error) 
    NSLog(@"Error : \n %@",error.description);
];
[[RKObjectManager sharedManager] enqueueObjectRequestOperation:managedObjectOperation];

干杯

【问题讨论】:

【参考方案1】:

每次调用此方法时,您都会调用两次alloc]initWithEntity:... insertIntoManagedObjectContext: 并创建两个新实体实例。您可能应该将实体实例传递给它使用的此方法,而不是创建任何新实例。

此外,不断创建新描述符并添加和删除它们是低效的。如果您尝试同时发出 2 个请求,您将收到错误消息。首次使用之前配置对象管理器一次,然后重复使用它而无需重新配置。

【讨论】:

以上是关于使用 Restkit 上传图像 - 向 UITableView 添加两行而不是一行的主要内容,如果未能解决你的问题,请参考以下文章

通过 RestKit 或任何 HTTP 请求上传回形针照片

RestKit 图片上传

如何使用restkit发送具有数据和图像的多格式请求

使用 RestKIt 在核心数据实体中映射 json 对象

Tomcat 上的 HTTP/1.1 200 213 使用 RESTKit 上传 jpeg 文件

使用多部分请求将大文件上传到服务器并使用休息套件读取进度