通过iOS设备连接时无法从本地服务器获取响应 [英] Unable to get responses from local server when connecting via iOS device

查看:358
本文介绍了通过iOS设备连接时无法从本地服务器获取响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用AFNetworking从一个简单的iOS项目中的基本Rails服务器中检索项目。

Im using AFNetworking to retrieve items from a basic rails server in a simple iOS project.

当我在模拟器中发出请求时,一切都会顺利进行。但是,当我在设备上运行项目时发出相同的请求时,出现了令人沮丧的错误。

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.

我知道我无法直接从本地连接到本地主机设备,因此需要使用我正在使用的IP地址。这是很奇怪的部分:当我向服务器发出请求时,我可以在终端中看到服务器被命中并返回200响应。但是,请求失败(在客户端),并显示错误消息:请求超时。

I understand that I cannot connect to localhost directly from my device and therefore need to use my ip address, which I am doing. 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. However, the request is failing (on the client end) with the error message: 'The request timed out.'

信息和代码:

我的rails服务器非常基础。实际上,我已经生成了一个新项目,建立了一个名为 items的简单模型,该模型只有一个列-字符串-用于显示项目的内容。我已将路由设置为仅响应JSON请求,而items_controller上的index方法仅以json形式返回Item.all的结果。

My rails server is extremely basic. 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. 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.

这是我的路由:

TestingServer::Application.routes.draw do
  scope :format => true, :constraints => { :format => 'json' } do
    resources :items, :only => [:index]
  end
end

这是我的items_controller.rb

and here is my items_controller.rb

class ItemsController < ApplicationController
  def index
    @items = Item.all
    render :status => 200, :json => @items
  end
end

至于iOS项目,这是我的AFHTTPClient子类标头:

As for the iOS project, here is my AFHTTPClient subclass header:

#import <Foundation/Foundation.h>
#import "AFHTTPClient.h"
@interface PNAPIClient : AFHTTPClient
+ (PNAPIClient *)sharedClient;
@end

这是它的实现:

#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);
    }];
}

最后一条评论:我尝试使用其他URL(从另一个例子),并且效果很好。这使我怀疑它们是我的Rails服务器出现问题,还是我的设备在本地连接到它时出现了问题。就像我说的那样,我能够很好地完成模拟器中的所有操作,并且可以看到我正在从设备中访问服务器。

One last comment: I tried using a different URL (one that is online from another example) and it worked fine. 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. 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.

更新1

无论服务器响应是什么,似乎都会调用-getPath:parameters:success:failure:上的故障块。也就是说,如果服务器抛出错误的json表示形式的422响应,则我可以在设备上获取错误消息。但是,如果服务器返回带有其他json对象的200响应,则仍然抛出故障块...当然没有错误。

It appears that the failure block on the -getPath:parameters:success:failure: is being called no matter what the server response is. 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. However, if the server returns a 200 response with some other json object, the failure block is still thrown... with no errors of course.

推荐答案

AFJSONRequestOperation将调用失败块:

AFJSONRequestOperation will call the failure block:


  • 如果返回了无效的JSON

  • 如果HTTP状态代码或内容类型不正确

  • 如果连接被取消或失败

在所有这些情况下,都会设置 error 变量。实际上,是由于错误的存在而导致调用失败块的(请参见 [AFJSONRequestOperation -setCompletionBlockWithSuccess:failure:] )。

In all of these cases, the error variable is set. In fact, it's the presence of an error that causes the failure block to be called (see [AFJSONRequestOperation -setCompletionBlockWithSuccess:failure:]).

如果您的日志未输出任何内容,请尝试记录错误而不是 error.localizedDescription

If your log isn't outputting anything, try logging error instead of error.localizedDescription.

无论如何,听起来您的服务器正在返回带有无效JSON对象的HTTP 200。您可以在故障块中设置一个断点,然后在调试器中键入 po operation.responseString 进行检查。

Anyway, it sounds like your server is returning HTTP 200 with an invalid JSON object. You can set a breakpoint in the failure block and then type po operation.responseString in the debugger to inspect.

这篇关于通过iOS设备连接时无法从本地服务器获取响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆