简体   繁体   English

通过iOS设备连接时无法从本地服务器获取响应

[英]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将调用失败块:

  • If invalid JSON is returned 如果返回无效的JSON
  • If the HTTP status code or content-type is incorrect 如果HTTP状态码或内容类型不正确
  • If the connection is cancelled or fails 如果连接被取消或失败

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM