-1

AFNetworking を使用して、会社の FTP サイトから .sqlite ファイルをダウンロードしようとしています。各 FTP ユーザーは、サーバー上に独自のフォルダーを持っています。認証を処理するためのこの質問と、ダウンロードを処理するためのこの質問を見つけました。私は、探しているものを得るために2つを正しくメッシュ化したと信じています(または、少なくともまだテストできるほど十分には進んでいません)。とにかくここにコードを添付しました。

AFHTTPClient Subclass.h

#import "AFHTTPClient.h"

@interface AFNetworkingHelper : AFHTTPClient

- (void) setUsername:(NSString *)username andPassword:(NSString *)password;

+ (AFNetworkingHelper *)sharedManager;

@end

AFHTTPClient サブクラス.m

#import "AFNetworkingHelper.h"
@implementation AFNetworkingHelper

#pragma mark - Methods
- (void)setUsername:(NSString *)username andPassword:(NSString *)password
{
    [self clearAuthorizationHeader];
    [self setAuthorizationHeaderWithUsername:username password:password];
}

#pragma mark - Initialization
- (id) initWithBaseURL:(NSURL *)url
{
    self = [super initWithBaseURL:url];
    if (!self)
    {
        return nil;
    }

    return self;
}

#pragma mark - Singleton Methods
+ (AFNetworkingHelper *)sharedManager
{
    static dispatch_once_t pred;
    static AFNetworkingHelper *_sharedManager = nil;

    dispatch_once(&pred, ^{ _sharedManager = [[self alloc] initWithBaseURL:[NSURL URLWithString:@"ftp://www.mysite.net"]]; });
    return _sharedManager;
}

@end

ViewController.m

// Download data - AFNetworking method
[[AFNetworkingHelper sharedManager] setUsername:@"myusername" andPassword:@"mypassword"];
[[AFNetworkingHelper sharedManager] getPath:@"/myfile.sqlite" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
     NSURL *path = [[[app applicationDocumentsDirectory] URLByAppendingPathComponent:@"myfile"] URLByAppendingPathExtension:@"sqlite"];
     operation.outputStream = [NSOutputStream outputStreamWithURL:path append:NO];
     [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
     {
          NSLog(@"Successfully downloaded file to path: %@",path);
          // Update dates table to reflect that info was updated here
     }
                                     failure:^(AFHTTPRequestOperation *operation, NSError *error)
     {
           NSLog(@"Error in AFHTTPRequestOperation in clickedButtonAtIndex on myController.m");
           NSLog(@"%@",error.description);
      }];

      [operation start];
  }
                          failure:^(AFHTTPRequestOperation *operation, NSError *error)
  {
        NSLog(@"Error in AFHTTPRequestOperation in clickedButtonAtIndex on myController.m");
        NSLog(@"%@",error.description);
   }];

私が抱えている問題は、NSURLErrorDomain Code=-1102 "You do not have permission to access the requested resource"実行しようとするとエラーが発生することです。送信したユーザー名とパスワードが正しいことを確認しました。存在しないファイルへのパスを渡そうとしても、依然として -1102 エラーが発生します (要求したファイルが存在しないというエラーではなく、これは発生するはずだったエラーです)。ブラウザーにリンクした最初の質問から入力するpathと、使用しているブラウザーに基づいていくつかの異なる動作が得られます。

  • Firefox:pathユーザー名なしで、ファイル (のようなものftp://www.mysite.net/myfile.sqlite) を入力する必要があります。これをアドレス バーに入力すると、ユーザー名とパスワードを求めるポップアップが表示されます。正しい資格情報を入力すると、ファイルのダウンロードが開始され、正常に完了します。
  • IE:pathユーザー名とファイルを入力する必要があります(つまり、のようなものですftp://www.mysite.net/myuser/myfile.sqlite)。これをアドレス バーに入力すると、ユーザー名とパスワードを求めるポップアップが表示されます。正しい資格情報を入力すると、ファイルのダウンロードが開始され、正常に完了します。
  • Safari: をどのように入力してもpath、エラー画面が表示されますYou don't have permission to open this page。資格情報のプロンプトが表示されず、ダウンロードも開始されません。path存在しないファイルに入力しようとすると、まだエラーが表示されますYou don't have permission to open this page(アプリで存在しないファイルを要求しようとしたときと同じです)。更新: @rog のコメントごとに「USERNAME:PASSWORD@www...」構文を使用すると、Safari で正常にダウンロードできます。

ここで何が起こっているのかよくわかりません。アプリからエラー メッセージが表示されるのは、Safari でアプリを開こうとしたときのように、実際には資格情報のチャレンジを受けていないためですか? もしそうなら、他のブラウザーを使用するときのように、アプリや Safari から資格情報のチャレンジを受けないのはなぜですか? アプリがファイルをダウンロードしようとしたときに、指定した資格情報を実際に使用しようとしているかどうかを確認する方法はありますか?

4

2 に答える 2

1

彼のコメントで提案された構文 @rog を使用して、私の質問 (ダウンロードに関する) の 2 番目のリンクからのコードを適応させて、基本認証を許可し、AFHTTPClient をすべて一緒にサブクラス化する必要を完全に排除することができました。私が使用した(編集された)コードは次のとおりです。

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"ftp://myUsername:myPassword@www.mysite.net/myfile.sqlite"]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSURL *path = [[[app applicationDocumentsDirectory] URLByAppendingPathComponent:@"myfile"] URLByAppendingPathExtension:@"sqlite"];
operation.outputStream = [NSOutputStream outputStreamWithURL:path append:NO];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        NSLog(@"Successfully downloaded file to path: %@",path);
    }
                                 failure:^(AFHTTPRequestOperation *operation, NSError *error)
    {
        NSLog(@"Error in AFHTTPRequestOperation in clickedButtonAtIndex on FlightInfoController.m");
        NSLog(@"%@",error.description);
    }];

[operation start];

[[AFNetworkingHelper sharedManager] setUsername:@"myUsername" andPassword@"myPassword"];これは、実際には失敗した理由を知ることに近づくことはありませんが、プラス面として、アプリから必要な動作を得ています。それだけで生きていけると思います。

于 2013-05-08T16:40:59.223 に答える