1. 程式人生 > >利用NSURLProtocol實現webView快取

利用NSURLProtocol實現webView快取

註冊自定義protocol handler MyURLProtocol
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [NSURLProtocol registerClass:[MyURLProtocol class]];
    return YES;
}
幾個重要的NSURLProtocol方法 + (BOOL)canInitWithRequest:(NSURLRequest *)request; 當URL loading System接收到一個請求時,系統會去尋找一個註冊過的protocol handler來處理這個請求。每一個protocol handler通過該方法告訴系統是否可以處理該請求。 return YES ,系統將會依賴該protocol handler 來處理這個請求。 如果所有的自定義protocol handler都返回NO, 系統會用自己的預設行為來處理這個請求。 如果你自定義了一個新的protocol foo:// 你可以在這裡判斷是否這個URL scheme 是foo。如果是,用自定義protocol handler 返回YES,來處理。 + (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request;
NSURLProtocol的抽象方法,子類必須進行實現。返回規範化後的request,這個方法給了我們重新處理request的機會,比如如果我們需要為request加一個header那麼在這裡會是一個不錯的時機。 + (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b; 在這裡可以指定兩個不同的請求,視為同一個請求。它們會使用相同的快取資料 - (void)startLoading和-(void)stopLoading 開始請求資料和結束請求資料 幾個NSURLConnection的代理方法
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [
self.client URLProtocol:self didLoadData:data]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { [self.client URLProtocolDidFinishLoading:self]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { [self.client URLProtocol:self didFailWithError:error]; }
在這些代理方法中我們拿到請求的進展過程,並通過urlprotocol handler 的client 將進展告訴系統,從而對系統進行代理。 執行程式,發生了什麼? 死迴圈! 解決辦法
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
    static NSUInteger requestCount = 0;
    NSLog(@"Request #%u: URL = %@", requestCount++, request);
 
    if ([NSURLProtocol propertyForKey:@"MyURLProtocolHandledKey" inRequest:request]) {
        return NO;
    }
 
    return YES;
}
 
- (void)startLoading {
    NSMutableURLRequest *newRequest = [self.request mutableCopy];
    [NSURLProtocol setProperty:@YES forKey:@"MyURLProtocolHandledKey" inRequest:newRequest];
 
    self.connection = [NSURLConnection connectionWithRequest:newRequest delegate:self];
}
本地快取網路請求
@property (nonatomic, strong) NSMutableData *mutableData;
@property (nonatomic, strong) NSURLResponse *response;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
 
    self.response = response;
    self.mutableData = [[NSMutableData alloc] init];
}
 
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.client URLProtocol:self didLoadData:data];
    [self.mutableData appendData:data];
}
 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [self.client URLProtocolDidFinishLoading:self];
    [self saveCachedResponse];
}
- (void)saveCachedResponse {
    NSLog(@"saving cached response");
 
    // 1.
    AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = delegate.managedObjectContext;
 
    // 2.
    CachedURLResponse *cachedResponse = [NSEntityDescription insertNewObjectForEntityForName:@"CachedURLResponse"
                                                                      inManagedObjectContext:context];
    cachedResponse.data = self.mutableData;
    cachedResponse.url = self.request.URL.absoluteString;
    cachedResponse.timestamp = [NSDate date];
    cachedResponse.mimeType = self.response.MIMEType;
    cachedResponse.encoding = self.response.textEncodingName;
 
    // 3.
    NSError *error;
    BOOL const success = [context save:&error];
    if (!success) {
        NSLog(@"Could not cache the response.");
    }
}
- (CachedURLResponse *)cachedResponseForCurrentRequest {
    // 1.
    AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = delegate.managedObjectContext;
 
    // 2.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"CachedURLResponse"
                                              inManagedObjectContext:context];
    [fetchRequest setEntity:entity];
 
    // 3.
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"url == %@", self.request.URL.absoluteString];
    [fetchRequest setPredicate:predicate];
 
    // 4.
    NSError *error;
    NSArray *result = [context executeFetchRequest:fetchRequest error:&error];
 
    // 5.
    if (result && result.count > 0) {
        return result[0];
    }
 
    return nil;
}
- (void)startLoading {
    // 1.
    CachedURLResponse *cachedResponse = [self cachedResponseForCurrentRequest];
    if (cachedResponse) 
            
           

相關推薦

利用NSURLProtocol實現webView快取

註冊自定義protocol handler MyURLProtocol - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc

利用ImageLoader實現imageView快取

public class MyPagerAdapter extends PagerAdapter { private List<Lunbo.DataBean> list; private Context context; public MyPagerAdapter(List

利用Varnish實現CDN快取

一.Varnish的簡要介紹 Varnish是一款高效能的開源HTTP加速器,具有反向代理,快取的功能,主要用來作為反向代理中的快取伺服器。 Varnish使用記憶體快取檔案來減少響應時間和網路頻寬消耗。 二.Varnish作為快取伺服器與Squid對比如下:

使用NSURLProtocol實現離線快取

一、說明:NSURLProtocol可以攔截任何網路請求,包含UIWebView中發出的所有請求。但是在WKWebView中,只能攔截到最初始的請求,內嵌的資源下載攔截不到。比如通過WKWebView載

【iOS】通過NSURLProtocol實現網頁載入本地快取資料

一.專案需求 專案中有個海報生成功能,使用UIWebView載入一些網頁,因為海報使用率比較高,有時載入網頁比較慢會影響使用者體驗,因此我們在APP啟動後,將一些固定資源,如css、圖片等,先快取到本地。載入網頁時,通過NSURLProtocol,優先使用本地的檔案,以加快網頁載入速

利用AOP實現一個簡單的快取儲存、清除的工具

基本要求:利用aop實現一個簡單的快取儲存、清除的工具,從實際使用上來說,切面應該在provider層。在service層方法呼叫和資料庫查詢之間生效。為了簡化過程,不要求與資料庫互動,資料可以隨機生成,不要求使用redis等中介軟體,可以直接快取到記憶體中。 程式碼實現非常的基礎,能夠很好

SpringBoot30 整合Mybatis-Plus、整合Redis、利用Ehcache和Redis分別實現二級快取

1 環境說明   JDK: 1.8   MAVEN: 3.   SpringBoot: 2.0.4 2 SpringBoot整合Mybatis-Plus   2.1 建立SpringBoot     利用IDEA建立SpringBoot專案,引入web mysql mybatis-plus lombok

利用spring的AOP來實現Redis快取

為什麼使用Redis 資料查詢時每次都需要從資料庫查詢資料,資料庫壓力很大,查詢速度慢,因此設定快取層,查詢資料時先從redis中查詢,如果查詢不到,則到資料庫中查詢,然後將資料庫中查詢的資料放到redis中一份,下次查詢時就能直接從redis中查到,不需要查

Java 利用Map實現快取

一、快取工具類 package com.zsplat.yyzx.util; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 快取機制

利用GeoWebCache實現WebGIS地形圖展示的快取優化

1.前言 我將前端瓦片的來源分為了兩種,一種是線上瓦片,一種是離線瓦片。但是如果我們深究瓦片的真正來源,無法是來至三個切圖工具:ArcGIS的切圖工具,城管局的切圖工具以及公司的切圖工具。當然,有時候我們也能看到來至於天地圖的切圖工具或者其他第三方切圖工具。這裡,我跟大家介紹另外一種切圖工具——Ge

利用ehcache2.6實現資料快取

對於一個大專案中利用快取來提高使用者訪問資料的速度和減小資料庫的壓力是很有必要的,今天就要跟大家分享一下利用ehcache實現資料快取。具體步驟如下: 1.編寫ehcache.xml。這裡面一定要有預設的快取,然後自己可以寫一個快取。 快取引數解釋: ma

Android之 -WebView實現離線快取閱讀

前言 本篇部落格要實現的是一個離線下載和離線閱讀的功能,這是很多閱讀類app都常見的一個功能,典型的應用就是網易新聞。什麼是離線下載?其實這個概念是比較模糊,是離線之後下載呢,還是下載之後離線,但稍微有點腦子的人都知道沒有網路之後怎麼下載呢?所以離線下載這個功能是”在有網路的情況下,把資源下載到本地“,離線

利用Ajax實現分頁快取

用原生JavaScript寫資料分頁快取,看教學視訊寫的,下面是詳細程式碼。 <!doctype html> <html> <head><title>index</title><meta charset="u

iOS開發 最新的NSURLProtocolwebView的離線快取快取webView,離線載入

四:1.+ (BOOL)canInitWithRequest:(NSURLRequest *)request; 作用:(1).處理返回YES,不處理返回NO (2).打標籤,已經處理過的不在處理 這篇文章有具體說明:http://www.jianshu.com/p/7c89b8c5482a 2.+ (NSU

PHP實現資料快取的方法利用檔案快取

//如果檔案生產失敗,多半是當前檔案沒有建立檔案與目錄的許可權,請給予許可權即可 //這裡呼叫快取,使用方法類是TP的S方法 if(!$cate = CacheHtml('IndexModelPlodesadasdw')){ $cate = array('asdsad

iOS如何實現網頁快取(實現webView快取)

樓主提供一個最簡單的方法: 以下程式碼直接複製即可使用. viewDidLoad裡邊程式碼如下:_urlStr為網頁連結     NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesD

Java利用Redis實現消息隊列

.get keys rpo throws max del 鍵值 先進先出 instance 應用場景 為什麽要用redis?二進制存儲、java序列化傳輸、IO連接數高、連接頻繁 一、序列化   這裏編寫了一個java序列化的工具,主要是將對象轉化為byte數組,和根

利用Tensorflow實現神經網絡模型

flow one 什麽 hold test ase tensor dom def 首先看一下神經網絡模型,一個比較簡單的兩層神經。 代碼如下: # 定義參數 n_hidden_1 = 256 #第一層神經元 n_hidden_2 = 128 #第

利用Sentinel實現Redis主從切換

edi nbsp ilo bind redis poc 自主 日誌 sent 利用Sentinel(哨兵)實現Redis集群的故障自主切換 首先部署redis主從集群,這裏忽略過程,主要看配置文件: master: bind 0.0.0.0 port 6801 log

利用FT232實現USB轉串口

可能性 olt documents generated ply pl2 繪制 很好 ner FT232B數據手冊:http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232BL_BQ.pdf 常用的US