最近一直在做手机H5的东西,网页写多了,测试也测出问题来了,打开十几个网页后,app出现无响应,app的webvIEw界面出现黑屏等等奇怪的问题。
我试了几遍,APP内存占用从20M飙升到100M+,到了100M的时候,xcode被断开了,然后问题就一个个冒出来了-_-!
搜索了一下,是uiwebvIEw内存泄漏,然后我就兼容了wkwebvIEw。
wkwebvIEw遇到的问题主要有几个:
1、多个wkwebvIEw数据不同步,localstorage在a页面能用,去到b页面能用,在b页面写入东西,在a页面看不到
2、跳转新增webvIEw,加载很慢
3、receiveMemoryWarning 之后,或者一段时间没用之后,返回之前的页面,页面变成空白
我解决了这几个问题,并写了一个替代的兼容webvIEw
@H_301_31@
所以标题也可以叫uiwebvIEw的无痛迁移
@H_301_31@
//// GsWebVIEw.swift// iosclIEnt//// Created by Yeshen on 16/8/31.// copyright © 2016年 L. All rights reserved.//import Foundationimport UIKitimport WebKitprotocol GsWebVIEwDelegate{ func webVIEw(webVIEw: GsWebVIEw,shouldStartLoaDWithRequest request: String?) -> Bool func webVIEwDIDStartLoad(webVIEw: GsWebVIEw) func webVIEwDIDFinishLoad(webVIEw: GsWebVIEw) func webVIEw(webVIEw: GsWebVIEw,dIDFailLoaDWithError error: NSError?)}class GsWebVIEw :NSObject,uiwebviewdelegate,WKNavigationDelegate,WKUIDelegate{ var delegate:GsWebVIEwDelegate? var vIEw:UIVIEw? init(frame:CGRect) { super.init() if #available(iOS 8.0,*) { let config = WKWebVIEwConfiguration() config.processpool = Processpool.ins.get() config.preferences = Processpool.ins.getPreferences() let v = WKWebVIEw(frame: frame,configuration: config) v.navigationDelegate = self v.UIDelegate = self v.opaque = false self.vIEw = v }else{ let v = UIWebVIEw(frame: frame) v.delegate = self v.dataDetectorTypes = UIDataDetectorTypes.None self.vIEw = v } } func loadRequest(url:String){ if let url = NSURL(string: url.EncodeURL()){ let request = NSURLRequest(URL: url) if #available(iOS 8.0,*) { if let wkweb = vIEw as? WKWebVIEw { wkweb.loadRequest(request) } } else { if let uiweb = vIEw as? UIWebVIEw{ uiweb.loadRequest(request) } } } } func setBackgroundcolor(color:UIcolor){ vIEw?.backgroundcolor = color } func getScrollVIEw() -> UIScrollVIEw?{ if #available(iOS 8.0,*) { if let wkweb = vIEw as? WKWebVIEw { return wkweb.scrollVIEw } } else { if let uiweb = vIEw as? UIWebVIEw{ return uiweb.scrollVIEw } } return nil } func runjs(action:String?){ if #available(iOS 8.0,*) { if let wkweb = vIEw as? WKWebVIEw { wkweb.runjs(action) } } else { if let uiweb = vIEw as? UIWebVIEw{ uiweb.runjs(action) } } } func JavaScriptGet(action:String?,callback:((AnyObject?,NSError?) -> VoID)){ if #available(iOS 8.0,*) { if let wkweb = vIEw as? WKWebVIEw { wkweb.JavaScriptGet(action,callback: callback) return } } else { if let uiweb = vIEw as? UIWebVIEw{ let str = uiweb.JavaScriptGet(action) callback(str,nil) return } } callback(nil,nil) } func getTitle() -> String{ if #available(iOS 8.0,*) { if let wkweb = vIEw as? WKWebVIEw { return wkweb.getTitle() } } else { if let uiweb = vIEw as? UIWebVIEw{ return uiweb.getTitle() } } return Strings.empty } func reloadFromOrigin(){ if #available(iOS 8.0,*) { if let wkweb = vIEw as? WKWebVIEw { wkweb.reloadFromOrigin() } } else { if let uiweb = vIEw as? UIWebVIEw{ uiweb.reload() } } } func reload(){ self.reload(nil) } func reload(optionalUrl:String?){ if #available(iOS 8.0,*) { if let wkweb = vIEw as? WKWebVIEw { if(wkweb.URL == nil && optionalUrl != nil){ loadRequest(optionalUrl!) return } wkweb.reload() } } else { if let uiweb = vIEw as? UIWebVIEw{ uiweb.reload() } } } func canGoBack() -> Bool{ if #available(iOS 8.0,*) { if let wkweb = vIEw as? WKWebVIEw { return wkweb.canGoBack } } else { if let uiweb = vIEw as? UIWebVIEw{ return uiweb.canGoBack } } return false } func goBack() { if #available(iOS 8.0,*) { if let wkweb = vIEw as? WKWebVIEw { wkweb.goBack() } } else { if let uiweb = vIEw as? UIWebVIEw{ uiweb.goBack() } } } //call on vIEwDIDAppear //for wkwebvIEw'BUG : Blank screen after running app for a while var ensure:Int = 0 func ensurePageValID(){ if #available(iOS 8.0,*) { ensure++ if(ensure > 1){ JavaScriptGet("document.body.children.length > 0",callback: {(data,error) -> VoID in var isVaild = true if(error == nil && data != nil){ if let vaild = data as? Bool{ isVaild = vaild } }else if(error != nil){ if(error?.domain == WKErrorDomain && error?.code == 1){ isVaild = false } } if(!isVaild){ NSOperationQueue.mainQueue().addOperationWithBlock({()-> VoID in self.reloadFromOrigin() }) } }) } }else{ //ignore it } } ///////////// func webVIEw(webVIEw: UIWebVIEw,shouldStartLoaDWithRequest request: NSURLRequest,navigationType: UIWebVIEwNavigationType) -> Bool{ if delegate != nil,let url = request.URL?.description.DecodeURL(){ return delegate!.webVIEw(self,shouldStartLoaDWithRequest: url) } return true } @available(iOS 8.0,*) func webVIEw(webVIEw: WKWebVIEw,decIDePolicyForNavigationAction navigationAction: WKNavigationAction,decisionHandler: (WKNavigationActionPolicy) -> VoID){ var policy = WKNavigationActionPolicy.Allow if delegate != nil,let url = navigationAction.request.URL?.deBUGDescription.DecodeURL(){ if(!delegate!.webVIEw(self,shouldStartLoaDWithRequest: url)){ policy = WKNavigationActionPolicy.Cancel } } decisionHandler(policy) } ////////////// func webVIEwDIDStartLoad(webVIEw: UIWebVIEw){ if delegate != nil{ delegate?.webVIEwDIDStartLoad(self) } } @available(iOS 8.0,dIDCommitNavigation navigation: WKNavigation!){ if delegate != nil{ delegate?.webVIEwDIDStartLoad(self) } } //////////// func webVIEwDIDFinishLoad(webVIEw: UIWebVIEw){ if delegate != nil{ delegate?.webVIEwDIDFinishLoad(self) } } @available(iOS 8.0,dIDFinishNavigation navigation: WKNavigation!){ if delegate != nil{ delegate?.webVIEwDIDFinishLoad(self) } } ////////////// func webVIEw(webVIEw: UIWebVIEw,dIDFailLoaDWithError error: NSError?){ if delegate != nil{ delegate?.webVIEw(self,dIDFailLoaDWithError: error) } } @available(iOS 8.0,dIDFailNavigation navigation: WKNavigation!,withError error: NSError){ if delegate != nil{ delegate?.webVIEw(self,dIDFailProvisionalNavigation navigation: WKNavigation!,dIDFailLoaDWithError: error) } } }@H_301_31@
@available(iOS 8.0,*)extension WKWebVIEw{ func JavaScriptGet(Jscode:String?,NSError?) -> VoID)?) -> String?{ if let Js = Jscode{ self.evaluateJavaScript("JavaScript:" + Js,completionHandler: callback) } return nil } func runjs(Jscode:String?){ if let Js = Jscode{ self.evaluateJavaScript("JavaScript:" + Js,completionHandler: {(error,data) -> VoID in }) } } func getTitle() -> String{ return self.Title == nil ? Strings.empty : self.Title! }}extension UIWebVIEw{ func JavaScriptGet(Jscode:String?) -> String?{ if let Js = Jscode{ return self.stringByEvaluatingJavaScriptFromString("JavaScript:" + Js) } return nil } func runjs(Jscode:String?){ if let Js = Jscode{ self.stringByEvaluatingJavaScriptFromString("JavaScript:" + Js) } } func getTitle() -> String{ if let Title = stringByEvaluatingJavaScriptFromString("document.Title"){ return Title } return Strings.empty }}@H_301_31@
//// Processpool.swift// iosclIEnt//// Created by Yeshen on 16/9/2.// copyright © 2016年 L. All rights reserved.//import Foundationimport WebKit@available(iOS 8.0,*)class LandowProcesspool { private var pool:WKProcesspool? private var preferences:WKPreferences? class var ins: Processpool{ struct Static { static var oncetoken:dispatch_once_t = 0 static var instance:Processpool? = nil } dispatch_once(&Static.oncetoken){ Static.instance = Processpool() } return Static.instance! } func get() -> WKProcesspool{ if(pool != nil){ return pool! } pool = WKProcesspool() return pool! } func getPreferences() ->WKPreferences{ if(preferences != nil){ return preferences! } preferences = WKPreferences() return preferences! } }@H_301_31@
此外,在Target general 的linked frameworks and librarIEs中要引入webkit.framework
@H_301_31@
以上,后面有问题再补充修改
总结以上是内存溢出为你收集整理的swift(ios) webview 的优化全部内容,希望文章能够帮你解决swift(ios) webview 的优化所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)