Domanda

I'm trying to work with FTP Servers. I have googled around for everything and everything is hard to understand for beginners like me. SimpleFTPSample is hard to understand because it is so much at a time. views, buttons, labels, textflelds, upload, download, request, list, get. Same with BlackRaccoon and everything else.

How to Simply and programily upload "test.txt" to FTP Server: "192.168.1.111" in Xcode (iPhone app) without views or button. Just code that can be in the ViewDidLoad for example.

Maybe something like this?:

NSURL* url = [NSURL URLWithString:@"ftp://username:pw@189.92.32.34"];
CFReadStreamRef stream = CFReadStreamCreateWithFTPURL(NULL, (__bridge CFURLRef) url);
stream.delegate= self;
[stream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[stream open];

but which file? expand this, or write a new code. i don't know, this is new for me.

Thanks Jonathan

È stato utile?

Soluzione

As the writer of Black Raccoon perhaps I'm biased (well, I KNOW I'm biased), but I've attempted to make it as simple and powerful as possible. Let's look at what you want to do, upload a file:

There are four things we need to upload a file - start up code, then four delegate methods: overwrite check, data, success and the fail. Let's assume that you read the entire file into memory (okay for small files less than 2 megs).

First, you need this in your header:

    BRRequestUpload *uploadData;  // Black Raccoon's upload object
    NSData *uploadData;           // data we plan to upload

Now for the code part:

- (IBAction) uploadFile :(id)sender
{
    //----- get the file path for the item we want to upload
    NSString *applicationDocumentsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *filepath = [NSString stringWithFormat: @"%@/%@", applicationDocumentsDir, @"file.text"];

    //----- read the entire file into memory (small files only)
    uploadData = [NSData dataWithContentsOfFile: filepath];

    //----- create our upload object
    uploadFile = [[BRRequestUpload alloc] initWithDelegate: self];

    //----- for anonymous login just leave the username and password nil 
    uploadFile.path = @"/home/user/myfile.txt";     
    uploadFile.hostname = @"192.168.1.100";
    uploadFile.username = @"yourusername";
    uploadFile.password = @"yourpassword";

    //----- we start the request
    [uploadFile start];
}

The first will be asking your code if you want to overwrite an existing file.

-(BOOL) shouldOverwriteFileWithRequest: (BRRequest *) request
{
    //----- set this as appropriate if you want the file to be overwritten
    if (request == uploadFile)
    {
        //----- if uploading a file, we set it to YES (if set to NO, nothing happens)
        return YES;
    }
}

Next, Black Raccoon will ask you for chunks of data to send. If you have a very large file you NEVER want to try to send it all in one shot - Apple's API will choke and drop data. However, we only have one small chunk so we do this:

- (NSData *) requestDataToSend: (BRRequestUpload *) request
{
    //----- returns data object or nil when complete
    //----- basically, first time we return the pointer to the NSData.
    //----- and BR will upload the data.
    //----- Second time we return nil which means no more data to send
    NSData *temp = uploadData;   // this is a shallow copy of the pointer

    uploadData = nil;            // next time around, return nil...

    return temp;
}

Remember we can ONLY do this for a small file.

Next we have our completion handler (if things worked according to plan):

-(void) requestCompleted: (BRRequest *) request
{
    if (request == uploadFile)
    {
        NSLog(@"%@ completed!", request);
        uploadFile = nil;
    }
}

Lastly we have our failure handler:

-(void) requestFailed:(BRRequest *) request
{
    if (request == uploadFile)
    {
        NSLog(@"%@", request.error.message);
        uploadFile = nil;
    }
}

It would be WONDERFUL if it was as simple as saying [BRFtpUploadTo: dest srcfile: srcFile destfile: dstFile] but there are many reasons why you SHOULDN'T. Part of it has to do with how Apple has implemented their internal FTP. There are also the issues of blocking, errors, etc. In the end, FTP sounds like it should be trivial but ends up being a bit of a nightmare.

FTP is non-trivial which is why there are so many implementations. I'm not arguing that Black Raccoon is the best, but it is maintained with response to issues being between minutes to a couple of days.

It may look daunting at first, but Black Raccoon is, in my opinion, one of the better FTP libraries. I've spent a lot of time and effort to make it a quality product with excellent response to issues. How do I do this for free? Volume. ;)

Good luck with whatever FTP software you end up with!

Altri suggerimenti

  1. Upload path is required when uploading. That is the way FTP works.

  2. The port is the standard FTP port. I know of no way to change this without violating the API. If you figure it out, you stand a good chance of not passing Apple's check.

  3. This code will upload/download any file.

  4. I do not know how to make this work under secure conditions. This uses Apple's FTP protocol. There are other FTP packages that have built this from scratch and are far more intelligent. I would look into them.

BR was designed because I needed simple FTP communication. White Raccoon didn't do this for me because at the time (it has since been modernized).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top