RestKit 超时被忽略

Posted

技术标签:

【中文标题】RestKit 超时被忽略【英文标题】:RestKit Timeout Being ignored 【发布时间】:2012-06-12 12:58:32 【问题描述】:

我正在从我的 ios 应用程序调用网络服务,这可能需要四分钟才能返回。我正在使用 RestKit 来调用和加载对象。我发现当请求需要很长时间时,我会在大约 60 秒后收到超时错误。我尝试将 timeoutInterval 设置为荒谬的数量,但它仍然在 ~60 之后超时。

RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:HOSTNAME];

objectManager.client.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
objectManager.client.disableCertificateValidation = YES;

//timeout
objectManager.client.timeoutInterval = 1000;

这是对服务的调用:

- (void)loadData 


NSString *uid = [self retrieveFromUserDefaults:@"login_preference"];
NSString *pwd = [self retrieveFromUserDefaults:@"password_preference"];

if([uid isEqualToString:@""] || [pwd isEqualToString:@""])
    [self stopSpinner];
    [self enableUserInterface:YES];
    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Missing Settings" 
                                                    message:@"Please enter your login information in the settings."
                                                   delegate:nil 
                                          cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    return;




RKObjectManager* objectManager = [RKObjectManager sharedManager];
NSDictionary *params = [NSDictionary dictionaryWithObjects: 
                        [NSArray arrayWithObjects:uid, pwd, nil] 
                                                   forKeys:[NSArray arrayWithObjects:@"uid", @"pwd", nil]]; 

// Load the object model via RestKit    
[objectManager loadObjectsAtResourcePath:[@"/synchData" appendQueryParams:params] delegate:self];

我正在后台线程中调用 Web 服务 - 该设计中是否存在可能导致问题的东西?我无法想象什么,比如 iOS 不允许后台线程运行超过 60 秒?我只是不知道是什么问题。

超时是从服务器获得响应所需的时间,还是从服务器获得整个响应所需的时间?我正在返回一个可能非常大的 json 响应 - 我需要在超时限制内返回整个内容,还是只需要在限制内从服务器获取任何响应?

【问题讨论】:

向我们展示您如何发送请求。超时是你的应用程序等待它得到任何响应的时间,你不需要在这段时间内返回整个东西。 谢谢 - 我加了一点,你是这个意思吗?我仔细检查了一下,无论我的超时间隔是多少,它都会在 60 秒后死亡。 是的,这就是我的意思。我看不出你的代码有什么问题,你如何捕捉超时? RestKit 文档说默认超时设置为 120 秒,并且该超时函数 will return an RKRequestConnectionTimeoutError via didFailLoadWithError:,因此如果您在 requestDidTimeout: 中捕获它,则有可能其他机制调用它。您可能希望在捕获超时的方法中放置一个调试器并检查调用堆栈以找出导致超时的确切原因,也许这将帮助您确定 60s 值的来源。 我在 didFailWithError 中发现了它。我从来没有得到 requestDidTimeout 因为我的 RKRequestBackgroundPolicy 是 None 从来没有从 RestKit 调用过。我想我在调试方面很糟糕,因为当我进入我的 didFailWithError 时,我在堆栈中找不到任何东西来说明导致它死亡的原因。 您能确认您使用的是最新版本吗?按照这个pull request这个问题应该已经解决了 【参考方案1】:

如果我了解您的问题,解决方案是:

- (void)request:(RKRequest *)request didFailLoadWithError:(NSError *)error

所以当你遇到超时时间问题时,就会被这个方法捕捉到。

【讨论】:

【参考方案2】:

我遇到了类似的问题,委托方法requestDidTimeout:(RKRequest*)request 从未被调用过。不管我是在 RKRequest 还是 RKClient 上设置超时。

警告: 在请求上设置超时时,我看到请求不遵守设置的超时 除非我也打电话给[requestObject createTimeOutTimer]

但是,我在您的实现中注意到的是,您使用 1000 表示 NSTimeInterval:您的意思是 1000 秒用于超时吗?如果您的意思是一秒 = 1000 毫秒,请更改为 1。

RestKit 的默认超时是 120 秒,所以很可能这是 NSURLConnection 超时。

【讨论】:

【参考方案3】:

长期以来,Restkit 库(版本 ~= .4)仅支持在单个位置添加 timeoutInterval

/**
An optional timeout interval within which the request should be cancelled.
This is passed along to RKRequest if set.  If it isn't set, it will default
to RKRequest's default timeoutInterval.
*Default*: Falls through to RKRequest's timeoutInterval
*/
@property (nonatomic, assign) NSTimeInterval timeoutInterval;

在 RKResponseLoader.h 中

/**
The timeout interval, in seconds, to wait for a response to load.
The default value is 4 seconds.
@see [RKTestResponseLoader waitForResponse]
*/
@property (nonatomic, assign) NSTimeInterval timeout;

【讨论】:

以上是关于RestKit 超时被忽略的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 restkit 忽略已发布对象上的空属性

在 iOS 的 RestKit 中执行 postObject 时忽略响应

Restkit如何将任意json(键可能会超时更改)映射到NSDictionary

如何过早取消 RestKit 中的请求并调用“didFailWithError”

RestKit valueTransformer 未被调用

restkit 映射嵌套数组为空(带有 json 响应的嵌套 restkit 请求)