• 协议(实现模块)层对缓存机制的支持。


    @interface JWCacheURLProtocol : NSURLProtocol<NSURLSessionDataDelegate>

    - (void)startLoading{

        NSCachedURLResponse *urlResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:[self request]];

        if (urlResponse) {

            //如果缓存存在,则使用缓存。并且开启异步线程去更新缓存

            [self.client URLProtocol:self didReceiveResponse:urlResponse.response cacheStoragePolicy:NSURLCacheStorageNotAllowed];

            [self.client URLProtocol:self didLoadData:urlResponse.data];

            [self.client URLProtocolDidFinishLoading:self];

            [self backgroundCheckUpdate];

        }

        

        NSMutableURLRequest *mutableRequest = [[self request] mutableCopy];

        

        [NSURLProtocol setProperty:@YES forKey:URLProtocolAlreadyHandleKey inRequest:mutableRequest];

        

        [self netRequestWithRequest:mutableRequest];

    }

    重新实现了一次网络请求,并将网络请求的数据进行了一次转发

    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

    {

      [[self client] URLProtocol:self didLoadData:data];

      [self appendData:data];

    }

    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

    {

      [[self client] URLProtocol:self didFailWithError:error];

      [self setConnection:nil];

      [self setData:nil];

      [self setResponse:nil];

    }

    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

    {

      [self setResponse:response];

      [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];  // We cache ourselves.

    }

    - (void)connectionDidFinishLoading:(NSURLConnection *)connection

    {

      [[self client] URLProtocolDidFinishLoading:self];

      NSString *cachePath = [self cachePathForRequest:[self request]];

      RNCachedData *cache = [RNCachedData new];

      [cache setResponse:[self response]];

      [cache setData:[self data]];

      [NSKeyedArchiver archiveRootObject:cache toFile:cachePath];

      [self setConnection:nil];

      [self setData:nil];

      [self setResponse:nil];

    }

    @interface RNCachingURLProtocol : NSURLProtocol

    - (void)startLoading

    {

      if (![self useCache]) {

        NSMutableURLRequest *connectionRequest = 

    #if WORKAROUND_MUTABLE_COPY_LEAK

          [[self request] mutableCopyWorkaround];

    #else

          [[self request] mutableCopy];

    #endif

        // we need to mark this request with our header so we know not to handle it in +[NSURLProtocol canInitWithRequest:].

        [connectionRequest setValue:@"" forHTTPHeaderField:RNCachingURLHeader];

        NSURLConnection *connection = [NSURLConnection connectionWithRequest:connectionRequest

                                                                    delegate:self];

        [self setConnection:connection];

      }

      else {

        RNCachedData *cache = [NSKeyedUnarchiver unarchiveObjectWithFile:[self cachePathForRequest:[self request]]];

        if (cache) {

          NSData *data = [cache data];

          NSURLResponse *response = [cache response];

          NSURLRequest *redirectRequest = [cache redirectRequest];

          if (redirectRequest) {

            [[self client] URLProtocol:self wasRedirectedToRequest:redirectRequest redirectResponse:response];

          } else {

              

            [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; // we handle caching ourselves.

            [[self client] URLProtocol:self didLoadData:data];

            [[self client] URLProtocolDidFinishLoading:self];

          }

        }

        else {

          [[self client] URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCannotConnectToHost userInfo:nil]];

        }

      }

    }

    其它

     @return 图片资源
     */
    - (void)getData:(GetDataCompletion)completion {
        NSURL *url = [NSURL URLWithString:kLastModifiedImageURL];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:15.0];
    
        //    // 发送 etag
        //    if (self.etag.length > 0) {
        //        [request setValue:self.etag forHTTPHeaderField:@"If-None-Match"];
        //    }
        // 发送 LastModified
        if (self.localLastModified.length > 0) {
            [request setValue:self.localLastModified forHTTPHeaderField:@"If-Modified-Since"];
        }
    
        [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    
            // NSLog(@"%@ %tu", response, data.length);
            // 类型转换(如果将父类设置给子类,需要强制转换)
            NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
            NSLog(@"statusCode == %@", @(httpResponse.statusCode));
            // 判断响应的状态码是否是 304 Not Modified (更多状态码含义解释: https://github.com/ChenYilong/iOSDevelopmentTips)
            if (httpResponse.statusCode == 304) {
                NSLog(@"加载本地缓存图片");
                // 如果是,使用本地缓存
                // 根据请求获取到`被缓存的响应`!
                NSCachedURLResponse *cacheResponse =  [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
                // 拿到缓存的数据
                data = cacheResponse.data;
            }
    
            // 获取并且纪录 etag,区分大小写
            //        self.etag = httpResponse.allHeaderFields[@"Etag"];
            // 获取并且纪录 LastModified
            self.localLastModified = httpResponse.allHeaderFields[@"Last-Modified"];
            //        NSLog(@"%@", self.etag);
            NSLog(@"%@", self.localLastModified);
            dispatch_async(dispatch_get_main_queue(), ^{
                !completion ?: completion(data);
            });
        }] resume];
    }
  • 相关阅读:
    pre 强制换行
    code标签和pre标签的定义
    angularJS绑定数据中对标签转义的处理二 与pre标签的使用
    angularJS绑定数据中对标签转义的处理
    html特殊字符
    js switch的使用 ng-switch的使用方法
    JS转换HTML转义符,防止javascript注入攻击,亲测可用
    MVC,MVP 和 MVVM 的图示 转自阮一峰先生网络日志
    AngularJs ngReadonly、ngSelected、ngDisabled
    你应该知道的jQuery技巧
  • 原文地址:https://www.cnblogs.com/feng9exe/p/7206614.html
Copyright © 2020-2023  润新知