| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| #import "WXResourceLoader.h" |
| #import "WXResourceRequestHandler.h" |
| #import "WXSDKInstance.h" |
| #import "WXLog.h" |
| #import "WXHandlerFactory.h" |
| #import "WXSDKError.h" |
| #import "WXConfigCenterProtocol.h" |
| #import "WXSDKEngine.h" |
| |
| //deprecated |
| #import "WXNetworkProtocol.h" |
| |
| @interface WXResourceLoader () <WXResourceRequestDelegate> |
| |
| @end |
| |
| @implementation WXResourceLoader |
| { |
| NSMutableData *_data; |
| WXResourceResponse *_response; |
| } |
| |
| - (instancetype)initWithRequest:(WXResourceRequest *)request |
| { |
| if (self = [super init]) { |
| self.request = request; |
| } |
| |
| return self; |
| } |
| |
| - (void)setRequest:(WXResourceRequest *)request |
| { |
| if (_request) { |
| [self cancel:nil]; |
| } |
| |
| _request = request; |
| } |
| |
| - (void)start |
| { |
| if ([_request.URL isFileURL]) { |
| [self _handleFileURL:_request.URL]; |
| return; |
| } |
| |
| id<WXResourceRequestHandler> requestHandler = [WXHandlerFactory handlerForProtocol:@protocol(WXResourceRequestHandler)]; |
| if (requestHandler) { |
| [requestHandler sendRequest:_request withDelegate:self]; |
| } else if ([WXHandlerFactory handlerForProtocol:NSProtocolFromString(@"WXNetworkProtocol")]){ |
| // deprecated logic |
| [self _handleDEPRECATEDNetworkHandler]; |
| } else { |
| WXLogError(@"No resource request handler found!"); |
| } |
| } |
| |
| - (void)cancel:(NSError *__autoreleasing *)error |
| { |
| id<WXResourceRequestHandler> requestHandler = [WXHandlerFactory handlerForProtocol:@protocol(WXResourceRequestHandler)]; |
| if ([requestHandler respondsToSelector:@selector(cancelRequest:)]) { |
| [requestHandler cancelRequest:_request]; |
| } else if (error) { |
| *error = [NSError errorWithDomain:WX_ERROR_DOMAIN code:WX_ERR_CANCEL userInfo:@{NSLocalizedDescriptionKey: @"handle:%@ not respond to cancelRequest"}]; |
| } |
| } |
| |
| - (void)_handleFileURL:(NSURL *)url |
| { |
| dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ |
| NSData *fileData = [[NSFileManager defaultManager] contentsAtPath:[url path]]; |
| if (self.onFinished) { |
| self.onFinished([[WXResourceResponse alloc]initWithURL:url statusCode:200 HTTPVersion:@"1.1" headerFields:nil], fileData); |
| } |
| }); |
| } |
| |
| - (void)_handleDEPRECATEDNetworkHandler |
| { |
| WXLogWarning(@"WXNetworkProtocol is deprecated, use WXResourceRequestHandler instead!"); |
| id networkHandler = [WXHandlerFactory handlerForProtocol:NSProtocolFromString(@"WXNetworkProtocol")]; |
| __weak typeof(self) weakSelf = self; |
| [networkHandler sendRequest:_request withSendingData:^(int64_t bytesSent, int64_t totalBytes) { |
| if (weakSelf.onDataSent) { |
| weakSelf.onDataSent(bytesSent, totalBytes); |
| } |
| } withResponse:^(NSURLResponse *response) { |
| _response = (WXResourceResponse *)response; |
| if (weakSelf.onResponseReceived) { |
| weakSelf.onResponseReceived((WXResourceResponse *)response); |
| } |
| } withReceiveData:^(NSData *data) { |
| if (weakSelf.onDataReceived) { |
| weakSelf.onDataReceived(data); |
| } |
| } withCompeletion:^(NSData *totalData, NSError *error) { |
| if (error) { |
| if (weakSelf.onFailed) { |
| weakSelf.onFailed(error); |
| } |
| } else { |
| weakSelf.onFinished(_response, totalData); |
| _response = nil; |
| } |
| }]; |
| } |
| |
| #pragma mark - WXResourceRequestDelegate |
| |
| - (void)request:(WXResourceRequest *)request didSendData:(unsigned long long)bytesSent totalBytesToBeSent:(unsigned long long)totalBytesToBeSent |
| { |
| WXLogDebug(@"request:%@ didSendData:%llu totalBytesToBeSent:%llu", request, bytesSent, totalBytesToBeSent); |
| |
| if (self.onDataSent) { |
| self.onDataSent(bytesSent, totalBytesToBeSent); |
| } |
| } |
| |
| - (void)request:(WXResourceRequest *)request didReceiveResponse:(WXResourceResponse *)response |
| { |
| WXLogDebug(@"request:%@ didReceiveResponse:%@ ", request, response); |
| |
| _response = response; |
| id<WXConfigCenterProtocol> configCenter = [WXSDKEngine handlerForProtocol:@protocol(WXConfigCenterProtocol)]; |
| if ([configCenter respondsToSelector:@selector(configForKey:defaultValue:isDefault:)]) { |
| BOOL isDefault; |
| BOOL clearResponseData = [[configCenter configForKey:@"iOS_weex_ext_config.clearResponseDataWhenDidReceiveResponse" defaultValue:@(NO) isDefault:&isDefault] boolValue]; |
| if(clearResponseData) { |
| _data = nil; |
| } |
| } |
| |
| if (self.onResponseReceived) { |
| self.onResponseReceived(response); |
| } |
| } |
| |
| - (void)request:(WXResourceRequest *)request didReceiveData:(NSData *)data |
| { |
| WXLogDebug(@"request:%@ didReceiveDataLength:%ld", request, (unsigned long)data.length); |
| |
| if (!_data) { |
| _data = [NSMutableData new]; |
| } |
| [_data appendData:data]; |
| |
| if (self.onDataReceived) { |
| self.onDataReceived(data); |
| } |
| } |
| |
| - (void)requestDidFinishLoading:(WXResourceRequest *)request |
| { |
| WXLogDebug(@"request:%@ requestDidFinishLoading", request); |
| |
| if (self.onFinished) { |
| self.onFinished(_response, _data); |
| } |
| |
| _data = nil; |
| _response = nil; |
| } |
| |
| - (void)request:(WXResourceRequest *)request didFailWithError:(NSError *)error |
| { |
| WXLogDebug(@"request:%@ didFailWithError:%@", request, error.localizedDescription); |
| |
| if (self.onFailed) { |
| self.onFailed(error); |
| } |
| |
| _data = nil; |
| _response = nil; |
| } |
| |
| #ifdef __IPHONE_10_0 |
| - (void)request:(WXResourceRequest *)request didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics |
| { |
| WXLogDebug(@"request:%@ didFinishCollectingMetrics", request); |
| } |
| #endif |
| |
| |
| @end |