blob: 9015625900e154703703dcd8e8c9b4ba405c6c0c [file] [log] [blame]
/*
* 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