Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Swift Cocoa app with WebKit: Upload picture doesn't work

I decided to make my own FB chat app that simply shows https://messenger.com on a WebView after trying other 'freemium' apps.

My ViewController.swift has just a few lines of code that loads URL on the web view

import Cocoa
import WebKit

class ViewController: NSViewController {

    @IBOutlet weak var webView: WebView!
    override func viewDidLoad() {
        super.viewDidLoad()

        let url = NSURL(string: "https://messenger.com")
        let request = NSURLRequest(URL: url!);
        webView.mainFrame.loadRequest(request);
    }

    override var representedObject: AnyObject? {
        didSet {
        // do nothing
        }
    }
}

Besides adding NSAppTransportSecurity key to info.plist to unblock HTTP traffic via HTTPS connection, I have not done any other settings.

Question

Please take a look at this image first.

Screenshot of testing app

Everything looks fine & working except two things.

  1. Uploading image does not work - I labeled as 1 in the picture.

    • normally (as in other released apps or from web browsers) if you click that icon, it shows an explorer to upload a picture like below. example of browser upload image

    • My app completely ignores user's click on that icon so I cannot upload any pictures to the chat. Interestingly, if I drag and drops the picture to the webview, it uploads fine.

  2. Shared picture does not show up - I labeled as 2 in the picture.

    • again, from other browsers or released apps, it shows the pictures that I shared with participants like below. (of course I censored the pictures) example of browser showing shared pics

    • my app tries to load the pics, but does not display them. I can see it trying to load because I see circular progress indicator while loading.

Why?

  1. I suspect that there might be a way to listen to the JavaScript that's triggered within the WebView and link to a file explorer or something like that?

  2. This I have no idea. I'm logged into Messenger (basically Facebook), so I think session is not a problem here. Maybe some jQuery loading issue??

What should I do to solve these issues?

like image 221
Saehun Sean Oh Avatar asked Nov 11 '15 00:11

Saehun Sean Oh


2 Answers

  1. There is indeed a delegate method to open a new panel called runOpenPanelForFileButtonWithResultListener, documentation here.

In the delegate method, just create a new NSOpenPanel like this:

func webView(sender: WebView!, runOpenPanelForFileButtonWithResultListener resultListener: WebOpenPanelResultListener!, allowMultipleFiles: Bool) {
    let openDialog = NSOpenPanel()
    if (openDialog.runModal() == NSOKButton) {
        let fileName: String = (openDialog.URL?.path)!
        resultListener.chooseFilename(fileName) // Use chooseFilenames for multiple files
    }
}
  1. I just tried to create a WebView from Messagers App and images are loading well.
    You should try to enable WebView options like "Autoload Images" or "Enable Animated Images" from interface builder (or by code).
like image 132
Amakh Avatar answered Dec 01 '22 22:12

Amakh


This code works for me and what is nice here is that you make the download of image asynchronous. You can find more about this concept here: http://www.raywenderlich.com/79149/grand-central-dispatch-tutorial-swift-part-1 and: http://www.raywenderlich.com/79150/grand-central-dispatch-tutorial-swift-part-2

Edited

I. You have to create new Class or a new iOS Swift File named ImageLoader with this content:

class ImageLoader {

var cache = NSCache()

class var sharedLoader : ImageLoader {
    struct Static {
        static let instance : ImageLoader = ImageLoader()
    }
    return Static.instance
}

func imageForUrl(urlString: String, completionHandler:(image: UIImage?, url: String) -> ()) {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {()in
        var data: NSData? = self.cache.objectForKey(urlString) as? NSData

        if let goodData = data {
            let image = UIImage(data: goodData)
            dispatch_async(dispatch_get_main_queue(), {() in
                completionHandler(image: image, url: urlString)
            })
            return
        }

        var downloadTask: NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: urlString)!, completionHandler: {(data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
            if (error != nil) {
                completionHandler(image: nil, url: urlString)
                return
            }

            if data != nil {
                let image = UIImage(data: data)
                self.cache.setObject(data, forKey: urlString)
                dispatch_async(dispatch_get_main_queue(), {() in
                    completionHandler(image: image, url: urlString)
                })
                return
            }

        })
        downloadTask.resume()
    })

}

}

II. In your actual viewController you call the method 'imageForUrl' from ImageLoaded following this lines of code:

ImageLoader.sharedLoader.imageForUrl("http://upload.wikimedia.org/wikipedia/en/4/43/Apple_Swift_Logo.png", completionHandler:{(image: UIImage?, url: String) in
        self.myImage.image = image!
    })

I took the code from this link: https://teamtreehouse.com/community/does-anyone-know-how-to-show-an-image-from-url-with-swift

Edited for image loaded on webview

Here is the code. It works perfect for me:

override func viewDidLoad() {
    super.viewDidLoad()
    let myWebView:UIWebView = UIWebView(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height))
    myWebView.loadRequest(NSURLRequest(URL: NSURL(string: "https://scontent-vie1-1.xx.fbcdn.net/hphotos-xap1/v/t1.0-9/12144725_10204647881668565_4367944825116750386_n.jpg?oh=5ecdae91f5258ffe0e0355e176f8eb8a&oe=56B007CA")!))
    self.view.addSubview(myWebView)
}
like image 25
Adela Toderici Avatar answered Dec 01 '22 22:12

Adela Toderici