iOS webView或WKWebView 本地 多格式文檔預(yù)覽

iOS端做文檔預(yù)覽,其實(shí)iOS在早期設(shè)計(jì)的時(shí)候,就已經(jīng)考慮到了預(yù)覽的功能,所以在iOS系統(tǒng)的早期,就有<QuickLook>框架支持我們實(shí)現(xiàn)該功能 ,并且逐漸有了QLPreviewController(并不是一個(gè)視圖控制器,而是繼承NSObject的一個(gè)對象)和UIDocumentInteractionController這兩個(gè)類可以支持我們實(shí)現(xiàn)預(yù)覽,但是這兩個(gè)類默認(rèn)是支持分享功能的,不符合我們的app的要求(我們要求文檔有權(quán)限管理),所以這兩個(gè)都被pass了,在這個(gè)過程中,我們發(fā)現(xiàn)webView或者WKWebView也可以實(shí)現(xiàn)文件預(yù)覽,而且文件預(yù)覽或者展示UI易于操作,所以我們選擇了使用 網(wǎng)頁瀏覽器來完成這個(gè)功能.

首先說一下webView吧,由于iOS8系統(tǒng)時(shí),iOS已經(jīng)發(fā)布了新版的WKWebView,性能更好,更省內(nèi)存,所以我們后來用的是WKWebView,這里先簡單講一下webiView,webView用起來很簡單:

image.png

這個(gè)是WebView加載文檔的簡單應(yīng)用,本地沙盒目錄下的也一樣,這個(gè)不是重點(diǎn),我們的重點(diǎn)在WKWebView上,因?yàn)閕OS8 以下的用戶(有蘋果官網(wǎng)統(tǒng)計(jì)的數(shù)據(jù),17年 june月的的時(shí)候,iOS 9以下的只占3%了,), 我們這個(gè)暫時(shí)舍棄了,但是如果大家兼容,也是可以的.
統(tǒng)計(jì)數(shù)據(jù)的鏈接 : https://developer.apple.com/support/app-store/

下面我們來講WKWebView ,WKWebView在開發(fā)的時(shí)候,要分兩種類型.iOS8和iOS8以上版本的客戶端,需要單獨(dú)處理
因?yàn)閃KWebView有一個(gè)loadFileUrl的方法,是在iOS9之后才出現(xiàn)的,iOS8這個(gè)方法不能用,那能不能直接使用loadRequest方法呢,實(shí)踐證明,loadRequest在WKWebView不太管用(也可能是我沒有摸索到,但是我是多次嘗試,都沒成功,但是loadFile在iOS9之上,是妥妥的管用的)


image.png

所以,為了處理這個(gè)問題,我們這樣處理的
iOS8 以上的設(shè)備:
iOS8以上的設(shè)備,可以直接使用loadFileURL的加載和展示,沒有什么重要的可以講的,現(xiàn)在針對的是iOS8 怎么使用WKWebView呢?
通過翻墻查資料,發(fā)現(xiàn)了一個(gè)牛人的實(shí)現(xiàn)原理,先上代碼,

image.png

//將文件移動(dòng)到tmp目錄  瀏覽完再移動(dòng)回去
- (NSURL *)fileURLForBuggyWKWebView8:(NSURL *)fileURL {
    NSError *error = nil;
    if (!fileURL.fileURL || ![fileURL checkResourceIsReachableAndReturnError:&error]) {
        return nil;
    }
    // Create "/temp/www" directory
    NSURL *temDirURL = QDTempDirectoryURL;
    if (![QDFileManager fileExistsAtPath:[temDirURL path]]) {
        [QDFileManager createDirectoryAtURL:temDirURL withIntermediateDirectories:YES attributes:nil error:&error];
    }
    NSURL *dstURL = [temDirURL URLByAppendingPathComponent:fileURL.lastPathComponent];
    // Now copy given file to the temp directory
    [QDFileManager moveItemAtURL:fileURL toURL:dstURL error:&error];
    if (error) {
        NSLog(@"后調(diào)整失敗 ");
    }
    self.tempfilePath = dstURL;

//    [fileManager copyItemAtURL:fileURL toURL:dstURL error:&error];
    // Files in "/temp/www" load flawlesly :)
    return dstURL;
}

之前的牛人是將文件copy(我的代碼是移動(dòng)的,我認(rèn)為移動(dòng)應(yīng)該會(huì)比copy更快吧,因?yàn)槲覀兊奈臋n有的時(shí)候是接近1g的視頻文件,)到 沙盒目錄下的 "/temp/www" 文件夾,然后再通過LoadRequest來實(shí)現(xiàn),發(fā)現(xiàn)WKWebView居然生效了,這樣的話 ,我理解的是/temp/www默認(rèn)應(yīng)該是存儲的WKWebView的網(wǎng)絡(luò)緩存,然后當(dāng)加載這個(gè)的時(shí)候,系統(tǒng)認(rèn)為是網(wǎng)頁請求的時(shí)候在優(yōu)先加載緩存,所有就可以讀取了這個(gè)文檔.然后這個(gè)文件就解決了.
ps : 你如果和我一樣 是使用的移動(dòng)文檔的話,要記得處理這幾個(gè)情況

  1. 用戶瀏覽的時(shí)候,移動(dòng)過去,瀏覽結(jié)束,記得將文檔移動(dòng)回去
image.png

2.當(dāng)用戶瀏覽的時(shí)候 項(xiàng)目出現(xiàn)了崩潰 或者被用戶強(qiáng)退 或者用戶退出后臺被系統(tǒng)殺死怎么辦?
要將文檔移動(dòng)到沙盒目錄的時(shí)候,對文件做個(gè)標(biāo)示(比如文件名加個(gè)后綴,展示給用戶的時(shí)候記得過濾一下),然后在應(yīng)用啟動(dòng)的時(shí)候,在appDelegate的啟動(dòng)方法中,去'temp/www'的目錄下做一個(gè)判斷,判斷是否存在這種前綴的文檔,如果存在,移回原來的目錄,就ok了,

image.png

此外.如果你們的產(chǎn)品和我們一樣,對文檔有權(quán)限要求,比如,不允許選擇,復(fù)制,粘貼,等操作,我們可以通過js注入WKWebView的方法讓禁止用戶交互,代碼如下

 //禁止長按彈出 UIMenuController 相關(guān)
    //禁止選擇 css 配置相關(guān)
    NSString*css = @"body{-webkit-user-select:none;-webkit-user-drag:none;}";
    //css 選中樣式取消
    NSMutableString*javascript = [NSMutableString string];
    [javascript appendString:@"var style = document.createElement('style');"];
    [javascript appendString:@"style.type = 'text/css';"];
    [javascript appendFormat:@"var cssContent = document.createTextNode('%@');", css];
    [javascript appendString:@"style.appendChild(cssContent);"];
    [javascript appendString:@"document.body.appendChild(style);"];
    [javascript appendString:@"document.documentElement.style.webkitUserSelect='none';"];//禁止選擇
    [javascript appendString:@"document.documentElement.style.webkitTouchCallout='none';"];//禁止長按
    //javascript 注入
    WKUserScript *noneSelectScript = [[WKUserScript alloc] initWithSource:javascript
                                                            injectionTime:WKUserScriptInjectionTimeAtDocumentEnd
                                                         forMainFrameOnly:YES];
    WKUserContentController*userContentController = [[WKUserContentController alloc] init];
    [userContentController addUserScript:noneSelectScript];
    WKWebViewConfiguration*configuration = [[WKWebViewConfiguration alloc] init];
    configuration.userContentController = userContentController;
    //控件加載
    [self.webView.configuration.userContentController addUserScript:noneSelectScript];


    [self.view addSubview:self.webView];
    

    [self.webView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.right.bottom.equalTo(self.view);
    }];

以上是我的個(gè)人見解,有問題請大家指出,謝謝大家.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • WkWebView是IOS8中引入的新組件,蘋果將UIWebViewDelegate 與 UIWebView 重構(gòu)...
    i_belive閱讀 5,160評論 1 25
  • WKWebView 新特性 加載 web 頁面 加載本地資源 - loadHTMLString:baseURL:同...
    獨(dú)木舟的木閱讀 22,359評論 2 43
  • 一、WebView WebView就是一個(gè)內(nèi)嵌瀏覽器控件,在iOS中主要有兩種WebView:UIWebView和...
    iOS祎閱讀 1,245評論 0 2
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,262評論 4 61
  • 雖然要做真實(shí)的自己但是自己一定要有方向和目標(biāo)。
    臨淄茂業(yè)DDM王麗萍閱讀 158評論 0 0

友情鏈接更多精彩內(nèi)容