业余时间研究了一下手机迅雷的嗅探功能,感觉很神奇。于是想自己动手做一个。
需求很简单:1.拦截并记录网页里所有的有.m3u8的链接 2.使用链接投屏到电视机
拦截网络请求
在iOS中,拦截网页的跳转URL可以使用webview的delegate中相应的方法,但是拦截webview中的网络请求就不行了。这个时候就要用到今天的主角NSURLProtocol 。
本文只实现拦截网络部分NSURLProtocol 的使用。
- 实例化
NSURLProtocol
NSURLProtocol 不能直接使用需要继承子类去实例化。
创建子类SechemaURLProtocol继承自NSURLProtocol
SechemaURLProtocol.h
1 2 3 4 5 6 7 8 9
| #import <Foundation/Foundation.h> #import "Constant.h"
FOUNDATION_EXTERN NSString *const HttpProtocolKey; FOUNDATION_EXTERN NSString *const HttpsProtocolKey;
@interface SechemaURLProtocol : NSURLProtocol
@end
|
实现SechemaURLProtocol.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| - (void)startLoading{} - (void)stopLoading{} + (BOOL)canInitWithRequest:(NSURLRequest *)request { NSString *scheme = [[request URL] scheme];
if ([request.URL.absoluteString containsString:@".m3u8"]) { [[NSNotificationCenter defaultCenter] postNotificationName:@"showURL" object:request.URL.absoluteString];
} // 判断是否需要进入自定义加载器 if ([scheme caseInsensitiveCompare:HttpProtocolKey] == NSOrderedSame || [scheme caseInsensitiveCompare:HttpsProtocolKey] == NSOrderedSame) { //看看是否已经处理过了,防止无限循环 if ([NSURLProtocol propertyForKey:kURLProtocolHandledKey inRequest:request]) { return NO; } } return YES; }
|
canInitWithRequest 所有网络请求都会走这个方法,在这里分析所有URL并且将信息传递到其他类中。
在webview的类中注册
[NSURLProtocol registerClass:[SechemaURLProtocol class]];
接收通知消息
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showURL:) name:@"showURL" object:nil];
解析URL,并显示相应的URL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| -(void)showURL:(NSNotification *)not{ NSString *string = not.object; NSInteger count = [[not.object mutableCopy] replaceOccurrencesOfString:@"https://" // 要查询的字符串中的某个字符 withString:not.object options:NSLiteralSearch range:NSMakeRange(0, [not.object length])]; if (count > 1) { [self.dic setObject:string forKey:string]; NSArray *arr = [string componentsSeparatedByString:@"https://"]; int current = 0; for (int i = 0 ; i<arr.count; i++) { current++; if ([arr[i] length]==0) { continue; } NSString *tmp=@""; for (int j=0; j<arr.count; j++) { if (j==current) { tmp = [[tmp stringByAppendingString:@"https://"] stringByAppendingString:arr[j]]; } } if (tmp.length !=0) { [self.dic setObject:tmp forKey:tmp]; } } }else { [self.dic setObject:string forKey:string]; } [self.tableView reloadData]; if (self.backgroundView.hidden || self.leftcon.constant == UIScreen.mainScreen.bounds.size.width) { [self.view bringSubviewToFront:self.btn];
[self.view bringSubviewToFront:self.backgroundView]; self.backgroundView.hidden = NO; [UIView animateWithDuration:1 animations:^{ self.leftcon.constant = 0; [self.view layoutIfNeeded]; }]; } }
|
完整代码地址 Github
后续还把网页嗅探功能优化了一下,点击m3u8自动投屏到电视机。
其他还有一些小工具 投屏,WiFi切换等。
如有什么好的点子可以告诉我哦~