[英]Unable to get responses from local server when connecting via iOS device
Im using AFNetworking to retrieve items from a basic rails server in a simple iOS project. 我在一个简单的iOS项目中使用AFNetworking从基本的Rails服务器中检索项目。
When I make the request in the simulator, everything works smoothly. 当我在模拟器中发出请求时,一切都会顺利进行。 However, when I make the same request while running the project on my device, I'm getting a frustrating error. 但是,当我在设备上运行项目时发出相同的请求时,会遇到令人沮丧的错误。
I understand that I cannot connect to localhost directly from my device and therefore need to use my ip address, which I am doing. 我了解我无法直接从设备连接到本地主机,因此需要使用我正在执行的IP地址。 This is the weird part: when I make a request to the server, I can see in my terminal that the server was hit and is returning a 200 response. 这是很奇怪的部分:当我向服务器发出请求时,我可以在终端中看到服务器被命中并返回200响应。 However, the request is failing (on the client end) with the error message: 'The request timed out.' 但是,请求失败(在客户端),并显示错误消息:“请求超时”。
Information and code: 信息和代码:
My rails server is extremely basic. 我的Rails服务器非常基础。 I've essentially generated a new project, set up a simple model called 'items' that has a single column -- a string -- for the item's content. 实际上,我已经生成了一个新项目,建立了一个名为“ items”的简单模型,该模型只有一个列(字符串)来表示项目的内容。 I have the routes set up to only respond to JSON requests and the index method on the items_controller just returns the results of Item.all in json form. 我将路由设置为仅响应JSON请求,并且items_controller上的index方法仅以json形式返回Item.all的结果。
Here are my routes: 这是我的路线:
TestingServer::Application.routes.draw do
scope :format => true, :constraints => { :format => 'json' } do
resources :items, :only => [:index]
end
end
and here is my items_controller.rb 这是我的items_controller.rb
class ItemsController < ApplicationController
def index
@items = Item.all
render :status => 200, :json => @items
end
end
As for the iOS project, here is my AFHTTPClient subclass header: 对于iOS项目,这是我的AFHTTPClient子类标头:
#import <Foundation/Foundation.h>
#import "AFHTTPClient.h"
@interface PNAPIClient : AFHTTPClient
+ (PNAPIClient *)sharedClient;
@end
and here is its implementation: 这是它的实现:
#import "PNAPIClient.h"
#import "AFJSONRequestOperation.h"
static NSString * const kPNAPIClientBaseURLString = @"http://<ip address>:9292/";
@implementation PNAPIClient
+ (PNAPIClient *)sharedClient {
static PNAPIClient *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[PNAPIClient alloc] initWithBaseURL:[NSURL URLWithString:kPNAPIClientBaseURLString]];
});
return _sharedClient;
}
- (id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (!self) {
return nil;
}
[self registerHTTPOperationClass:[AFJSONRequestOperation class]];
[self setDefaultHeader:@"Accept" value:@"application/json"];
return self;
}
@end
And finally, here is the request that is failing: 最后,这是失败的请求:
- (IBAction)testRequest:(id)sender {
[[PNAPIClient sharedClient] getPath:@"/items.json" parameters:nil
success:^(AFHTTPRequestOperation *operation, id JSON) {
NSLog(@"success: %@", JSON);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"failure %@", error.localizedDescription);
}];
}
One last comment: I tried using a different URL (one that is online from another example) and it worked fine. 最后一个评论:我尝试使用其他URL(另一个示例在线),它工作正常。 This makes me suspect that their is either an issue with my Rails server, or that there is an issue with my device connecting to it locally. 这使我怀疑它们是我的Rails服务器出现问题,还是我的设备在本地连接到它时出现了问题。 Like I said, I am able to do everything from the simulator just fine, and can see that I am hitting the server from my device. 就像我说的那样,我能够很好地完成模拟器中的所有操作,并且可以看到我正在从设备中击中服务器。
Update 1 更新1
It appears that the failure block on the -getPath:parameters:success:failure: is being called no matter what the server response is. 看来,无论服务器响应是什么,都会调用-getPath:parameters:success:failure:上的故障块。 That is, if the server throws a 422 response with a json representation of the error, I am able to get the error message on my device. 也就是说,如果服务器抛出错误的json表示形式的422响应,则我可以在设备上获取错误消息。 However, if the server returns a 200 response with some other json object, the failure block is still thrown... with no errors of course. 但是,如果服务器使用其他json对象返回200响应,则仍然抛出失败块...当然没有错误。
AFJSONRequestOperation will call the failure block: AFJSONRequestOperation将调用失败块:
In all of these cases, the error
variable is set. 在所有这些情况下,都会设置error
变量。 In fact, it's the presence of an error
that causes the failure block to be called (see [AFJSONRequestOperation -setCompletionBlockWithSuccess:failure:]
). 实际上,是error
的存在导致了故障块的调用(请参阅[AFJSONRequestOperation -setCompletionBlockWithSuccess:failure:]
)。
If your log isn't outputting anything, try logging error
instead of error.localizedDescription
. 如果您的日志没有输出任何内容,请尝试记录error
而不是error.localizedDescription
。
Anyway, it sounds like your server is returning HTTP 200 with an invalid JSON object. 无论如何,听起来您的服务器正在返回带有无效JSON对象的HTTP 200。 You can set a breakpoint in the failure block and then type po operation.responseString
in the debugger to inspect. 您可以在故障块中设置一个断点,然后在调试器中键入po operation.responseString
进行检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.