【发布时间】:2014-03-15 21:12:43
【问题描述】:
我正在尝试使用 Restkit 0.22.0 向 Web 服务发送 POST 请求。我已经设置了请求描述符和响应描述符,并且正在发送请求,但是服务器永远不会获取有效负载(或者不“知道”有效负载的结束位置),因此不会返回到我的应用程序。结果是 60 秒后服务器超时。
在设置请求描述符或请求时,我缺少一些东西。看起来,服务器要么根本没有得到任何有效载荷,要么不知道有效载荷何时结束,要么是由于 http 标头中缺少 content-length 属性,要么是由于缺少“流结束”标志。
如果我对邮递员进行同样的尝试,它会起作用。
我在 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
更新:
唷,我现在不需要后端程序员的帮助,只需将 requestSerializationMIMEType 设置为 @"text/plain" 就可以工作了。
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:@"text/plain"];
sharedManager.requestSerializationMIMEType = @"text/plain";
这显然不是一个正确的服务器设置,因为在 Restkit 框架中没有用于“文本/纯文本”的 mime 类型的常量。如果我只是将 requestSerializationMIMEType 设置为“text/plain”的“任意值”,这给我留下了一个问题,是否“坏事会发生在我身上”。现在它可以工作,但我以后会遇到新问题吗?
(非常感谢 Wain 为我指明了正确的方向并建议使用 Charles!)
【问题讨论】:
-
哦,还有一件事很重要:Web 服务托管在 Amazon AWS 服务器上
-
网络服务日志说?
-
Web 服务日志中没有错误。如果我打开服务器上的日志,我可以看到对路径“用户”的请求,没有别的。它只是看起来,因为它坐在那里并等待有效负载流入(或停止流入)
-
代替行:RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:[self responseDescriptors]];我现在使用 RKObjectRequestOperation *operation = [objectManager objectRequestOperationWithRequest: success: failure: .. 但仍然得到相同的服务器超时。如何更改 POST 有效负载的格式。显然服务器需要另一种格式
-
那是
requestSerializationMIMEType
标签: ios objective-c restkit restkit-0.20