Restkit POST操作服务器超时

时间:2014-03-15 21:12:44

标签: ios objective-c restkit restkit-0.20

我正在尝试使用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!)

1 个答案:

答案 0 :(得分:0)

所以为了回答我自己的问题,后端服务器设置要求我将requestSerializationMIMEType设置为@" text / plain"。

[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:@"text/plain"];
sharedManager.requestSerializationMIMEType = @"text/plain";

我不确定,更好的解决方案是更改后端服务器设置,因为它似乎非常普遍,它只适用于@" text / plain"。当@" text / plain"甚至没有常量时。我将再打开另一个问题。