我可以为Safari View Controller预加载Web内容吗?

时间:2016-02-01 11:40:45

标签: objective-c swift sfsafariviewcontroller

我可以毫无问题地创建Safari View Controller:

let svc = SFSafariViewController(URL: NSURL(string: remote_url)!, entersReaderIfAvailable: true)
self.presentViewController(svc, animated: true, completion: nil)

在向用户展示视图控制器之前,有什么方法可以预先加载URL吗?

例如,我可以先在后台预加载URL(网页内容),在用户点击某些内容后,我可以立即向Safari View Controller显示内容。用户会感觉页面加载更快或更快。

P.S。解决方法/黑客也是可以接受的。例如,使用缓存或在后台启动视图控制器等。

编辑:请仅考虑SFSafariViewController。

4 个答案:

答案 0 :(得分:11)

这是一个解决方案。 显然,如果你马上点击按钮,你会看到装载。 但基本上,我加载浏览器并将视图放在另一个视图后面,我在另一个视图中放了一个按钮。

当您按下按钮时,浏览器将被带到前面,已经加载。 这里唯一的问题是我没有使用任何转换,但至少是一个解决方案。

import UIKit
import SafariServices

class ViewController: UIViewController {
  var svc = SFSafariViewController(URL: NSURL(string: "https://microsoft.com/")!, entersReaderIfAvailable: true)
  var safariView:UIView?
  let containerView = UIView()
  let btn = UIButton()

  override func viewDidLoad() {
    super.viewDidLoad()
    //let tmpView = svc.view
    addChildViewController(svc)
    svc.didMoveToParentViewController(self)
    svc.view.frame = view.frame
    containerView.frame = view.frame
    containerView.backgroundColor = UIColor.redColor()
    safariView = svc.view
    view.addSubview(safariView!)
    view.addSubview(containerView)

    btn.setTitle("Webizer", forState: UIControlState.Normal)
    btn.titleLabel!.textColor = UIColor.blackColor()
    btn.addTarget(self, action: "buttonTouched:", forControlEvents: .TouchUpInside)
    btn.frame = CGRectMake(20, 50, 100, 100)
    containerView.addSubview(btn)

    view.sendSubviewToBack(safariView!)

    // Do any additional setup after loading the view, typically from a nib.
  }

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }

  @IBAction func buttonTouched(sender: AnyObject) {
    view.bringSubviewToFront(safariView!)
    //self.presentViewController(svc, animated: true, completion: nil)
  }


}

答案 1 :(得分:4)

遗憾的是,SFSafariViewController的当前实现不支持此行为。我鼓励向Apple提交雷达以增加对此行为的支持,但其他人建议您最好使用WKWebView并在添加到层次结构之前开始加载。

我遇到了一个可爱的radar from Twitter实际上提到了你要求的东西。我想您可能会发现以下请求有用:

  

高优先级:      - 能够在实际向磁盘上提供URL,URL请求,HTML数据或文件之前加热SFSafariViewController        - 目前,正在大力投资以加热高优先级推文的共享URL缓存,以便在用户点击我们的推文时   将使用预先缓存的Web打开UIWebView(遗憾的是不是WKWebView)   页。如果我们可以用一个温暖SFSafariViewController   所需的链接,这将消除我们的巨大努力   端。

你可以在他们的实现中看到他们只是使用UIWebView缓存响应,因为WKWebView似乎有点模糊了缓存语义。唯一的风险是UIWebView很可能是他们在docs&#34;在iOS 8及更高版本中运行的应用程序中看到的弃用的候选者,使用WKWebView类而不是使用UIWebView。&#34; < / p>

所以不幸的是,似乎他们需要通过很多箍来实现这一切,所以现在最好的选择就是纠缠苹果并欺骗Twitters雷达。

答案 2 :(得分:2)

您可以尝试使用http缓存,但我认为它不会起作用,因为Safari View Controller作为一个单独的进程(可能与Safari相同),所以这就是它的原因,例如规避ATS。

我能想到这个工作的唯一方法是以某种方式迫使用户的Safari加载它? openURL:或者可能会添加到阅读列表中?这听起来不是一个可行的解决方案。

您可以随时尝试自定义视图控制器的显示,将其附加到视图层次结构,触发外观事件,但将其框架设置为CGRectMake(0,0,1,1)或将其附加到屏幕外的某个位置,然后等待一段时间并表示它用正确的框架。

答案 3 :(得分:1)

您可以使用以下代码下载网页。并在svc的帮助下代表它 让数据:NSData?  做{             let weatherData = try NSData(contentsOfURL:NSURL(string:remote_url)!, options:NSDataReadingOptions()) data = weatherData             打印(weatherData)         } catch {             打印(错误)         }

并在svc

中需要时加载它