如何防止 WKWebView 对象崩溃?

2024-01-01

Scenario

我正在用 Swift 构建一个 iOS 应用程序。其中一项功能是将实时视频源作为应用程序背景。视频源源自本地网络上的 Raspberry Pi,使用sudo motion。 Motion 已成功在默认端口上托管源8081.

Swift 应用程序有一个WKWebView对象的源指向我的 Raspberry Pi 的运动端口。

疑似问题

端口网页8081不断刷新以从相机加载最新的帧。

Problem

运行应用程序时,提要成功连接并加载第一帧,偶尔会加载第二帧,但随后会中断。

有几次我在终端中收到以下错误:[ProcessSuspension] 0x282022a80 - ProcessAssertion() Unable to acquire assertion for process with PID 0让我相信这是一个与网页不断刷新性质相关的内存管理问题。

当前配置

目前,我对 .load() 的调用WKWebView对象位于ViewController.swift > override func viewDidLoad().

拟议决议

我是否需要构建某种形式的循环结构,在其中加载帧,暂停执行,然后调用WKWebView几秒钟后重新加载新帧。

我对 Swift 很陌生,所以非常感谢您对我的问题格式的耐心。


WkWebView 和动作加载在 iOS 11 版本的 Xcode 9 中工作,但似乎不再在 iOS 12 中工作。你是对的,webkit 在第二张图像上崩溃了​​。

由于您是 Swift 新手,我建议您阅读有关代表的链接,因为我提供的这个解决方案对您来说更有意义。快速代表 https://medium.com/@jamesrochabrun/implementing-delegates-in-swift-step-by-step-d3211cbac3ef总之,“委托是一种设计模式,允许一个对象在特定事件发生时向另一个对象发送消息。”

通过这个解决方案/黑客,我们将使用几个 WKNavigationDelegates 来通知我们 WkWebView 何时执行特定任务,并将我们的解决方案注入到问题中。您可以在此处找到 WKWebKit 拥有的所有委托WK导航代表 https://developer.apple.com/documentation/webkit/wknavigationdelegate.

下面的代码可以在一个全新的iOS项目中使用并替换ViewController.swift中的代码。它不需要接口生成器或 IBOutlet 连接。它将在视图上创建单个 Web 视图并指向地址 192.168.2.75:6789。我添加了内联注释来尝试解释代码的作用。

  1. 我们在decidePolicyFor navigationResponse 委托中从运动中加载HTTP 响应两次,并使用计数器进行跟踪。我留下了一些打印声明,以便您可以看到响应是什么。第一个是标题,第二个是图像信息。
  2. 当我们的计数器达到 3 个项目(即第二张图像)时,我们将强制 wkWebView 取消decidePolicyFor navigationResponse 委托中的所有导航(即停止加载)。请参阅带有 DecisionHandler(.cancel) 的行。这就是阻止崩溃的原因。
  3. 这导致我们接收来自 wkwebview 委托 WebView didFail 导航的回调。此时我们要再次加载 Motion/pi url 并再次开始加载过程。
  4. 然后我们必须重置计数器,以便我们可以重复此过程,直到其他人提出更好的解决方案。

    import UIKit
    import WebKit
    
    class ViewController: UIViewController, WKNavigationDelegate  {
    
        // Memeber variables
        var m_responseCount = 0; /* Counter to keep track of how many loads the webview has done.
                        this is a complete hack to get around the webkit crashing on
                        the second image load */
        let m_urlRequest = URLRequest(url: URL(string: "http://192.168.2.75:6789")!) //Enter your pi ip:motionPort
        var m_webView:WKWebView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            m_webView = WKWebView(frame: self.view.frame)  // Create our webview the same size as the viewcontroller
            m_webView.navigationDelegate = self            // Subscribe to the webview navigation delegate
        }
    
        override func viewDidAppear(_ animated: Bool) {
            m_webView.load(m_urlRequest)                    // Load our first request
            self.view.addSubview(m_webView)                 // Add our webview to the view controller view so we can see it
        }
    
        // MARK: - WKNavigation Delegates
        func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
            print("decidePolicyFor navigationAction")
            print(navigationAction.request) //This is the request to connect to the motion/pi server http::/192.168.2.75:6789
            decisionHandler(.allow)
        }
    
        func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
            print("decidePolicyFor navigationResponse")
            print(navigationResponse.response) // This is HTML from the motion/rpi
    
        /* We only want to load the html header and the first image
           Loading the second image is causing the crash
             m_responseCount = 0 - Header
             m_responseCount = 1 - First Image
             m_responseCount >= 2 - Second Image
        */
            if(m_responseCount < 2)
            {
                decisionHandler(.allow)
            }
            else{
                decisionHandler(.cancel) // This leads to webView::didFail Navigation Delegate to be called
            }
    
            m_responseCount += 1;  // Incriment our counter
    
        }
    
        func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        /*
         We have forced this failure in webView decidePolicyFor navigationResponse
         by setting decisionHandler(.cancel)
         */
            print("didFail navigation")
    
            m_webView.load(m_urlRequest) //Lets load our webview again
            m_responseCount = 0     /*  We need to reset our counter so we can load the next header and image again
                                    repeating the process forever
                                */
        }
    
        func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
        // If you find your wkwebview is still crashing break here for
        // a stack trace
            print("webViewWebContentProcessDidTerminate")
    
        }
    }
    

注意:由于 Motion/pi 服务器响应是 http 而不是 https,您还需要将以下内容添加到 info.plist 文件中

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

我鼓励您使用这个基本示例并对其进行修改以满足您的应用程序要求。我还鼓励您发布您自己的任何发现,因为我使用与您完全相同的硬件遇到了完全相同的问题,这不仅仅是解决方案,更是一种黑客攻击。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何防止 WKWebView 对象崩溃? 的相关文章

  • NSString stringWithContentsOfFile 失败,错误代码似乎错误

    我正在尝试将文件加载到字符串中 这是我正在使用的代码 NSError error nil NSString fullPath NSBundle mainBundle pathForResource filename ofType html
  • 为什么performSegueWithIdentifier在viewDidLoad中不起作用?

    我试图在视图控制器上调用 viewDidLoad 后立即触发故事板转场 Segue 附加了一个标识符 当从链接到按钮或其他控件的方法内部调用时 它可以正常工作 但它在 viewDidLoad 内部不起作用 它只是默默地失败了 viewDid
  • 如何使用 Vapor 和 Leaf 将图像从浏览器上传到 Amazon S3?

    我已经设置了 AWS S3 存储桶 并且可以使用 Vapor 3 和 Postman 上传文件 PUT request 和标头 x amz acl public read 但我想从浏览器中执行此操作 我使用的是 leaf 那么如何从浏览器上
  • Swift SpriteKit edgeLoopF​​romRect 问题

    下面的代码可以识别底部和顶部边缘场景和球按预期弹开 但是 那左边缘和右边缘现场的情况一直被破坏 如果施加足够的力 球会离开屏幕 然后最终返回 就好像场景的边缘超出了 iPhone 模拟器窗口的边缘 import SpriteKit clas
  • 如何保护 iOS 应用程序免受任何操作系统攻击(在越狱设备上)

    我希望保护我的应用程序数据 以防任何操作系统攻击或越狱 iOS 设备上的未经授权的访问 在这种情况下 有什么方法可以检测此类威胁并保护应用程序数据 虽然我同意 jrturton 的说法 但如果您有想要保护的关键数据免受流氓应用程序 而不是用
  • 从一个模态视图无缝翻转到另一个模态视图,而不显示纯色背景

    我的 iPad 应用程序的 UI 如下 当我点击Settings按钮 我希望对话框水平翻转以显示设置对话框 我这个工作正常 但是 当对话翻转时会显示背景颜色 如你看到的 有什么办法可以让对话框翻转时不显示该颜色块吗 我希望它看起来更加无缝
  • 每 24 小时触发一次方法

    我正在尝试每天在给定时间触发一个方法 我尝试了一些方法 但我无法真正使其发挥作用 任何意见 将不胜感激 此外 如果无论应用程序是否打开它都会触发 那就更理想了 这可能吗 UI本地通知 http developer apple com lib
  • iOS 中 NSDecimalNumber 的小数分隔符错误

    我尝试通过以下方式输出具有正确的小数分隔符的十进制数的描述 NSString strValue 9 94300 NSDecimalNumber decimalNumber NSDecimalNumber decimalNumberWithS
  • dyld:无法加载插入的库

    当我尝试运行 UI 和单元测试时 出现异常 dyld 无法加载插入的库 private var containers Bundle Application AutoTestingApp app Frameworks IDEBundleInj
  • 为什么 iOS 启动屏幕很慢?

    我的 iOS 应用程序启动屏幕大约需要 3 5 秒 我有一张将在启动屏幕后加载的地图 我的用户必须等待启动屏幕加载 然后再等待 3 秒才能加载地图 有没有办法最大限度地减少启动屏幕时间 基本上这种延迟意味着you在启动过程中做了一些非常错误
  • “预期的 ';'在 Swift 下的顶级声明符之后”

    我正在尝试将所有颜色设置在一个 Swift 文件中 该文件可以在我的整个应用程序中使用 下面的代码会导致 import Foundation import UIKit class DotColors let tsblueColor UICo
  • UItextView 背景颜色 Linespacing 区域太

    我正在尝试在 UITextView 中复制文本突出显示 不是搜索文本突出显示 但我也被行间距的颜色所困扰 我该如何纠正这个问题 现在的情况 期望的结果 我已将以下属性添加到我的 UiTextview 的属性文本中 对于段落行间距 我使用了以
  • 如何在代码中编辑约束

    我有一个以 100 开始宽度限制的网页 当用户单击按钮时 我想将约束更改为 200 我试过这个 NSLayoutConstraint constrain NSLayoutConstraint constraintWithItem self
  • 根据一个数组对多个数组进行排序

    如何根据数组对一堆数组进行排序createdAt 例如 2015 11 02 19 19 35 0000 将它们组合成另一种类型 字典 以便在 tableView 中使用是否有益 如果有的话如何 var comment AnyObject
  • TableViewController 的 viewDidLoad 未触发

    我一直在关注这个tutorial http www appcoda com ios programming sidebar navigation menu 有一个滑出式菜单 我添加了一个 TableViewController 它将显示文章
  • 使用 MapKit 的地形和卫星视图

    我是 Mapkit View 的新手 当我给出没有目的地的纬度和经度时 我想显示 MapKit中是否可以通过地形 卫星视图来显示地图 有教程链接吗 我看过一些访问 Google 地图 API html 文件 的示例 有必要吗 或者您可以通过
  • 如何更改 SwiftUI 列表中分隔符的颜色?

    我在 SwiftUI 中创建了一个列表 我想更改颜色或删除分隔符 因为在 UIKit 中 我们可以轻松更改 TableView 中分隔符的颜色 下面是 SwiftUI 中列表的代码和 UI 图片 State private var user
  • 模态转场需要点击 2 次而不是 1 次

    我的 UITableView 需要点击 2 次才能显示所选单元格的详细信息页面 一次用于选择 另一次用于显示详细信息视图 我希望有一个 CLI 直接显示所单击单元格的详细视图 我在 UITableViewManager m 中使用此方法的模
  • 像 TraceGL 一样分析 Objective C 中的代码路径?

    TraceGL 是一个非常简洁的项目 它允许 JS 程序员跟踪 Javascript 中的代码路径 它看起来像这样 我想为 Objective C 构建类似的东西 我知道运行时使跟踪方法调用变得相当容易 但是我如何跟踪控制流 例如 在上面的
  • ios - 如何声明静态变量? [复制]

    这个问题在这里已经有答案了 C 中声明的静态变量如下 private const string Host http 80dfgf7c22634nbbfb82339d46 cloudapp net private const string S

随机推荐

  • 如何找出真实屏幕刷新率(不是四舍五入的数字)

    根据微软的这篇文章 http support microsoft com kb 2006076 en us用户设置的屏幕刷新率可以 并且大部分是 小数 用户设置为 59Hz 但屏幕按照屏幕显示 60Hz 运行 但实际上是 59 94Hz 我
  • 我可以放慢 Django 的速度吗

    确实很简单的问题 manage py runserver 我可以慢下来吗localhost 8000在我的开发机器上 以便我可以模拟文件上传并处理 ajax 上传的外观和感觉 取决于你想模拟的地方 这样你就可以简单地睡觉吗 from tim
  • Android 异步任务一个接一个

    我有一个现有的代码 其中有一个用于某些请求响应的异步任务 在执行后方法中 它将解析的数据设置到某个数据库中 现在我需要修改此代码 以便在应用程序启动时 数据被一一下载 即我需要执行任务 A 然后在其完全完成后 即使数据已设置 我需要启动任务
  • int.TryParse = null 如果不是数字?

    如果无法将字符串解析为 int 是否有某种方法返回 null with public string categoryID int TryParse categoryID out categoryID 获取 无法从 out string 转换
  • for循环到底是如何工作的[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 这是一个非常简单的 for 循环 for int i 0 i lt 100 i System out println i 我知道它主要
  • WP All Import Pro:Polylang 兼容性

    我正在尝试使用 WP All Import 的专业版将数据从 Excel 工作表导入到 WordPress 中 我们使用 Polylang 来支持多语言 我想知道如何管理将内容导入正确的语言版本 我发现有一个隐藏的分类 语言 我可以手动将其
  • iPhone:协处理器偏移超出范围

    我在 xcode 和 iphone 上遇到了一个奇怪的编译问题 我的游戏即将完成 但现在我突然遇到这个编译错误 standard input 6108 co processor offset out of range gcc 4 2 fai
  • 使用 iOS 11 中增加的导航栏标题

    iOS 11 Beta 1 几乎所有系统应用程序都使用了增加的导航栏标题 它开始在 iOS 10 和音乐应用程序中这样做 我想知道 Apple 是否在 iOS 11 中为此提供了公共 API 或者目前是否会保持私有状态 行为是标题的字体大小
  • 创建带有限制的 XSD 可选小数元素

    我已经成功地使用以下方法创建了一个可选的小数元素
  • HandlerThread 中的 NullPointerException

    这个错误让我困惑了几个小时 我正在得到空指针异常 问题是这个错误不一致 当我启动应用程序时会发生这种情况 但只是偶尔 所以我不确定是什么原因造成的 对于错误日志中的冗长问题 我深表歉意 但我找不到其他询问方式 错误日志如下 FATAL EX
  • 查找某个表的数据来源-ORACLE

    这可能是一个微不足道的问题 但是 由于我正在处理很久以前由其他人创建的数据库 没有包含适当的文档或注释 所以我遇到了一个关键问题 我需要知道数据如何插入到某个表中 有没有脚本或者其他方法可以识别数据源 换句话说 我需要知道数据是否是通过某些
  • 仅允许视频嵌入代码 (Rails)

    我想知道是否有人知道一种方法 只允许将来自 youtube vimeo blip tv 等的代码嵌入到表单字段中 我的网站上有一个表单 允许用户嵌入视频 但我只希望他们添加嵌入代码 html 而不添加任何其他危险的内容 例如 JS 或其他
  • 使用 node-inspector 调试 karma-jasmine 测试

    几乎同样的问题使用 node inspector 调试 jasmine node 测试 https stackoverflow com questions 6162920 debugging jasmine node tests with
  • Xcode 11 beta 无法将应用程序上传到 TestFlight

    我正在尝试将我的应用程序分发到 TestFlight 目前我的应用程序需要 iOS 13 以及 NFC 访问 在 iOS 13 结束测试版之前 我不打算发布我的应用程序 但我希望我的 QA 团队能够对其进行测试 我可以从 Xcode 11
  • 多个图表延迟问题,SVG 还是 HTML5 Canvas?

    我正在寻找使用 Javascript 构建动态且交互式的多个图表 在此练习中涉及同时移动 平移多个图表 我已经使用 SVG 和各种图表库实现了这个练习 然而 我发现当我开始拥有超过 12 个图表时 平移渲染变得缓慢 Highcharts 库
  • 在 C# 中,Array.ToArray() 是否执行深度复制?

    这应该是一个非常基本的问题 但我在找到明确的答案时遇到了一些困难 当你有一个值数组并使用 ToArray 方法 它创建数组的深副本还是浅副本 No 您可以通过编写一个小程序进行测试来轻松验证这一点
  • PHP 警告: include(/var/www/html/....../lib/Cake/Error/ErrorHandler.php): 无法打开流错误

    我在尝试加载网页时遇到此错误 错误消息中显示的路径是 PHP 警告 包括 var www html test com www products abc lib Cake Error ErrorHandler php 无法打开流 它无法找到
  • Angular 6 Universal 不等待解析器完成

    我刚刚安装了 Angular Universal 启动套件版本6并在其中创建了我的组件 该组件应在加载时通 过 API 获取用户信息并将其显示以供查看 问题是 API 结果显示在浏览器中 但未显示在 查看源代码 什么叫普惠如此 My get
  • 变量神秘消失? AWS 代码构建

    接下来是我的 buildspec yml build commands IMAGE TAG cat package json grep version head 1 awk F print 2 sed s g echo IMAGE TAG
  • 如何防止 WKWebView 对象崩溃?

    Scenario 我正在用 Swift 构建一个 iOS 应用程序 其中一项功能是将实时视频源作为应用程序背景 视频源源自本地网络上的 Raspberry Pi 使用sudo motion Motion 已成功在默认端口上托管源8081 S