I'm trying to download a .sqlite file from my companies FTP site using AFNetworking. Each FTP user has their own folder on my server. I found this question to handle the authentication, and this question to handle the download. I believe I have meshed the two together correctly to get what I'm looking for (or atleast I'm not getting far enough to be able to test that yet). I've attached my code here anyway.

AFHTTPClient Subclass.h

#import "AFHTTPClient.h"

@interface AFNetworkingHelper : AFHTTPClient

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

+ (AFNetworkingHelper *)sharedManager;

@end

AFHTTPClient Subclass.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);
   }];

The problem I'm having is that I'm getting an NSURLErrorDomain Code=-1102 "You do not have permission to access the requested resource" when I try to run it. I have verified that the username and password I'm sending are correct. If I try to pass a path to a file that doesn't exist, I still get the -1102 error (instead of an error saying the file I requested doesn't exist, which is the error I expected to get). If I type the path from the first question I linked into a browser, I'm getting some different behavior based on which browser I use:

  • Firefox: I have to enter path without the username, with the file (so something like ftp://www.mysite.net/myfile.sqlite). When I enter this into the address bar, I get a popup asking for username and password. When I enter the correct credentials, the file download begins and completes successfully.
  • IE: I have to enter the path with username and file, (so something like ftp://www.mysite.net/myuser/myfile.sqlite). When I enter this into the address bar, I get a popup asking for username and password. When I enter the correct credentials, the file download begins and completes successfully.
  • Safari: No matter how I enter the path, I just get an error screen saying You don't have permission to open this page. I do not get a credential prompt, nor does the download ever start. If I try to enter a path to a file that doesn't exist, I still get an error saying You don't have permission to open this page (just like when I tried requesting a non-existent file in my app). UPDATE: using "USERNAME:PASSWORD@www..." syntax per @rog's comment allows me to download successfully in Safari.

I don't really understand what's going on here. Am I getting the error message from my app because it is never actually getting a credential challenge, like when I try to open it with Safari? If so, why don't I get a challenge for my credentials from my app or Safari like I do when I use the other browsers? Is there a way I can check if my app is actually trying to use the credentials I've supplied when it tries to download the file?

有帮助吗?

解决方案 2

Using the syntax @rog suggested in his comment, I was able to adapt the code from the second link in my question (concerning downloading) to allow for basic authentication, and completely eliminate the need to subclass AFHTTPClient all together. Here's the (redacted) code I used:

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];

This doesn't actually get me any closer to knowing why using the [[AFNetworkingHelper sharedManager] setUsername:@"myUsername" andPassword@"myPassword"]; failed, but on the plus side I'm getting the behavior I want from my app. I guess I can live with just that.

其他提示

FTP and HTTP are two different protocols.

Using AFHTTPClient for an FTP server is not going to work. AFNetworking only supports FTP with AFURLConnectionOperation; everything else is HTTP.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top