首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >网络浏览器在引擎盖下的工作历史

网络浏览器在引擎盖下的工作历史
EN

Stack Overflow用户
提问于 2021-03-10 16:26:13
回答 1查看 165关注 0票数 0

我试图在WKWebView上为iOS实现自己的web浏览器历史记录,但是我不能完全实现这个功能,而且每次我都会遇到麻烦。我可以创建一个历史记录,用户确实在其中,然后在历史中向前和向后移动。但我有下一个麻烦,我认为这只是我路上的许多问题中的一个。例如,当我有一个有10个元素的历史时,然后我将移回元素5,然后继续前进,但是尝试打开新的链接,我不能删除元素6-10并放置新的链接。

我认为我的问题是,我不能完全理解历史是如何在所有浏览器内部工作的,这不是一项艰巨的任务,但我在这个算法中感到困惑。我用来保存历史的主要数据结构帮助我理解了如何在浏览器中使用这个算法,或者可能存在一个很好的理论?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-11 14:36:06

我解决了这个问题,并很好地实现了完整的算法,完成的项目在这里可用:https://github.com/IhorYachmenov/Custom-browser-history-for-WKWebView

算法:

代码语言:javascript
复制
struct PlayerHistory {
    
    static var shared = PlayerHistory()
    
    var historyExist: Bool = false
    var historyCurrentPosition: Int = 0
    var historyLastPositionBeforeUpdatingHistory: Int!
    var userHistoryKey: String!
    
    var backPressed: Bool!
    var forwardPressed: Bool!
    
    var urlOfPlayer: String!
    
    // Function only for first loading inside <viewDidLoad or another method from app LifeCycle>.
    mutating func getUrlForFirstLoading(initURL: String, key: String) -> String {
        
        urlOfPlayer = initURL
        
        guard HistoryStorage.shared.getHistoryFromUserDefaults() != nil else {
            updateFirstElement(key: key, url: initURL)
            return initURL
        }
        
        guard HistoryStorage.shared.getHistoryFromUserDefaults()![key] != nil else {
            return initURL
        }
        
        let position = HistoryStorage.shared.getHistoryFromUserDefaults()![key]!.count - 1
        
        historyExist = true
        historyCurrentPosition = position
        userHistoryKey = key
        let initUrlFromHistoryStorage = HistoryStorage.shared.getHistoryFromUserDefaults()![key]!.last!.url
        
        return initUrlFromHistoryStorage
    }
    
    // Create new or update exist history, use this method indsede <decidePolicyForNavigation>.
    mutating func updatePlayerHistory(backlisk: [String], key: String) {
        
        var history = [WebViewHistory]()
        
        for i in backlisk {
            history.append(WebViewHistory(i))
        }
        
        if (historyExist == true) {
            // If old history exist need compound both and then to save.
            
            let oldHistory = HistoryStorage.shared.getHistoryFromUserDefaults()![key]

            let oldAndNewHostoryTogether = oldHistory! + history
            
            var keyValuePair = Dictionary<String, [WebViewHistory]>()
            keyValuePair.updateValue(oldAndNewHostoryTogether, forKey: key)
            
            HistoryStorage.shared.removeHistory()
            HistoryStorage.shared.saveHistory(keyValuePair)
            
            setCurrentPosition(url: backlisk.last!, key: key)
        } else {
            var keyValuePair = Dictionary<String, [WebViewHistory]>()
            keyValuePair.updateValue(history, forKey: key)
            
            historyExist = true
            
            HistoryStorage.shared.removeHistory()
            HistoryStorage.shared.saveHistory(keyValuePair)
            setCurrentPosition(url: backlisk.last!, key: key)
        }
    }
        
    
    // Before using this method check if result don't equals nil. Use this method for navigation beetween history
    func moveThroughHistory(key: String, direction: Bool) -> String? {
        
        guard  historyExist != false else {
            return nil
        }
        
        let history = HistoryStorage.shared.getHistoryFromUserDefaults()![key]!
        
        if (direction == true) {
            let index = historyCurrentPosition + 1
            guard index != history.count else { return nil }
            return history[index].url
        } else {
            let index = historyCurrentPosition - 1
            guard index > 0 else { return history[0].url }
            return history[index].url
        }
        
        
    }
    
    // Method <setCurrentPosition> each time set position at history
    mutating func setCurrentPosition(url: String, key: String) {
        
        guard HistoryStorage.shared.getHistoryFromUserDefaults() != nil else { return }
        guard HistoryStorage.shared.getHistoryFromUserDefaults()![key] != nil else { return }
        
        let history = HistoryStorage.shared.getHistoryFromUserDefaults()![key]
        let index = history?.firstIndex(of: WebViewHistory(url))
        
        guard index != nil else {
            historyCurrentPosition = 0
            return
        }
        historyCurrentPosition = index!
    }
    
    // <removeUnusedPeaceOfHistory> need use when user want open new page staying inside the middle of history
    mutating func removeUnusedPeaceOfHistory(key: String) {
        
        guard HistoryStorage.shared.getHistoryFromUserDefaults() != nil else {
            return
        }
        
        guard HistoryStorage.shared.getHistoryFromUserDefaults()![key] != nil else {
            return
        }
        
        var history = HistoryStorage.shared.getHistoryFromUserDefaults()![key]!
        let startIndex = historyCurrentPosition + 1
        let endIndex = history.endIndex - 1
        let countOfAllElements = history.count
        
        guard startIndex != countOfAllElements else { return }
        let range = startIndex...endIndex
        history.removeSubrange(range)
        
        var keyValuePair = Dictionary<String, [WebViewHistory]>()
        keyValuePair.updateValue(history, forKey: key)
        
        HistoryStorage.shared.removeHistory()
        HistoryStorage.shared.saveHistory(keyValuePair)
    }
        
    // Use <updateFirstElement> inside <getUrlForFirstLoading> if history doesn't exist
    private mutating func updateFirstElement(key: String, url: String) {
        var history = [WebViewHistory]()
        history.insert(WebViewHistory(url), at: 0)
        
        var keyValuePair = Dictionary<String, [WebViewHistory]>()
        keyValuePair.updateValue(history, forKey: key)
        
        HistoryStorage.shared.saveHistory(keyValuePair)
        historyExist = true
        historyCurrentPosition = 0
        
    }
    
    // Use <webViewWillBeClosedSaveHistory> when WKWebView should be closed, if the user moves through history new position will be saved.
    mutating func webViewWillBeClosedSaveHistory(key: String) {
        let history = HistoryStorage.shared.getHistoryFromUserDefaults()![key]!
        let currentPosition = historyCurrentPosition + 1
        guard currentPosition != history.count else { return }
        removeUnusedPeaceOfHistory(key: key)
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66568914

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档