1

AFNetworking を使用して、単純な iOS プロジェクトで基本的な Rails サーバーからアイテムを取得しています。

シミュレーターでリクエストを行うと、すべてがスムーズに機能します。ただし、デバイスでプロジェクトを実行しているときに同じ要求を行うと、イライラするエラーが発生します。

デバイスから直接 localhost に接続できないため、自分の IP アドレスを使用する必要があることを理解しています。これは奇妙な部分です。サーバーにリクエストを送信すると、端末でサーバーがヒットし、200 レスポンスが返されていることがわかります。ただし、リクエストは (クライアント側で) エラー メッセージ「The request timed out.」で失敗します。

情報とコード:

私のレールサーバーは非常に基本的です。基本的に、新しいプロジェクトを生成し、アイテムのコンテンツ用の単一の列 (文字列) を持つ「アイテム」と呼ばれる単純なモデルをセットアップしました。JSON リクエストにのみ応答するようにルートを設定しました。items_controller の index メソッドは、Item.all の結果を json 形式で返すだけです。

ここに私のルートがあります:

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

ここに私のitems_controller.rbがあります

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

iOS プロジェクトに関しては、ここに私の AFHTTPClient サブクラス ヘッダーがあります。

#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

そして最後に、失敗しているリクエストは次のとおりです。

- (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 サーバーに問題があるか、ローカルに接続しているデバイスに問題があると思われます。私が言ったように、私はシミュレーターからすべてをうまく行うことができ、自分のデバイスからサーバーにアクセスしていることを確認できます。

更新 1

サーバーの応答に関係なく、 -getPath:parameters:success:failure: の障害ブロックが呼び出されているようです。つまり、サーバーがエラーの json 表現を含む 422 応答をスローした場合、デバイスでエラー メッセージを取得できます。ただし、サーバーが他のjsonオブジェクトで200応答を返した場合でも、失敗ブロックがスローされます...もちろんエラーはありません。

4

1 に答える 1