一:友盟的错误日志怎么看?
先说说友盟崩溃日志怎么查看的问题, 友盟统计我自己用的是比较多的,因为这个第三方的分享也是有的,就直接把友盟集成进去,统计和第三方分享的功能都是可以用的,利用友盟统计也是可以统计错误信息的,这样就涉及到这个错误日志的查看问题,友盟反馈给你的错误是下面这样的,得分析一下这个日志才能查定位到为题具体是出现在哪一行代码上,日志像下面所示:
我也是上网看到这儿dSYM工具,自己试了一下,还是很好用的,这个工具作者也是开源放到Git上了,这里是工具的下载地址,感谢作者!
由于我们这个是技巧的总结篇,我就不累赘的说怎么使用这个根据了,下面的文章能教你怎么的使用这个工具,作者在GIT上面也有文章说明了怎么使用这个工具,说的也是很详细,这篇文章也可以帮助你,dSYM 文件分析工具。
二:Reason: image not found
这个问题在开发的过程中一般是在库上面体现出来的,说说我自己遇到之后的解决方法吧:
问题就在这个 Optional 和 Required 两个选项:要是遇见了上面说的错误,把你的status改成Optional 这里说明一下这两个选项的含义: Xcode中Link Binary With Libraries的Status含义
Reason: image not found 问题 2018-2-26更新
最近在接入“七陌”客服SDK的时候,也发现了这个问题,但是通过上面的方法是没有办法解决的,在仔细的看了一下这个问题,其实上面的答案我们可以很直观的理解成: 把status设置成le optional 也就是可选的,其实你仔细想一想,这个还真的不是根治这个问题的解决的方式,仔细看了看,根治这个问题的方法是把出现这个错误的SDK添加到下面位置,先看解决办法我们再大概的解释这么做是为了什么:
Embedded Binaries (嵌入式二进制文件)
那添加到这个 Embedded Binaries 是什么意思呢?其实Embedded Binaries 的意思是嵌入的二进制文件,但是这个嵌入并不是嵌入 APP 可执行文件,而是嵌入 APP 的 Bundle 文件。那就又有一个问题,什么是Bundle文件呢?
Bundle 文件,简单理解,就是资源文件包。我们将许多图片、XIB、文本文件组织在一起,打包成一个 Bundle 文件。方便在其他项目中引用包内的资源。
Bundle 文件是静态的,也就是说,我们包含到包中的资源文件作为一个资源包是不参加项目编译的。也就意味着,Bundle 包中不能包含可执行的文件。它仅仅是作为资源,被解析成为特定的 2 进制数据。
这样你就理解我们添加到这里的真正的含义是什么!!
其实还有一种就是添加到下面位置:
这也是没有问题的,道理和前面的理解是一样的!
三: iOS 上避免 SIGPIPE 信号导致的 Crash
这个问题不知道有多少人遇到过,在前段时间写Socket的时候,遇到这个问题,在你的网络不稳定的时候,当Socket链接的时候会出现Crash,解决的办法在网上查找之后又两个常见的方案,自己最近也是在看这个CocoaAsyncSocket的源码,最主要的也就是常见的GCDAsyncSocket这个文件,先一步一步来看这个问题,造一下这个错误,截张图给大家看看,还有一点这个Crash在你Debug的时候你在Xcode上点击下一步程序是还能运行的,但在你手机上的话就直接Crash,其实是很严重的一个错误:
好咯,一时半会造不出来这张图了,在遇到补会来,这个处理的话下下面这篇文章说的也清楚:
如何在 iOS 上避免 SIGPIPE 信号导致的 crash (Avoiding SIGPIPE signal crash in iOS)
代码的话就就是这句:放在你创建Socket之后,或者连接之后都OK。
四:今天用Cocoapods的时候遇到这样一个问题,如下图所示:
这个问题在这里也发出来,看到的就算给大家混个脸熟吧,这个问题解决也简单,在你 pod 的三方下面加上这样一句:
use_frameworks!
这个 use_frameworks! 的解释在这:
在xcode 6.4 中使用swift和object-c混合编程,同时通过cocoapods进行管理的一些问题和解决办法
五:在导入第三方框架的时候,由于Swift的版本出现的问题
Use Legacy Swift Language Version” (SWIFT_VERSION) is required to be configured correctly for targets which use Swift. Use the [Edit > Convert > To Current Swift Syntax…] menu to choose a Swift version or use the Build Settings editor to configure the build setting directly.
这个错误的解决就说下面两点:
1、在Buildsetting 里面设置 Use Legacy Swift Language Version 为YES
2、在Edit里面修改 具体的修改看下图选中选项
六: 这里有你最常用的命令:
这里再说两点我们常用到的小技巧,不是命令行来的,但可能你也能用的着:
1、你pod search .... 某一个三方之后,你怎么退出这个信息显示页面? 这个不需要命令,只要你按一下 Q 键 !!
2、你ping ..... 某一个地址之后,怎么结束这个ping? control + C
七:肯定有人让你获取一下苹果的设备ID:
这里在后面我也会总结出文章,针对的就是最后面的方法,要有人问你,你可以先把各种方式的好坏或者能不能用先说清楚:
UDID ios5.0之后禁止
IDFA 广告ID,ios6.0之后出现,在同一个设备上的所有APP都会获取到相同的值,用户可以在设置-隐私-广告追踪中关闭它的获得,会出现获取不到情况。
IDFV UUID 用户删除应用重新装会随之改变。
MAC地址 ios7.0之后禁止。
UUID + keychain 获取到上面说的UUID之后保存在系统当中,就算用户卸载了APP之后还是能获取到相同的UUID,但是用户刷机或重装系统后uuid还是会改变,越狱的设备可能会出现存储失败的问题!
八:先简单的说一下关于渐变色,代码里面的注释写的是比较详细了,可以仔细的看看代码里的注释,一定有帮助,关于图形绘制这方面的内容没有整理过,等有机会有时间这方面的内容也是需要好好整理一下的。
-(void)drawRect:(CGRect)rect{ /* 颜色空间的创建 */ // 我们最常用的就是RGB色彩 显示三色 CGColorSpaceRef rgbSpaceRef = CGColorSpaceCreateDeviceRGB(); // 这个是灰度色彩 // CGColorSpaceRef graySpaceRef = CGColorSpaceCreateDeviceGray(); // 印刷四色 CMYK色彩 // CGColorSpaceRef cmykSpaceRef = CGColorSpaceCreateDeviceCMYK(); /* const CGFloat *components :数组 每四个一组 表示一个颜色 {r,g,b,a ,r,g,b,a} const CGFloat *locations :表示渐变的开始位置 可以像下面这样写 CGFloat components[8] = {1.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0}; CGFloat locations[2] = {0.0,1.0}; */ UIColor * strokeColor = [UIColor colorWithWhite:0.06 alpha:1.0f]; // 上面的也可以直接写成如下形式: UIColor * gradientLightColor = [UIColor colorWithRed:0.101 green:0.100 blue:0.103 alpha:1.000]; UIColor * gradientDarkColor = [UIColor colorWithRed:0.237 green:0.242 blue:0.242 alpha:1.000]; // NSArray * gradientColors = @[(id)gradientDarkColor.CGColor,(id)gradientLightColor.CGColor]; CGFloat locations[] ={0.0,1.0}; // gradientColors 这个是OC的对象 // 仔细看创建时候的参数可以看到这里需要的是CFArrayRef cg_nullable colors // CFArrayRef 对象 利用 __bridge的知识,把NSArray对象转化成 CFArrayRef CGGradientRef grandRef = CGGradientCreateWithColors(rgbSpaceRef, (__bridge CFArrayRef)gradientColors, locations); // 获取图形上下文 Graphics 绘制 CGContextRef contextRef = UIGraphicsGetCurrentContext(); // 渐变区域裁剪 // CGContextClipToRect(context, CGRectMake(0, 360, 200, 100)); // CGRect rect[5] = {CGRectMake(0, 0, 100, 100),CGRectMake(100, 100, 100, 100),CGRectMake(200, 0, 100, 100),CGRectMake(0, 200, 100, 100),CGRectMake(200, 200, 100, 100)}; // CGContextClipToRects(context, rect, 5); /* 这里也可以理解一下 CGRectInset 和 CGRectOffset CGRect CGRectInset(CGRect rect, CGFloat dx, CGFloat dy) 以rect为核心,dx 和dy 缩小相应的值 CGRect CGRectOffset(CGRect rect, CGFloat dx, CGFloat dy) 以rect左上角为基点,向X轴和Y轴偏移dx和dy像素。 */ // 创建这个rect的目的是找到一个比View的rectX.Y缩小2.0个像素的rect CGRect insetRect = CGRectInset(rect, 2.0, 2.0); // 先给整个context设置填充色 CGContextSetFillColorWithColor(contextRef, strokeColor.CGColor); // 填充指定矩形中的椭圆 Ellipse 椭圆 // 给我们指定的rect绘制一个内切椭圆 CGContextFillEllipseInRect(contextRef, insetRect); // X 坐标加 rect 宽度的值 CGFloat midX = CGRectGetMidX(insetRect); CGFloat midY = CGRectGetMidY(insetRect); // 根据中心点,半径,起始的弧度,最后的弧度,是否顺时针画一个圆弧 // CG_EXTERN void CGContextAddArc(CGContextRef cg_nullable c, CGFloat x, CGFloat y,CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise) // 参数分别是 context 中心点 半径 起始的弧度 结束的弧度 是否顺时针 CGContextAddArc(contextRef, midX, midY, CGRectGetWidth(insetRect) / 2, 0, M_PI * 2, 1); // 设置阴影 CGContextSetShadowWithColor(contextRef, CGSizeMake(0.0f, 0.5f), 2.0f, [UIColor darkGrayColor].CGColor); // 直接在图形上下文中渲染路径 CGContextFillPath(contextRef); // 在画一个比前面小一点的圆弧 CGContextAddArc(contextRef, midX, midY, (CGRectGetWidth(insetRect) - 6) / 2, 0, M_PI * 2, 1); // 裁剪 // CGContextClip 裁剪当前View path 的区域 // CGContextEOClip 这个 CGContextClip(contextRef); CGPoint startPoint = CGPointMake(midX, CGRectGetMaxY(insetRect)); CGPoint endPoint = CGPointMake(midX, CGRectGetMinY(insetRect)); /* CGContextDrawRadialGradient //下面再看一个颜色渐变的圆 //参数1:图形上下文 //参数2:渐变色 //参数3:开始中心点 //参数4:开始半径 //参数5:结束中心点 //参数6:结束半径 //参数7:渲染模式 CGContextDrawRadialGradient(context, gradient, CGPointMake(400, 100), 0.0, CGPointMake(350, 100), 30, kCGGradientDrawsBeforeStartLocation); */ // gradient渐变颜色,startPoint开始渐变的起始位置,endPoint结束坐标,options开始坐标之前or开始之后开始渐变 CGContextDrawLinearGradient(contextRef, grandRef, startPoint, endPoint, 0); CGGradientRelease(grandRef); CGColorSpaceRelease(rgbSpaceRef); }