Search code examples
swiftcore-datawebkitsfsafariviewcontroller

Webkit vs SFSafariViewController and Core Data


Which is the most preferred method for an in-app web browser? My app has the need to have a toolbar at the bottom, and I need to be able to take screenshots of visited web pages by hitting a button on the toolbar.

Here is what I'm running into. I want to be able to click a link in my app, open an in-app browser, take a screenshot, and save to core data along with other information about the site.

I'm able to save a screenshot to the camera roll with .takesnapshot() method for Webkit. I've been unable to save it to core data. As of last night, I've found a few functions on SO that show how to take a screenshot of the UIView and return a UIImage, but I've been unable to cast this back to Data since this is what Core Data expects for binary data. Does anyone have a good resource to save Webkit snapshots to Core Data?

In one of the functions I attempted last night, I was able to return the UIImage object, but I was unable to convert it back to Data. I can save all other data about the site to Core Data, but I'm unable to save the image - in fact, when I attempted to save the data directly with Webkit's .takesnapshot() method, the result was nil.


Solution

  • I'm going to answer your question in two parts.

    WebKit vs SFSafariViewController

    If you want to have a custom toolbar with a button for taking screenshots, I would use a UIViewController with a custom tab bar where you can add whatever buttons you want, then I would also embed a WebKit view in the view controller too. That should be pretty straightforward.

    Saving screenshot to Core Data

    By the sounds of it, you may be getting a screenshot the wrong way, you want to do so with graphics begin and end image context as follows:

    let layer = UIApplication.shared.keyWindow!.layer
    let scale = UIScreen.main.scale
    UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale)
    layer.render(in: UIGraphicsGetCurrentContext()!)
    let screenshot = UIGraphicsGetImageFromCurrentImageContext()
    

    Now you have a screenshot saved as a UIImage? in your screenshot variable. Next up you should convert this to data with:

    let data = UIImagePNGRepresentation(screenshot!)
    

    Which should give you a data representation of your image that you can then save to Core Data.