How to allow files uploading with WebView in Cocoa?
Asked Answered
A

2

7

WebView have a method called

- (void)webView:(WebView *)sender runOpenPanelForFileButtonWithResultListener:(id < WebOpenPanelResultListener >)resultListener

But there is almost 0 doc and details on it. Inside I display an open file dialog and get the selected file name.

Like this

- (void)webView:(WebView *)sender runOpenPanelForFileButtonWithResultListener:(id < WebOpenPanelResultListener >)resultListener
{       
    NSOpenPanel* openDlg = [NSOpenPanel openPanel];

    [openDlg setCanChooseFiles:YES];

    [openDlg setCanChooseDirectories:NO];

    // process the files.
    if ( [openDlg runModal] == NSOKButton )
    {
        NSString* fileString = [[openDlg URL]absoluteString];
        [resultListener chooseFilename:fileString]; 
    }

}

But then ?

What should I do ? On website, it show that I selected a file, but when you click on upload the website just return an error, like if no file is uploaded. Should I write the code that handle the file upload or what ?

I'm kinda lost...

Edit:

In fact I got it working.... By just alter the code from here: Cocoa webkit: how to get file upload / file system access in webkit a bit, as some part was deprecated

- (void)webView:(WebView *)sender runOpenPanelForFileButtonWithResultListener:(id < WebOpenPanelResultListener >)resultListener
{       
    // Create the File Open Dialog class.
    NSOpenPanel* openDlg = [NSOpenPanel openPanel];

    // Enable the selection of files in the dialog.
    [openDlg setCanChooseFiles:YES];

    // Enable the selection of directories in the dialog.
    [openDlg setCanChooseDirectories:NO];

    if ( [openDlg runModal] == NSOKButton )
    {
        NSArray* URLs = [openDlg URLs];
        NSMutableArray *files = [[NSMutableArray alloc]init];
        for (int i = 0; i <[URLs count]; i++) {
            NSString *filename = [[URLs objectAtIndex:i]relativePath];
            [files addObject:filename];
        }

        for(int i = 0; i < [files count]; i++ )
        {
            NSString* fileName = [files objectAtIndex:i];
            [resultListener chooseFilename:fileName]; 
        }
        [files release];
    }

}

Enjoy !

Abode answered 2/10, 2011 at 12:58 Comment(4)
What is the language you're using?Carrasquillo
Objective-c, but I got it working nowAbode
Or, post the solution as an answer, then accept your own answer (or a better one if one comes along) later.Brigadier
runOpenPanelForFileButtonWithResultListener this method not called for meMcconnell
A
8

I followed Peter Hosey comment and wow, my code is now short and works the same

- (void)webView:(WebView *)sender runOpenPanelForFileButtonWithResultListener:(id < WebOpenPanelResultListener >)resultListener
{       
    // Create the File Open Dialog class.
    NSOpenPanel* openDlg = [NSOpenPanel openPanel];

    // Enable the selection of files in the dialog.
    [openDlg setCanChooseFiles:YES];

    // Enable the selection of directories in the dialog.
    [openDlg setCanChooseDirectories:NO];

    if ( [openDlg runModal] == NSOKButton )
    {
        NSArray* files = [[openDlg URLs]valueForKey:@"relativePath"];
        [resultListener chooseFilenames:files];
    }

}
Abode answered 4/10, 2011 at 7:41 Comment(2)
runOpenPanelForFileButtonWithResultListener,this method not called for meMcconnell
@Mcconnell and anyone else with this issue, you need to connect the view to the 'UIDelegate', otherwise the function won't be called.Hyperform
B
2

There are a couple of ways your code can be improved:

  • To loop through an array, use fast enumeration instead of an index loop. It's both faster and easier to read. The only time you should use an index loop is when you really need indexes, and this is not such a situation.
  • You don't need the first loop at all. Send the URLs array a valueForKey: message, with @"relativePath" for the key. The array will ask each object (each URL) for its relativePath, collect an array of all the results, and return that for you. The code for this is a one-liner.
  • You don't need the second loop, either. The WebOpenPanelResultListener protocol added chooseFilenames: in 10.6, so you can now just send that message, once, passing the whole array to it.
Brigadier answered 2/10, 2011 at 22:1 Comment(1)
Thanks a lot, I really need to learn to use the true power of Objective-CAbode

© 2022 - 2024 — McMap. All rights reserved.