我正在尝试使用Restkit 0.22.0向Web服务发送POST请求。我已经设置了请求描述符和响应描述符并且正在发送请求,但服务器永远不会获得有效负载(或者不“知道”有效负载结束的位置),因此不会返回到我的应用程序。结果是60秒后服务器超时。
在设置请求描述符或请求时,我遗漏了一些内容。似乎服务器根本没有得到任何有效载荷,或者不知道有效载荷何时结束,原因是由于http报头中缺少内容长度属性或者由于缺少“流结束”符号。
如果我和邮递员一样尝试,那就行了。
我在Xcode日志中看到的是:
2014-03-15 20:43:14.819 testIOS[52095:60b] T restkit.network:RKObjectRequestOperation.m:148 POST 'http://api.test.com:3000/0.1/user/':
request.headers={
Accept = "application/json";
"Accept-Language" = "en;q=1, fr;q=0.9, de;q=0.8, zh-Hans;q=0.7, zh-Hant;q=0.6, ja;q=0.5";
"Content-Type" = "application/json; charset=utf-8";
"User-Agent" = "testIOS/1 (iPhone Simulator; iOS 7.1; Scale/2.00)";
"X-NewRelic-ID" = "UAEBVFNWGwAEV1ZQBgM=";
}
request.body={"name":"alex"}
到目前为止看起来它是正确的,虽然我不知道,这个request.body是否正确格式化。 然后需要60秒才能在日志窗口中获得下一个输出,并出现以下错误:
2014-03-15 20:44:14.948 testIOS[52095:3707] E restkit.network:RKObjectRequestOperation.m:547 Object request failed: Underlying HTTP request operation failed with error: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0xd342700 {NSErrorFailingURLStringKey=http://api.test.com:3000/0.1/user/, NSErrorFailingURLKey=http://api.test.com:3000/0.1/user/, NSLocalizedDescription=The request timed out., NSUnderlyingError=0xd656c20 "The request timed out."}
2014-03-15 20:44:14.949 testIOS[52095:3707] E restkit.network:RKObjectRequestOperation.m:208 POST 'http://api.test.com:3000/0.1/user/' (0 / 0 objects) [request=60.1298s mapping=0.0000s total=60.1320s]:
error=Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0xd342700 {NSErrorFailingURLStringKey=http://api.test.com:3000/0.1/user/, NSErrorFailingURLKey=http://api.test.com:3000/0.1/user/, NSLocalizedDescription=The request timed out., NSUnderlyingError=0xd656c20 "The request timed out."}
response.body=(null)
2014-03-15 20:44:14.950 testIOS[52095:60b] error is: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0xd342700 {NSErrorFailingURLStringKey=http://api.test.com:3000/0.1/user/, NSErrorFailingURLKey=http://api.test.com:3000/0.1/user/, NSLocalizedDescription=The request timed out., NSUnderlyingError=0xd656c20 "The request timed out."}
以下是代码(我认为某些地方必须是错误的或缺少重要的部分):
+ (void)setupRK
{
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseURL];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[objectManager.HTTPClient setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
if (status == AFNetworkReachabilityStatusNotReachable) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No network connection"
message:@"You must be connected to the internet to use this app."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
}];
[RKObjectManager setSharedManager:objectManager];
// Log all HTTP traffic with request and response bodies
RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
}
+ (RKObjectRequestOperation *)loginRKOperationForUser:(STF_RKObj_User *)user
{
RKObjectManager *objectManager = [RKObjectManager sharedManager];
RKObjectMapping *userMapping = [STF_RKObj_User objectMapping];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:userMapping method:RKRequestMethodAny pathPattern:nil keyPath:nil statusCodes:statusCodes];
[objectManager addResponseDescriptor:responseDescriptor];
RKObjectMapping *objMapping = [STF_RKObj_User objectMapping];
RKRequestDescriptor *reqDescr = [RKRequestDescriptor requestDescriptorWithMapping:[objMapping inverseMapping] objectClass:[STF_RKObj_User class] rootKeyPath:nil method:RKRequestMethodPOST];
[objectManager addRequestDescriptor:reqDescr];
NSMutableURLRequest *request = [objectManager requestWithObject:user method:RKRequestMethodPOST path:@"user/" parameters:nil];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];
return operation;
}
然后从另一个类中调用它:
- (void)loginWithUserObject:(STF_RKObj_User *)userObj
{
RKObjectRequestOperation *operation = [STF_REST_Operations loginRKOperationForUser:userObj];
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(@"mappingResult: %@", mappingResult);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
[self logoutUser];
self.loginCallback(NO, error);
[self setLoginCallback:nil];
}];
[operation start];
}
我不能为我的生活找出我所缺少的东西。一整天都在谷歌搜索...帮助...
TIA
更新:
Phew,我只需将requestSerializationMIMEType设置为@“text / plain”,就可以在没有后端程序员帮助的情况下使用它。
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:@"text/plain"];
sharedManager.requestSerializationMIMEType = @"text/plain";
这显然无法成为正确的服务器设置,因为Restkit框架中的mime类型的“text / plain”没有常量。如果我只是将requestSerializationMIMEType设置为“text / plain”的“任意值”,这就让我想到“坏事会发生在我身上”的问题。现在它可以工作,但我以后会遇到新问题吗?
(非常感谢Wain指出我正确的方向并建议使用Charles!)
答案 0 :(得分:0)
所以为了回答我自己的问题,后端服务器设置要求我将requestSerializationMIMEType设置为@" text / plain"。
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:@"text/plain"];
sharedManager.requestSerializationMIMEType = @"text/plain";
我不确定,更好的解决方案是更改后端服务器设置,因为它似乎非常普遍,它只适用于@" text / plain"。当@" text / plain"甚至没有常量时。我将再打开另一个问题。