Charles抓取https请求 ssl证书问题
如何使用Charles抓取https请求
设置Charles
1.Charles -> 工具栏 -> Proxy -> Proxy Setting
1.设置Port(默认8888)
2.勾选 Enable Transparent HTTP Proxying
2.Charles -> 工具栏 -> Proxy -> SSL Proxy Setting
1.勾选Enable SSL Proxying
2.在Location部份选择add,抓取任意站点、443端口的数据
设置手机代理
1.查看内网IP地址
Charles -> 工具栏 -> Help ->Local IP Addresses
2.手机设置代理端口
3.Safari中跳转 chls.pro/ssl 下载Charles证书
4.设置 -> 通用 -> 关于本机 -> 证书信任设置 -> 信任Charles证书
iOS响应者链、事件的传递
##iOS响应者链、事件的传递
1、响应链的传递
Responder一点也不神秘————iOS用户响应者链完全剖析(建议全看)
看完上面一篇应该能完全熟悉了响应链的传递,自己可以打印一下响应链看看,代码如下:
- (IBAction)click:(id)sender {
UIResponder *res = sender;
while (res) {
NSLog(@"*************************************\n%@",res);
res = [res nextResponder];
}
}
2、Hit-Test 机制
当用户触摸(Touch)屏幕进行交互时,系统首先要找到响应者(Responder)。系统检测到手指触摸(Touch)操作时,将Touch 以UIEvent的方式加入UIApplication事件队列中。UIApplication从事件队列中取出最新的触摸事件进行分发传递到UIWindow进行处理。UIWindow 会通过hitTest:withEvent:方法寻找触碰点所在的视图,这个过程称之为hit-test view。
hitTest 的顺序如下
UIApplication -> UIWindow -> Root View -> ··· -> subview
在顶级视图(Root View)上调用pointInside:withEvent:方法判断触摸点是否在当前视图内;
如果返回NO,那么hitTest:withEvent:返回nil;
如果返回YES,那么它会向当前视图的所有子视图发送hitTest:withEvent:消息,所有子视图的遍历顺序是从最顶层视图一直到到最底层视图,即从subviews数组的末尾向前遍历,直到有子视图返回非空对象或者全部子视图遍历完毕。
如果有subview的hitTest:withEvent:返回非空对象则A返回此对象,处理结束(注意这个过程,子视图也是根据pointInside:withEvent:的返回值来确定是返回空还是当前子视图对象的。并且这个过程中如果子视图的hidden=YES、userInteractionEnabled=NO或者alpha小于0.1都会并忽略);
如果所有subview遍历结束仍然没有返回非空对象,则hitTest:withEvent:返回self;
系统就是这样通过hit test找到触碰到的视图(Initial View)进行响应。
如果还不清楚Hit-Test 机制,看更加清晰的Hit-Test 机制(建议还不清楚的看)
3、手势的原理及与touches系列的关系,具体的可以看iOS触摸事件传递响应之被忽视的手势识别器工作原理(建议不看也没关系,结论在下面了。)
简而言之,就是下面这幅图了。触摸事件会优先分发给附在view的手势,在这段延迟的期间,如果手势被识别,那么view的touches系列将被立刻取消,如果没有被识别,那么会继续我们所熟知的touches系列流程。
4、实际开发中常见的相关问题
在实际开发中,经常会遇到视图没有响应的情况,特别是新手会经常搞不清楚状况。
一下是视图没有响应的几个情况:
1.userInteractionEnabled=NO;
2.hidden=YES;
3.alpha=0~0.01;
4.没有实现touchesBegan:withEvent:方法,直接执行touchesMove:withEvent:等方法;
5.目标视图点击区域不在父视图的Frame上 (superView背景色为clear Color的时候经常会忽略这个问题)。
5、手势代理
ios手势识别代理,看这个基本上就够了。引用文章中的一段话,如下:
- 当时做项目时这个主控制器就是RootViewController,虽然用的是ScrollView但也没考虑到导航栏的手势返回的问题 ,现在做小区宝3.0的闪购订单,用之前的就有问题了。导航栏的返回手势用不了,根据响应者链和响应事件,手势被ScrollView识别了,就到不了导航的手势识别,所以导致无法手势返回。
我也曾经处理过这样的问题,不过我那时候是带有QQ的侧滑功能,主控制器用的View是ScrollView,导致不能侧滑。但是处理的方法都是一样的,自定义的ScrollView的代码重写gestureRecognizerShouldBegin方法如下,我是手势方向向右并且x轴起点小于60px的,让ScrollView的手势失效。这样就不会截获对应的事件了。但是其实看完上面,还有更简单的方法,就是让ScrollView的手势共存,但是这样可能会带来一些其它的问题。shouldRecognizeSimultaneouslyWithGestureRecognizer设置为true,不过应该要判断手势为UIScreenEdgePanGestureRecognizer时才return true,这样就可以了。
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
CGPoint velocity = [(UIPanGestureRecognizer *)gestureRecognizer velocityInView:self];
CGPoint location = [gestureRecognizer locationInView:self];
NSLog(@"velocity.x:%f----location.x:%d",velocity.x,(int)location.x%(int)[UIScreen mainScreen].bounds.size.width);
if (velocity.x > 0.0f&&(int)location.x%(int)[UIScreen mainScreen].bounds.size.width<60) {
return NO;
}
return YES;
}
案例分析
案例一
下面这种做法,除非你很熟悉,否则不要这么干。因为 [super touchesBegan:touches withEvent:event];会执行原来默认的操作,如果按钮本来就没有添加对应的事件。那么[[self nextResponder] touchesBegan:touches withEvent:event];和[super touchesBegan:touches withEvent:event];将会向下一响应者发送两次事件。
-(void)touchesBegan:(NSSet<uitouch *> *)touches withEvent:(UIEvent *)event{
if (self.enableNextResponder) {
[[self nextResponder] touchesBegan:touches withEvent:event];
[super touchesBegan:touches withEvent:event];
}
}
案例二
Window
-ViewA(能响应)
-ButtonA
-ViewB(不响应)
假设ViewB完全覆盖在ButtonA上,结果是:
ViewA能触发
Button没反应
ViewB没反应
简单来说,ViewB能阻隔ButtonA的响应,但是不能阻隔ViewA的响应。假设ViewB是个遮罩,那么并不是阻隔ViewA的事件触发。
案例三
一个按钮添加了点击事件到底发生了什么事儿。
我们有时候需要使用到一些特殊的情况,比如:
1、A包含B,AB都响应事件。
对于普通View,根据响应链,让B作为第一个响应者处理,然后B根据nextResponder传递触摸事件。
针对手势做分析:
手势不会走view的touches系列方法,但有自己的一系列touches方法,不过没有暴露出来。但是shouldRecognizeSimultaneouslyWithGestureRecognizer也可以做到。
针对UIButton的分析:
UIButton addTarget分析,addTarget是UIControl的方法,其实addTarget的方法原理是,UIControl对touches的触摸事件的封装。[super touchesBegan:touches withEvent:event];包括了对
事件的封装处理,如果重新了[super touchesBegan:touches withEvent:event];,并且里面什么都不实现,那么当前UIButton添加的addTarget所绑定的所有事件都不会触发。因为覆盖了父类UIControl的封装方法。
如果我想一个按钮的事件触发,并且它的下一响应者也能触发相应的事件。那么该怎么处理呢?
我们在按钮上处理,重写touchesBegan系列的方法,那么根据上面所说,必须要调用super的方法,并且主动像下一响应者[self nextResponder]发送touchesBegan系列的方法。
2、A包含B、C,C在B的上面,但是想让B接收事件,C不接收事件
这种可以这么处理,自定义C的View,重写hitTest:withEvent方法,返回nil,这样自定义C的View及其子类都不会拦截事件。这样B就可以顺利处理事件。
还可以把C的userInteractionEnabled设置为NO
3、A是B、C的父视图,C在B的上面,这时候,CB都处理事件。这样到底行不行?根据响应链,这样应该是不靠谱的了。在C的touches方法中调用C的touches方法,然后重写B的touches方法,但是这样怪怪的。有什么高招也请多多指教。貌似也没有这样的必要。
最后还发现了一篇一步到位的iOS响应者链的全过程:iOS触摸事件的流动(想有更清晰的了解的看)
直接引用里面的一张图:
参考资料:
响应者链及相关机制总结
iPhoneX适配
一. iPhone手机各版本尺寸
机型 | 发布时的系统 | 屏幕尺寸 | 比例 | pt | 像素 |
---|---|---|---|---|---|
iPhone4 | iOS 4 | 3.5英寸 | 3:2 | 320*480pt | 960X640 |
iPhone4S | iOS 5 | 3.5英寸 | 3:2 | 320*480pt | 960X640 |
iPhone5 | iOS 6 | 4英寸 | 16:9 | 320*568pt | 1136X640 |
iPhone5C/5S | iOS 7 | 4英寸 | 16:9 | 320*568pt | 1136X640 |
iPhone6 | iOS 8 | 4.7英寸 | 16:9 | 375*667pt | 1334X750 |
iPhone6Plus | iOS 8 | 5.5英寸 | 16:9 | 414*736pt | 1920X1080 |
iPhone6S | iOS 9 | 4.7英寸 | 16:9 | 375*667pt | 1334X750 |
iPhone6SPlus | iOS 9 | 5.5英寸 | 16:9 | 414*736pt | 1920X1080 |
iPhoneSE | iOS 9 | 4英寸 | 16:9 | 320*568pt | 1136X640 |
iPhone7 | iOS 10 | 4.7英寸 | 16:9 | 375*667pt | 1334X750 |
iPhone7Plus | iOS 10 | 5.5英寸 | 16:9 | 414*736pt | 1920X1080 |
iPhone8 | iOS 11 | 4.7英寸 | 16:9 | 375*667pt | 1334X750 |
iPhone8Plus | iOS 11 | 5.5英寸 | 16:9 | 414*736pt | 1920X1080 |
iPhoneX | iOS 11 | 5.8英寸 | 18:9 | 375*812pt | 2436X1125 |
iPhoneXs | iOS 12 | 5.8英寸 | 18:9 | 375*812pt | 2436X1125 |
iPhoneXr | iOS 12 | 6.1英寸 | 18:9 | 414*896pt | 1792X828 |
iPhoneXs Max | iOS 12 | 6.5英寸 | 18:9 | 414*896pt | 2688X1242 |
Library not loaded问题
Xcode8报错 Library not loaded:
/System/Library/Frameworks/UserNotifications.framework/UserNotifications
调试时Xcode报错
低版本手机中 UserNotifications框架不支持
Target下的Build Phases标签里,找到Link Binary With Libraries,在里面找到UserNotifications.framework,把status由Required修改成Optional
WKWebView问题
WKWebView无法响应H5页面中的location.href
根据WKWebView代理方法 WKNavigationDelegate拦截location.herf动作
1 | - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { |
WKWebView如何使用JS调用原生方法
1.设置WKScriptMessageHandler,注册js方法
1 | WKWebViewConfiguration *config = [WKWebViewConfiguration new]; |
2.实现WKWebView的WKScriptMessageHandler代理方法
1 | -(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message |
NSMutableArray删除时遇到的问题
一. removeObjectAtIndex和removeObject的不同之处
removeObjectAtIndex:
删除指定NSMutableArray中指定index的对象,注意index不能越界。
removeObject:
删除NSMutableArray中所有isEqual:待删对象的对象
从API文档可以看出,两者之间的主要区别是
removeObjectAtIndex:
最多只能删除一个对象,而removeObject:
可以删除多个对象(只要符合isEqual:的都删除掉)。
svn
一. 查看当前文件下修改
1 | svn status |
二. 提交当前文件夹下修改文件
1 | a. svn ci -m "还原confi.h文件 " Additions/heads/Config.h (单个文件) |
markdown语法
markdown是一种纯文本格式的标记语言。通过简单的标记语法,它可以使普通文本内容具有一定的格式。
一、标题
在想要设置为标题的文字前面加#来表示
一个#是一级标题,二个#是二级标题,以此类推。支持六级标题。
注:标准语法一般在#后跟个空格再写文字,貌似简书不加空格也行。
cocoaPods的使用
一、什么是CocoaPods
每种语言发展到一个阶段,就会出现相应的依赖管理工具,例如 Java 语言的 Maven,nodejs 的 npm。随着 iOS 开发者的增多,业界也出现了为 iOS 程序提供依赖管理的工具,它的名字叫做:CocoaPods。