ios - RestKit 0.20 - 发布多个对象
<p><p>我正在创建一个具有离线模式的任务应用程序。我几乎已经使用 RestKit 成功创建了在线模式。</p>
<p>在离线模式下,我将每个对象的 <code>isSync</code> 属性设置为 <code>false</code>,这样当网络可用时,我可以使用谓词获取这些未同步的对象并发布它们到服务器。</p>
<p>不幸的是,我找不到使用 RestKit 一次性将这些对象的数组<code>POST</code> 到服务器的方法。 </p>
<p>RestKit 支持这个吗?或者有没有更好的方法来使用 RestKit 实现离线支持?</p>
<p><strong>更新:</strong></p>
<p>我找到了方法<a href="https://stackoverflow.com/questions/18232620/restkit-0-20-how-to-post-get-more-than-1-managed-object-without-a-wrapper-class" rel="noreferrer noopener nofollow">here</a> ,创建具有 <code>NSArray</code> 属性的中间 <code>Entity</code> (具有自己的映射),可以 POST 到服务器。 </p>
<p>但是我有许多需要离线功能的实体(笔记、任务、评论...等),我是否必须为每个原始实体创建一个额外的中间实体? (这样每个人的响应都可以在我原来的实体中正确映射)</p>
<p><strong>更新 2:</strong></p>
<p>访问后<a href="https://github.com/RestKit/RestKit/issues/398" rel="noreferrer noopener nofollow">here</a> ,我发现现在在 RestKit 0.20.0 中支持发布多个对象的数组。但是每当我发布一组对象时,都不会向服务器发送任何参数。我就是这样做的:</p>
<pre><code>[DBTasks createTask:task attachments:nil completionHandler:^(DBTasks *task, NSError *error) {
isPosting = NO;
;
if (!error) {
KLog(@"task is %@", task); // works perfect
;
;
} else {
KLog(@"error %@", error);
}
}];
</code></pre>
<p>这是我实际发送 POST 请求的方法:</p>
<p>(只考虑 <code>else</code> 部分)</p>
<pre><code>+ (void)createTask:(DBTasks *)task attachments:(NSArray *)attachments completionHandler:(void (^)(DBTasks *, NSError *))completionHandler {
if (attachments != nil && attachments.count > 0) {
NSMutableURLRequest *request =[ multipartFormRequestWithObject:task
method:RKRequestMethodPOST
path:URL_TASKS
parameters:@{@"total_attachments": }
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
int counter = 0;
for (NSDictionary *dic in attachments) {
, 0.7)
name:", counter]
fileName:
mimeType:@"image/jpg"];
counter++;
}
}];
RKObjectRequestOperation *operation = [ managedObjectRequestOperationWithRequest:request
managedObjectContext:
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
KLog(@"success");
completionHandler((DBTasks *), nil);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
KLog(@"fail");
completionHandler(nil, error);
}];
;
}
// without attachment
else {
[ postObject:task path:URL_TASKS parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
completionHandler((DBTasks *), nil);
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
completionHandler(nil, error);
}];
}
}
</code></pre>
<p>以下是映射:</p>
<pre><code>- (RKEntityMapping *)tasksMapping {
RKEntityMapping *tasksMapping = ;
tasksMapping.setDefaultValueForMissingAttributes = NO;
tasksMapping.deletionPredicate = ;
;
tasksMapping.identificationAttributes = @[@"id"];
];
;
];
];
];
];
return tasksMapping;
}
</code></pre>
<p>POST/PUT/DELETE 使用相同的映射,但需要调用 <code>inverseMapping</code> 方法。</p>
<p>现在当我用数组调用 <code>postObject</code> 时:</p>
<pre><code> attachments:nil completionHandler:^(NSArray *array, NSError *error) {
isPosting = NO;
;
if (!error) {
KLog(@"Array of objects is %@", array);
;
;
} else {
KLog(@"error %@", error);
}
}];
</code></pre>
<p>使用几乎以前的方法:</p>
<pre><code>+ (void)createTasks:(NSArray *)tasksArray attachments:(NSArray *)attachments completionHandler:(void (^)(NSArray *, NSError *))completionHandler {
[ postObject:tasksArray path:URL_TASKS parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
completionHandler(mappingResult.array, nil);
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
completionHandler(nil, error);
}];
}
</code></pre>
<p>应用程序被终止</p>
<pre><code>2014-05-05 16:18:30.692 MyApp D restkit.object_mapping:RKMapperOperation.m:377 Executing mapping operation for representation: (
{
attachments = (
);
"completed_at" = "<null>";
"created_at" = "<null>";
deleted = 0;
"due_date" = "<null>";
from = "Stand-alone task";
id = "<null>";
note = "<null>";
owner = "<null>";
private = 0;
"send_email" = "<null>";
status = "<null>";
tags = (
);
title = "<null>";
"total_attachments" = 0;
"total_comments" = 0;
type = Task;
"updated_at" = "<null>";
url = "http://10.28.79.98:3000/workspace/tasks?open=task_";
"user_id" = 26894;
}
)
and targetObject: (null)
2014-05-05 16:18:30.693 MyApp D restkit.object_mapping:RKMapperOperation.m:297 Found mappable collection at keyPath '': (
{
attachments = (
);
"completed_at" = "<null>";
"created_at" = "<null>";
deleted = 0;
"due_date" = "<null>";
from = "Stand-alone task";
id = "<null>";
note = "<null>";
owner = "<null>";
private = 0;
"send_email" = "<null>";
status = "<null>";
tags = (
);
title = "<null>";
"total_attachments" = 0;
"total_comments" = 0;
type = Task;
"updated_at" = "<null>";
url = "http://10.28.79.98:3000/workspace/tasks?open=task_";
"user_id" = 26894;
}
)
2014-05-05 16:18:30.694 MyApp CoreData: error: Failed to call designated initializer on NSManagedObject class 'DBTasks'
2014-05-05 16:18:30.694 MyApp D restkit.object_mapping:RKMapperOperation.m:231 Asked to map source object {
attachments = (
);
"completed_at" = "<null>";
"created_at" = "<null>";
deleted = 0;
"due_date" = "<null>";
from = "Stand-alone task";
id = "<null>";
note = "<null>";
owner = "<null>";
private = 0;
"send_email" = "<null>";
status = "<null>";
tags = (
);
title = "<null>";
"total_attachments" = 0;
"total_comments" = 0;
type = Task;
"updated_at" = "<null>";
url = "http://10.28.79.98:3000/workspace/tasks?open=task_";
"user_id" = 26894;
} with mapping <RKEntityMapping:0x10598240 objectClass=DBTasks propertyMappings=(
"<RKAttributeMapping: 0x10599660 completed_at => completed_at>",
"<RKAttributeMapping: 0x10599670 created_at => created_at>",
"<RKAttributeMapping: 0x10599680 due_date => due_date>",
"<RKAttributeMapping: 0x10599690 id => id>",
"<RKAttributeMapping: 0x105996a0 note => note>",
"<RKAttributeMapping: 0x105996b0 private => private>",
"<RKAttributeMapping: 0x105996c0 send_email => send_email>",
"<RKAttributeMapping: 0x105996d0 status => status>",
"<RKAttributeMapping: 0x105996e0 title => title>",
"<RKAttributeMapping: 0x105996f0 type => type>",
"<RKAttributeMapping: 0x10599700 updated_at => updated_at>",
"<RKAttributeMapping: 0x10599710 user_id => user_id>",
"<RKAttributeMapping: 0x10599720 parent_id => parent_id>",
"<RKAttributeMapping: 0x10599730 total_attachments => total_attachments>",
"<RKAttributeMapping: 0x10599740 url => url>",
"<RKAttributeMapping: 0x10599750 from => from>",
"<RKAttributeMapping: 0x10599760 total_comments => total_comments>",
"<RKAttributeMapping: 0x10599870 deleted => shouldBeDeleted>",
"<RKRelationshipMapping: 0x1059b1c0 attachments => attachments>",
"<RKRelationshipMapping: 0x1059c5f0 owner => owner>",
"<RKRelationshipMapping: 0x1059dca0 additional_owners => additional_owners>",
"<RKRelationshipMapping: 0x105a1e00 tags => tags>"
)>
2014-05-05 16:18:30.695 MyApp D restkit.object_mapping:RKMappingOperation.m:952 Starting mapping operation...
2014-05-05 16:18:30.696 MyApp D restkit.object_mapping:RKPropertyInspector.m:130 Cached property inspection for Class 'DBTasks': {
"additional_owners" = {
isPrimitive = 0;
keyValueCodingClass = NSSet;
name = "additional_owners";
};
attachments = {
isPrimitive = 0;
keyValueCodingClass = NSSet;
name = attachments;
};
"completed_at" = {
isPrimitive = 0;
keyValueCodingClass = NSDate;
name = "completed_at";
};
"created_at" = {
isPrimitive = 0;
keyValueCodingClass = NSDate;
name = "created_at";
};
"due_date" = {
isPrimitive = 0;
keyValueCodingClass = NSDate;
name = "due_date";
};
from = {
isPrimitive = 0;
keyValueCodingClass = NSString;
name = from;
};
id = {
isPrimitive = 0;
keyValueCodingClass = NSNumber;
name = id;
};
note = {
isPrimitive = 0;
keyValueCodingClass = NSString;
name = note;
};
owner = {
isPrimitive = 0;
keyValueCodingClass = DBContacts;
name = owner;
};
"parent_id" = {
isPrimitive = 0;
keyValueCodingClass = NSNumber;
name = "parent_id";
};
private = {
isPrimitive = 0;
keyValueCodingClass = NSNumber;
name = private;
};
"send_email" = {
isPrimitive = 0;
keyValueCodingClass = NSNumber;
name = "send_email";
};
shouldBeDeleted = {
isPrimitive = 0;
keyValueCodingClass = NSNumber;
name = shouldBeDeleted;
};
status = {
isPrimitive = 0;
keyValueCodingClass = NSNumber;
name = status;
};
tags = {
isPrimitive = 0;
keyValueCodingClass = NSSet;
name = tags;
};
title = {
isPrimitive = 0;
keyValueCodingClass = NSString;
name = title;
};
topic = {
isPrimitive = 0;
keyValueCodingClass = DBTopics;
name = topic;
};
"total_attachments" = {
isPrimitive = 0;
keyValueCodingClass = NSNumber;
name = "total_attachments";
};
"total_comments" = {
isPrimitive = 0;
keyValueCodingClass = NSNumber;
name = "total_comments";
};
type = {
isPrimitive = 0;
keyValueCodingClass = NSString;
name = type;
};
"updated_at" = {
isPrimitive = 0;
keyValueCodingClass = NSDate;
name = "updated_at";
};
url = {
isPrimitive = 0;
keyValueCodingClass = NSString;
name = url;
};
"user_id" = {
isPrimitive = 0;
keyValueCodingClass = NSNumber;
name = "user_id";
};
}
2014-05-05 16:18:30.698 MyApp *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** setObjectForKey: key cannot be nil'
*** First throw call stack:
(
0 CoreFoundation 0x034721e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x02be48e5 objc_exception_throw + 44
2 CoreFoundation 0x034fbeb8 - + 888
3 MyApp 0x002dad3a __61-_block_invoke61 + 154
4 libdispatch.dylib 0x04ce17b8 _dispatch_call_block_and_release + 15
5 libdispatch.dylib 0x04cf64d0 _dispatch_client_callout + 14
6 libdispatch.dylib 0x04ce4047 _dispatch_queue_drain + 452
7 libdispatch.dylib 0x04ce3e42 _dispatch_queue_invoke + 128
8 libdispatch.dylib 0x04ce4de2 _dispatch_root_queue_drain + 78
9 libdispatch.dylib 0x04ce5127 _dispatch_worker_thread2 + 39
10libsystem_pthread.dylib 0x05025dab _pthread_wqthread + 336
11libsystem_pthread.dylib 0x05029cce start_wqthread + 30
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
</code></pre>
<p>任何建议我做错了什么?</p></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p>问题与发送数组无关,这是由于您的核心数据堆栈设置所致。你的两种情况有很大的不同。一个有效的使用魔法记录中的默认上下文。不使用对象管理器及其关联的对象存储的那个 - 似乎没有配置。</p>
<p>从代码和错误来看,发布没有附件的单个任务也应该会失败。</p>
<p>检查您的核心数据堆栈创建以及与对象管理器的关联。</p></p>
<p style="font-size: 20px;">关于ios - RestKit 0.20 - 发布多个对象,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/23380725/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/23380725/
</a>
</p>
页:
[1]