NSURLSession Api for ftp request

Good Evening,



After that I tried my application (work well with iOS8) with Xcode 7 beta (and iOS9.0 beta 1), I received this message:

'CFReadStreamCreateWithFTPURL' is deprecated: first deprecated in iOS 9.0 - Use NSURLSessionAPI requests for ftp

I tried to find any reference 'NSURLSession', but I did not find anything on this topic. Then I also watched the video number 711 of WWD15

Can anyone help me?

Accepted Reply

Thanks for the answer but I've always read the reference I did not find nothing on the ftp.. isn't?

Replies

Thanks for the answer but I've always read the reference I did not find nothing on the ftp.. isn't?

According to the URL Loading System Programming Guide, you just feed it an ftp: // URL.

After I've read a bit of NSURLSession theory, I tried to write a small example.

#import “ExampleViewController.h"
@interface ExampleViewController () <NSURLSessionDelegate, NSURLSessionDownloadDelegate,NSURLSessionDataDelegate,NSURLSessionTaskDelegate>
@end
@implementation ExampleViewController
#pragma mark -
#pragma mark View Life Cycle
- (void)viewDidLoad {
    [super viewDidLoad];
    NSURL *url = [NSURL URLWithString:@"ftp://ftp.test.it/filedati.zip"];
    NSString * utente = @"mickey";
    NSString * codice = @"mouse";
    NSURLProtectionSpace * protectionSpace = [[NSURLProtectionSpace alloc] initWithHost:url.host port:[url.port integerValue] protocol:url.scheme realm:nil authenticationMethod:nil];

    NSURLCredential *cred = [NSURLCredential
                             credentialWithUser:utente
                             password:codice
                             persistence:NSURLCredentialPersistenceForSession];


    NSURLCredentialStorage * cred_storage ;
    [cred_storage setCredential:cred forProtectionSpace:protectionSpace];

    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    sessionConfiguration.URLCredentialStorage = cred_storage;
    sessionConfiguration.allowsCellularAccess = YES;

    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
    NSLog(@"viewdidload");

    NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:url];
    [downloadTask resume];
}
#pragma mark -
#pragma mark Session Download Delegate Methods
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(nullable NSError *)error {
    NSLog(@"errors %@",error.debugDescription);
}
- (void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didReceiveChallenge:(nonnull NSURLAuthenticationChallenge *)challenge completionHandler:(nonnull void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * __nullable))completionHandler
{
    NSLog(@“credential”);
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
    NSData *data = [NSData dataWithContentsOfURL:location];

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.progressView setHidden:YES];
        [self.imageView setImage:[UIImage imageWithData:data]];
    });
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes {
    NSLog(@"%s", __PRETTY_FUNCTION__);
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
    float progress = (double)totalBytesWritten / (double)totalBytesExpectedToWrite;
    NSLog(@"progress %f",progress);

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.progressView setProgress:progress];
    });
}
@end

Unfortunately, I get this error message

2015-06-22 20:54:07.383 Sessions[42566:6554516] viewdidload

2015-06-22 20:54:08.238 Sessions[42566:6554547] errori Error Domain=NSURLErrorDomain Code=-1102 "You do not have permission to access the requested resource." UserInfo=0x7fdcdaf2af70 {NSUnderlyingError=0x7fdcdaca4790 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1102.)", NSErrorFailingURLStringKey=ftp://ftp.test.it/filedati.zip", NSErrorFailingURLKey=ftp://ftp.test.it/filedati.zip, NSLocalizedDescription=You do not have permission to access the requested resource.}


I can not understand what's wrong

Solved it!


The issue was on this row :

  1. NSURL *url = [NSURL URLWithString:@"ftp://ftp.test.it/filedati.zip"];
  2. NSString * utente = @"mickey";
  3. NSString * codice = @"mouse";


The correct version is :

NSURL *url = [NSURL URLWithString:@"ftp://mickey:mouse@ftp.test.it/filedati.zip"];

"Unfortunely, It seems not to work NSURLSessionUploadTash with FTP (background too)

The Delegate Method "didSendBodyData" is never called!!!!


    NSURL *url_upload = [NSURL URLWithString:@"ftp://mickey:mouse@ftp.test.it/Aggiornamenti/temp.zipmouse@ftp.test.it/Aggiornamenti/temp.zip"];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url_upload];
    [request setHTTPMethod:@"PUT"];

    NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSURL *docsDirURL = [NSURL fileURLWithPath:[docsDir stringByAppendingPathComponent:@"prova.zip"]];

  NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
    sessionConfig.timeoutIntervalForRequest = 30.0;
    sessionConfig.timeoutIntervalForResource = 60.0;
    sessionConfig.allowsCellularAccess = YES;
    sessionConfig.HTTPMaximumConnectionsPerHost = 1;
    NSURLSession *upLoadSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
    NSURLSessionUploadTask *uploadTask = [upLoadSession uploadTaskWithRequest:request fromFile:docsDirURL];
[uploadTask resume];

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent
    totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend{
  
    float progress = (double)totalBytesSent / (double)totalBytesExpectedToSend;
    NSLog(@"progress %f",progress);
  
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.progressView setProgress:progress];
    });
}

not sure if it's a copy/paste issue, but your url is incorrectly entered twice in the last code you pasted. That would be a reason that the code failed.

I tried something similar using -uploadTaskWithRequest:fromData:completionHandler: and it gave me a "resource unavailable" error. When I created the resource I was trying to upload on the ftp server and tried again, it no longer gave me any error, but it did not upload anything, either.


This is on the latest iOS 9 beta running in the simulator.


Taking a wild guess, I'd say that NSURLSession supports ftp GET but not PUT, and it was trying to service the upload task using GET logic.