利用NSURLProtocol
可以获取网页中的资源。例如:图片,js,css,视频,音频等。
代码
继承NSURLProtocol
#import <Foundation/Foundation.h>
FOUNDATION_EXTERN NSString *const kHttpProtocolKey;
FOUNDATION_EXTERN NSString *const kHttpsProtocolKey;
FOUNDATION_EXTERN NSString *const kURLLoadingNotification;
FOUNDATION_EXTERN NSString *const kVideoPlayURLGetNotificationName;
@interface SechemaURLProtocol : NSURLProtocol
@end
#import "SechemaURLProtocol.h"
static NSString *const kURLProtocolHandledKey = @"URLProtocolHandledKey";
NSString *const kHttpProtocolKey = @"http";
NSString *const kHttpsProtocolKey = @"https";
NSString *const kURLLoadingNotification = @"com.wudan.URLLoadingNotificationName";
NSString *const kVideoPlayURLGetNotificationName = @"com.wudan.VideoPlayURLGetNotificationName";
@interface SechemaURLProtocol()<NSURLSessionDelegate>
@property (atomic, strong, readwrite) NSURLSessionDataTask *task;
@property (nonatomic, strong) NSURLSession *session;
@property (nonatomic, strong) NSOperationQueue *queue;
@end
@implementation SechemaURLProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
NSString *scheme = [[request URL] scheme];
if ([request.URL.absoluteString containsString:@".mp4"] ||
[request.URL.absoluteString containsString:@".m3u8"] ||
[request.URL.absoluteString containsString:@".avi"] ||
[request.URL.absoluteString containsString:@".rmvb"] ||
[request.URL.absoluteString containsString:@".flv"] ||
[request.URL.absoluteString containsString:@".3gp"] ||
[request.URL.absoluteString containsString:@".wmv"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:kVideoPlayURLGetNotificationName object:request.URL.absoluteString];
} else if ([request.URL.absoluteString containsString:@".jpg"] ||
[request.URL.absoluteString containsString:@".png"] ||
[request.URL.absoluteString containsString:@".bmp"] ||
[request.URL.absoluteString containsString:@".jpeg"] ||
[request.URL.absoluteString containsString:@".webp"] ||
[request.URL.absoluteString containsString:@".gif"] ||
[request.URL.absoluteString containsString:@".svg"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:kVideoPlayURLGetNotificationName object:request.URL.absoluteString];
} else {
NSLog(@"Other URL ----> %@", request.URL.absoluteString);
}
if ([scheme caseInsensitiveCompare:kHttpProtocolKey] == NSOrderedSame ||
[scheme caseInsensitiveCompare:kHttpsProtocolKey] == NSOrderedSame) {
if ([NSURLProtocol propertyForKey:kURLProtocolHandledKey inRequest:request]) {
return NO;
}
}
return YES;
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
NSMutableURLRequest *mutableReqeust = [request mutableCopy];
return mutableReqeust;
}
+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b {
return [super requestIsCacheEquivalent:a toRequest:b];
}
- (void)startLoading {
NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
[NSURLProtocol setProperty:@YES forKey:kURLProtocolHandledKey inRequest:mutableReqeust];
[[NSNotificationCenter defaultCenter] postNotificationName:kURLLoadingNotification object:mutableReqeust.URL.absoluteString];
NSURLSessionConfiguration *configure = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:configure delegate:self delegateQueue:self.queue];
self.task = [self.session dataTaskWithRequest:mutableReqeust];
[self.task resume];
}
- (void)stopLoading {
[self.session invalidateAndCancel];
self.session = nil;
[[NSNotificationCenter defaultCenter] postNotificationName:kURLLoadingNotification object:@""];
}
#pragma mark - Getter
- (NSOperationQueue *)queue {
if (!_queue) {
_queue = [[NSOperationQueue alloc] init];
}
return _queue;
}
@end
@implementation SechemaURLProtocol(NSURLSessionDelegate)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
if (error != nil) {
[self.client URLProtocol:self didFailWithError:error];
} else {
[self.client URLProtocolDidFinishLoading:self];
}
}
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
completionHandler(NSURLSessionResponseAllow);
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
[self.client URLProtocol:self didLoadData:data];
}
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
willCacheResponse:(NSCachedURLResponse *)proposedResponse
completionHandler:(void (^)(NSCachedURLResponse * _Nullable))completionHandler {
completionHandler(proposedResponse);
}
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
willPerformHTTPRedirection:(NSHTTPURLResponse *)response
newRequest:(NSURLRequest *)newRequest
completionHandler:(void (^)(NSURLRequest *))completionHandler {
NSMutableURLRequest *redirectRequest;
redirectRequest = [newRequest mutableCopy];
[[self class] removePropertyForKey:kURLProtocolHandledKey inRequest:redirectRequest];
[[self client] URLProtocol:self wasRedirectedToRequest:redirectRequest redirectResponse:response];
[self.task cancel];
[[self client] URLProtocol:self didFailWithError:[NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil]];
}
@end
说明
这边代码里面我是根据获取的URL
路径中是否含有该类型字段进行判断。
使用方法
注册类
- (void)registerClass {
NSArray *privateStrArr = @[@"Controller", @"Context", @"Browsing", @"K", @"W"];
NSString *className = [[[privateStrArr reverseObjectEnumerator] allObjects] componentsJoinedByString:@""];
Class cls = NSClassFromString(className);
SEL sel = NSSelectorFromString(@"registerSchemeForCustomProtocol:");
if (cls && sel) {
if ([(id)cls respondsToSelector:sel]) {
[(id)cls performSelector:sel withObject:kHttpProtocolKey];
[(id)cls performSelector:sel withObject:kHttpsProtocolKey];
}
}
[NSURLProtocol registerClass:[SechemaURLProtocol class]];
}
移除
- (void)dealloc {
[NSURLProtocol unregisterClass:[SechemaURLProtocol class]];
}
网友评论