[技术文档][技术中心][iOS部][114啦]全局搜索

需求说明

1、首页进入显示搜索历史,网页进入对关键词进行联想搜索。
2、搜索需要用web打开都统一新建标签页打开,加在最后面。
3、按照标签、工具、应用、经验、说明书、百度联想排序。
4、显示1条工具,点击更多显示工具列表。
5、显示3条相关的经验,点击更多进入更多经验列表。
6、显示3条相关的说明书,点击更多进入更多相关说明书的列表。
7、关键词联想,由百度提供该关键词的联想,并显示在底部。

需求地址

http://192.168.1.75/114la/220/114la_220/#g=1&p=2_2_%E6%90%9C%E7%B4%A2_%E6%B5%8F%E8%A7%88%E4%BA%A4%E4%BA%92

接口说明

URL:http://114larc.com/q/api/1.0/android/1.0/search
请求方式:GET

  • 请求参数说明:
参数名称 必选 类型 描述
q true string 关键字
  • 返回结果说明:
    列表中的type值:1-经验 2-说明书 3-工具 4-标签 5-应用,
    不同type对应不同的结构模型,经验和说明书结构一样,请参考下面的json数据结构:
    share:分享地址

  • 返回结果:

{
    "state": 1,
    "code": 0,
    "message": "",
    "data": {
        "share": "114larc.com/p/search?q=1",
        "list": [
            {
                "name": "标签",
                "type": 4,
                "list": [
                    "比较"
                ]
            },
            {
                "name": "工具",
                "type": 3,
                "list": [
                    {
                        "name": "比较6",
                        "url": "http://6.com",
                        "logo": "http://img.114larc.com/thumb/P/RC/3D/PRC3D74AC06B2B5772DF7ED285C6C31F5B0_100_100?s=6dt6DCcT4y78R5jmWyrsjQ"
                    }
                ]
            },
            {
                "name": "应用",
                "type": 5,
                "list": [
                    {
                        "pinyin": "bilin-402anzhuoyingyongapk",
                        "size": "31.1M",
                        "name": "比邻",
                        "description": "

软件简介:

比邻是一款电话社交平台APP,是一个刺激年轻人心跳的社交工具。

主要通过即时通话,随时畅聊你感兴趣的话题,并且可以通过精彩的图片和文字分享生活中的美好点滴,

也可以欣赏其它用户个性十足的个人资料和生活相册。


功能简介:

随机电话 - 无距离、无时差随时开聊

超能力标签 - 找到自己的独特话题

最近在线 - 温暖的陌生人都在这里

连线好友 - 免费无限时、无限次通话


使用场景:

√当你寂寞的时候,打打比邻,这里有人为你唱歌

√当你失眠的时候,打打比邻,这里有人哄你入睡

√当你难过的时候,打打比邻,这里有人逗你开心

√当你觉得的时候,打打比邻,这里有暖男热线


更新内容:

1、解决部分崩溃问题
2、优化随机群聊匹配
", "logo": "http://img.anxia.com/thumb/P/DL/BB/PDLBB6E146E341F7900B35E690F7813E1B3_0?s=Sv8uwHljz5_qEeEM9hq7nA", "sid": "18081", "release_time": "1496073600", "has_history": 0, "url": "/a/bilin-402anzhuoyingyongapk" } ] }, { "name": "说明书", "type": 2, "list": [ { "t_id": 90, "c_id": 4362, "type": 2, "is_hot": 0, "is_top": 0, "subject": "苯巴比妥片", "summary": "", "state": 1, "post_time": 1500968344, "update_time": 1500982779, "url": "http://114larc.com/s/detail/23D60020000004Y5BJDPASGK.html", "cat_id": 0, "useful_num": 0, "is_useful": 0, "location": "", "icon_url": "http://img.114larc.com/thumb/P/RC/2D/PRC2D0CF8CCC0AAC491D879969C5B4BF3AD_800_800?s=TRfGkLQUmrIzy_5wETifbA", "pics": [], "tags": [ "失眠", "心脑血管" ] } ] } ], "count": 4 } }

核心代码

进入搜索界面都先调用该方法,进行初始化操作

func urlBarViewDidClick(_ urlBarView: URLBarView) {
        if let keyworkSearch = MainViewFacade.sharedInstance.cache?.object(forKey: "keywork_search") as? [NSCoding] {
            let temp = NSMutableArray(array: keyworkSearch)
            //覆盖安装时,缓存的内容为【string】,需转化为模型
            if temp as AnyObject is [String] {
                for i in 0..

修改该属性则会延迟0.6s执行搜索操作,还带有cancel上一次未完成的请求。

var textFieldText: String? {
        didSet {
            
            if textFieldText?.characters.count == 0 && shouldUpdateDatas {
                NSObject.cancelPreviousPerformRequests(withTarget: self)
                updateDatas("")
                return
            }
            guard textFieldText != oldValue else {
                if shouldUpdateDatas {
                    NSObject.cancelPreviousPerformRequests(withTarget: self)
                    self.perform(#selector(NewSearchViewManager.updateDatas(_:)), with:textFieldText, afterDelay: 0.1)
                    shouldUpdateDatas = false
                }
                return
            }

            NSObject.cancelPreviousPerformRequests(withTarget: self)
            self.perform(#selector(NewSearchViewManager.updateDatas(_:)), with:textFieldText, afterDelay: 0.6)
        }
    }

该方法则是真正发出请求。
该处分为两个接口,同时发出请求,先回来数据则先显示,后回来的则进行处理拼接起来后再刷新数据。
返回的结果是有固定的排序方式的。

func updateDatas(_ text: String?) {
        if text?.trimmingCharacters(in: CharacterSet.whitespaces).isEmpty == false {
            
            let enginModel = SearchGroupModel(SearchGroupType.engine)
            enginModel.searchDatas = [SearchCellModel(keyword: text!)]
            self.datas = [enginModel]
            self.tableView.reloadData()
            //114啦  热词联想搜索接口
            self.api.associateSearch(withKeywork: text!) { [weak self](keyworks, searchEngineURL) -> Void in
                guard let strongSelf = self else {
                    return
                }
                guard let keyworks = keyworks as? [String], strongSelf.textFieldText! == text else {
                    return
                }
                
                var levdatas = [SearchCellModel]()
                
                for kword in keyworks {
                    let model = SearchCellModel(keyword: kword)
                    levdatas.append(model)
                }
                
                if levdatas.count > 0 || text == "114la.com" || text == "115.com" {
                    if text == "w" || text == "ww" || text == "www" || text == "www."
                     || text == "114la.com" || text == "115.com" {
                        levdatas.insert(SearchCellModel(keyword: "www.115.com"), at: 0)
                        levdatas.insert(SearchCellModel(keyword: "www.114la.com"), at: 0)
                    }
                    let lenovoModel = SearchGroupModel(SearchGroupType.lenovo)
                    lenovoModel.searchDatas = levdatas
                    
                    
                    if let datas = strongSelf.datas, datas.last?.type == .share {
                        strongSelf.datas?.insert(lenovoModel, at: datas.count - 1)
                    } else {
                        strongSelf.datas?.append(lenovoModel)
                    }
                }
                strongSelf.tableView.isHidden = false
                strongSelf.tableView.dk_backgroundColorPicker = DKColor.picker(withNormalColor: UIConstants.NormalBackgroundColor, nightColor: UIConstants.NightDarkBackgroundColor)
                strongSelf.tableView.reloadData()
            }
            
            // 综合搜索
            YYW114LaService.comprehensiveSearch(keyword: text!, { (json, error) -> AnyObject? in
                if error != nil {
                    self.urlBarView?.addressTextField.resignFirstResponder()
                    return nil
                }
                if let json = json {
                    guard self.textFieldText! == text, json["state"].intValue == 1 else {
                        return nil
                    }
                    
                    let listDatas = json["data"]["list"].arrayValue
                    
                    var tempDatas = [SearchGroupModel]()
                
                    for type in showOrder {
                        if let dict = listDatas.filter({ (dict) -> Bool in
                            return dict["type"].intValue == type
                        }).first {
                            switch type {
                            case 1:
                                if dict["list"].arrayValue.count > 0 {
                                    tempDatas.append(SearchGroupModel(SearchGroupType.experience,dict["list"].arrayValue))
                                }
                            case 2:
                                if dict["list"].arrayValue.count > 0 {
                                    tempDatas.append(SearchGroupModel(SearchGroupType.instructions,dict["list"].arrayValue))
                                }
                            case 3:
                                if dict["list"].arrayValue.count > 0 {
                                    tempDatas.append(SearchGroupModel(SearchGroupType.tool,dict["list"].arrayValue))
                                }
                            case 4:
                                if dict["list"].arrayValue.count > 0 {
                                    let model = SearchGroupModel(.label)
                                    model.searchDatas = SearchGroupModel.getLabelModels(dict["list"].arrayValue)
                                    tempDatas.append(model)
                                }
                            case 5:
                                if dict["list"].arrayValue.count > 0 {
                                    tempDatas.append(SearchGroupModel(SearchGroupType.application,dict["list"].arrayValue))
                                }
                            case 999:
                                tempDatas.append(SearchGroupModel(SearchGroupType.ads,[dict["list"]]))
                            default:
                                break
                            }
                        }
                    }
                    
                    self.datas?.insert(contentsOf: tempDatas, at: 1)
                    if !json["data"]["share"].stringValue.isEmpty && tempDatas.count > 0
                    && self.datas?.last?.type != .share {
                        let shareModel = SearchGroupModel(SearchGroupType.share)
                        shareModel.searchDatas = [SearchCellModel(keyword: json["data"]["share"].stringValue)]
                        self.datas?.append(shareModel)
                    }
                    
                    self.tableView.dk_backgroundColorPicker = DKColor.picker(withNormalColor: UIConstants.NormalBackgroundColor, nightColor: UIConstants.NightDarkBackgroundColor)
                    self.tableView.isHidden = false
                    self.tableView.reloadData()
                }
                return nil
            })
        }
        else
        {
            shouldShowKeyWordSearch()
        }
    }

当点击搜索记录发生页面跳转,并且会记录搜索历史。

//处理url后进行加载
fileprivate func loadAndAddToHistoryWithURLString(_ URLString: String) {
        
        guard !isSearchUrlToChangeSearchKey(URLString) else { return }
        
        var text = self.searchEngineURL + URLString
        if let _ = MainViewFacade.sharedInstance.mainViewModel.verificationURL(URLString)
        {
            text = URLString
        }
        
        if UserDefaults.standard.bool(forKey: "isOpenSearch")
        {
            self.addKeyworkToSearchHistory(URLString)
        }
        
        if let request = MainViewFacade.sharedInstance.mainViewModel.verificationURL(text) {
            urlBarView?.clearText(UITapGestureRecognizer())
            urlBarView?.cancel()
//            MainViewFacade.sharedInstance.currentPageView().loadRequest(request)
            mainViewController()?.pageViewManager.newTabLoadRequest(request)
            if let absoluteString = request.url?.absoluteString {
                urlBarView?.addressTextString = absoluteString
            }
            cancelFocus()
        }
        
    }
//添加搜索历史记录 隐身模式不添加
    func addKeyworkToSearchHistory(_ keywork: String) {
        guard !self.isPrivate else {
            return
        }
        let index = isContainsKeyWord(keywork)
        if index >= 0 {
            self.keyworkSearch.remove(at: index)
        }
        let searchModel:SearchCellModel
        
        if let _ = MainViewFacade.sharedInstance.mainViewModel.verificationURL(keywork) {
            searchModel = SearchCellModel(dict: ["keyWord": keywork as AnyObject], type: .url)
        } else {
            searchModel = SearchCellModel(keyword: keywork)
        }
        
        self.keyworkSearch.insert(searchModel, at: 0)
        if self.keyworkSearch.count > 10 {
            self.keyworkSearch.removeSubrange(Range(10 ..< self.keyworkSearch.count))
        }
        MainViewFacade.sharedInstance.cache?.setObject(self.keyworkSearch as NSCoding, forKey: "keywork_search")
    }

添加分享搜索结果以后需要判断是不是打开分享出去的搜索结果url。
是的话则用原生UI打开搜索页面,不进行打开网页。

fileprivate func isSearchUrlToChangeSearchKey(_ text: String) -> Bool {//http://114larc.com/p/search?q=keyword
        if text.contains("114larc.com/p/search?q=") || text.contains("114la.com/p/search?q=") {
            let range = text.range(of: ".com/p/search?q=")
            var changeText = text.substring(from: range!.upperBound)
            changeText = changeText.removingPercentEncoding ?? changeText
            urlBarView?.addressTextField.text = changeText
            textFieldText = changeText
            return true
        }
        return false
    }

该搜索界面是将view添加在首页的view中的,显示时添加,取消搜索时将view移除。
使用的是同一个tableview。不会重新创建,因此每次需要初始化。

你可能感兴趣的:([技术文档][技术中心][iOS部][114啦]全局搜索)