-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
115 lines (115 loc) · 57.7 KB
/
search.xml
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[马甲包混淆步骤]]></title>
<url>%2F2020%2F08%2F07%2F%E9%A9%AC%E7%94%B2%E5%8C%85%E6%B7%B7%E6%B7%86%E6%AD%A5%E9%AA%A4%2F</url>
<content type="text"><![CDATA[马甲包混淆步骤 利用python脚本先做以下垃圾代码的添加: 创建添加新的类文件,数量自定,主要创建懒加载属性和一些方法 基于旧类文件里面添加垃圾代码,主要添加懒加载属性代码 基于混淆工具对项目做修改: 混淆指定类名称文件 混淆指定方法名 混淆属性名 批量修改图片名称 删除注释 UI上的步骤: APP icon的修改替换 启动图替换 tabbar图片替换 全局图片名称替换,资源压缩有助于md5的值不一致 主体颜色替换 以下为没做但是可以尝试的替换 12345678- 修改view的背景颜色- 大面积修改排序- 修改一些框架的构成,比如把主页的cell改变样式- 修改主体的架构,比如去掉tabbar,改为抽屉式菜单- 修改字体大小- 修改接口请求到的IP- 修改更多的图片,比如默认头像,带有标志性默认图片- pbxproj项目的uuid重构(uuid主要用mac地址+时间生成) 额外情况 一些情况下需要直接跟审核人员对线 开发者账号 账号的干净程度是很重要的,注册的邮箱,绑定的手机号码,登陆过的设备,这些都会影响账号的干净程度。]]></content>
<categories>
<category>iOS经验</category>
</categories>
</entry>
<entry>
<title><![CDATA[老虎证券基于Transferwise的入金于出金]]></title>
<url>%2F2020%2F05%2F27%2F%E8%80%81%E8%99%8E%E8%AF%81%E5%88%B8%E5%9F%BA%E4%BA%8Etransferwise%E7%9A%84%E5%85%A5%E9%87%91%E4%BA%8E%E5%87%BA%E9%87%91%2F</url>
<content type="text"><![CDATA[前言这篇严格来说算是教程篇,但是拖了许久,拖延症这个得治。 transferwise是一家第三方的钱包机构,类似支付宝,支持开户各国的银行账号,支持的国家也挺多,手续费透明,这点还是挺好,没什么坑。 transferwise开户首先你需要拥有一个transferwise(以下简称TF)的账号,其次还需要开通一个美国的银行卡,这样你才能进行各种操作。这里我简单说下,这里我说下我这边的操作: 先在TF注册好账号,之后开通美国银行卡,这里的开通是需要汇入20刀,这里其实卡住不少人,毕竟来这里就是没美金,但是非要汇入美金才可以开户,有点坑 我利用了全球付(globalcash)来完成这个操作,注册记得选择美金账号,首次最低汇入50刀,可以用微信转账汇入。 之后在TF里就可以汇款了,你可以只汇款20,也可以汇款50,如果你以后不想用全球付,就都汇入到TF,反正转过去的钱也是你的,不过需要注意有手续费,不是很多,具体看金额。 终于完成了开户了,这个时候你想问,那么我应该如何汇款到TF里面呢?难道用全球付?但是全球付的汇率不划算啊,所以我用了支付宝,对,就是支付宝,支付宝有个小程序,跨境汇款,中国汇出手续费50人名币,汇率按支付宝汇率,是不是非常划算。 利用你TF的美国银行信息,在支付宝的跨境汇款填写清楚,然后进行汇款,一般时间是3个工作日。 注意,国际汇款是有双向手续费的,也就是说,中国出去会收你手续费,也就是50人名币,还有所谓的中转站银行也会收取手续费,TF是不收的。 以我为例,我从支付宝转了700美金,到了TF实际收到695.5美金,实际手续费是50人名币+4.5美金。 如果你成功从支付宝充值到了TF,那么也就成了,后面的事情就简单多了 老虎入金老虎证券的入金有很多方式,我算了下用TF的方式虽然麻烦,但是相对来说手续费是最低的,而且TF没有管理费,就是前期开户麻烦点,说下关于老虎的入金步骤: 打开老虎证券,选存入美元 选择华美银行,因为只有华美银行的收款地区是USA,同国家转账费用是最低的 打开TF,选择send USD,输入要入金的金额,实测不管你汇入老虎多少钱,手续费固定只收取1.4美金 之后按照老虎证券的地址填写就可以 对了,在TF填写的最后一项留言,可以把老虎的转账附言那串输入填写进去就可以 付款后记得在老虎这边点通知查收,输入汇款金额好让老虎那边更快汇入到你的账户 老虎出金当你玩腻了美股,或者需要用钱了,或者亏钱了,需要出金了,那么也有几个选择,要么直接汇入到中国账号,我没试过这样是否划算,以后有机会试试吧。所以依旧利用TF来出金。 在老虎点击提取资金,填写提取的银行账号信息 这里有个坑,最后一栏是填写美国ABA号码,如果你按照TF的ABA去填写,那么会出金失败,这里其实你要填写的是TF的Wire transfer number这个号码。 实测提取2000美金,到TF只有1981美金,被收取了19手续费,差不多1%的手续费 一般第二天钱就到账了,这个钱你肯定是拿到国内账号的,所以你需要在TF内部转为人名币,汇率和手续费也是透明的。 实测100到转人民币手续费为1.18美金,汇率为7.10969。手续费大概为1.18% 转为人民币后,汇入中国账号,TF提供了支付宝的方式,填写一个支付宝账号,输入汇款金额,马上就能在支付宝收到了。这个过程无手续费产生! 需要在支付宝做一下确认即可 总结在美股玩的这段时间,套路学了不少,学了不少金融知识,果然要自己花钱才学的到哈哈哈哈哈哈哈哈,总结就是,可以玩,但是不要多,毕竟,玩不起,稍微玩玩学下就好。]]></content>
<categories>
<category>闲谈</category>
</categories>
</entry>
<entry>
<title><![CDATA[iOS APP项目整理]]></title>
<url>%2F2018%2F11%2F20%2FiOS%20APP%E9%A1%B9%E7%9B%AE%E6%95%B4%E7%90%86%2F</url>
<content type="text"><![CDATA[iOS APP项目整理我自己的项目2014.04-至今:年龄相机 | 娱乐工具APP独立完成的个人APP,可以检测出照片人物年龄,识别性别还有动物品种,通过Admob广告盈利,自2014年4月上线至今已有400K左右下载量;后续又制作了微信小程序版本; 项目链接:https://itunes.apple.com/cn/app/id845996071 GitHub链接:https://github.com/chenfengfeng/AgeDistinguish 使用swift语言进行开发 使用face++接口来进行识别人物相片 使用谷歌Admob广告平台嵌入广告 已在GitHub上开源 2018.01-至今:SS-VPN | 翻墙工具独立完成的个人APP,已下线中国区,一键自动翻墙,采取shadowsocks连接模式; 目前项目已经开源在GitHub提供技术学习; GitHub链接:https://github.com/chenfengfeng/ss-vpn 采用swift语言开发 基于NEKit网络框架搭建 支持多IP自动ping地址并且切换IP 从做iOS至今,已经做过不少APP了,虽然都没赚钱,但至少丰富了自己,也锻炼了自己,让自己知道APP Store的规则和规范,避免以后出现的问题,我的账号目前已经上架了8款APP,不过我觉得拿得出手的也就上面提到的两个,其他都是充数,233 公司项目2018.01-2018.10:声夕 | 声音社交APP给有思想、有情怀的人一片净土,用最真实的声音记录最绚烂的人生。 项目链接:https://itunes.apple.com/cn/app/id1358222995 独立开发,使用swift语言完成整体开发 基于YYKit框架完成项目主体框架 基于Alamofire完成整体网络框架 使用音频和线程完成语音播放 自定义网易云信私聊第三方模块 多语言版本切换显示和夜间模式切换 2017.03-2018.10:游戏档案 | 游戏社区APP游戏档案GMDOC的目标是成为玩家们的记忆存档点,为他们保存珍贵的游戏回忆。 项目链接:https://itunes.apple.com/cn/app/id1217343635 独立开发,使用swift语言完成整个项目 基于YYKit框架完成项目主体框架 基于Alamofire完成整体网络框架 使用UITableView、UICollectionView等完成自定义数据展示并优化内存显示 仿微博feed显示圈子 更新迭代各种功能 2016.10-2017.03:OnlyS | 瘦身工具APP【OnlyS】一个汇聚全球优秀减脂瘦身方法的应用。 项目链接:https://www.qimai.cn/app/baseinfo/appid/1169918968 独立开发,使用Objective-C语言完整整体项目 基于AFNetworking实现网络框架 利用MVC设计模式,以及单例,代理,懒加载等、实现了项目的良好架构设计 使用UITableView、UICollectionView等完成自定义数据展示 自定义类似朋友圈界面 使用YYKit处理各种图片和模型 使用Charts开源框架绘制曲线 使用UIView动画完成一些动画效果 2015.11-2016.09:不二听 | 佛家音乐社交APP二听是一款为佛教信众研发的软件产品,软件中,无上清净的佛乐,沁入心灵,静心苦修的寺院大师,阐释佛法,芸芸信众,结缘而来。 项目链接:https://www.qimai.cn/app/baseinfo/appid/1092426529 带领两位iOS同事共同完成项目开发,负责架构和主要功能设计 使用Objective-C语言完整整体项目 分配安排任务给开发小组成员 基于AFNetworking实现网络框架 自定义评论回复界面(微信朋友圈类型) 使用利用SDWebImage处理图片 使用豆瓣开源框架播放音频 使用环信框架搭建群聊社区 2015.01-2015.09:触电 | 智能家居APP触电为爱而生的智能台灯,开启智能硬件时代的生活方式。 项目链接::https://www.qimai.cn/app/baseinfo/appid/980859898 基于AFNetworking实现网络框架 使用UITableView、UICollectionView等完成自定义数据展示 采用FMDB对数据进行存储,并实现对数据的增删改查等操作 使用CoreBluetooth框架连接蓝牙设备 使用利用SDWebImage处理图片 使用UILocalNotification实现闹钟功能 使用原生态AVFoundation框架播放音频视频 2013.03-2014.12:英盛商学院 | 在线教育APP英盛商学院,与你一起,遇见更好的自己! 项目链接:https://itunes.apple.com/cn/app/id740403029 负责整个APP开发,包含了视频播放、视频下载,信息反馈,视频评论,视频购买,社交互动,完整的购买流程,包括整个框架开发和功能开发,包含数据库,HTTP请求,web请求,API请求,内购等等 利用MVC设计模式,常用单例,代理,懒加载等、实现了项目的良好架构设计 自定义封装的网络框架实现网络的异步请求,并对其加以封装方便扩展 采用FMDB对数据进行存储,并实现对数据的增删改查等操作 自定义控件,实现代码的复用 使用sharedSDK实现分享 使用第三方实现各种常见动画]]></content>
<categories>
<category>闲谈</category>
</categories>
</entry>
<entry>
<title><![CDATA[iOS项目开源——SS-VPN]]></title>
<url>%2F2018%2F10%2F10%2FVPN%20APP%E5%BC%80%E6%BA%90%2F</url>
<content type="text"><![CDATA[借鉴和第三方 网络框架:NEKit(https://github.com/zhuhaow/NEKit) RabbitVpnDemo(https://github.com/yichengchen/RabbitVpnDemo) 感谢以上两个项目的帮助,才能有我这个项目的完成,其实目前在设置NEKit的里面很多还是RabbitVpnDemo的东西,我只是稍微做了修改,再次感谢这两个项目! APP概要 支持多个IP自动切换 支持自动ping IP地址是否有效 支持只能从APP内打开链接 支持多语言显示 动效算不算? APP开源地址ss-vpn(https://github.com/chenfengfeng/ss-vpn) 如何编译1234// 终端cd到项目文件夹// 需要使用cocoapod和Carthage,需要先安装环境pod installcarthage update --platform iOS APP页面展示]]></content>
<categories>
<category>开源项目</category>
</categories>
</entry>
<entry>
<title><![CDATA[iOS越狱deb打包之APP打包]]></title>
<url>%2F2018%2F07%2F31%2FiOS%E8%B6%8A%E7%8B%B1deb%E6%89%93%E5%8C%85%E4%B9%8BAPP%E6%89%93%E5%8C%85%2F</url>
<content type="text"><![CDATA[准备工作 Theos(https://github.com/theos/theos) 准备打包的APP 打包套路先安装好Theos 一般来说,最好配置下环境: 12export THEOS=~/theos export PATH=$THEOS/bin:$PATH 1$ git clone --recursive https://github.com/theos/theos.git $THEOS 如果之前已经有配置了,就可以无视了 打开终端,选择你喜欢的目录 12$ cd ~/Desktop$ nic.pl 这里我选择iPhone/tweak模版 填写的项目名之类的自己随意,最后确认创建 打开在桌面你创建的文件夹 新建文件夹 1Layout/Applications 等下编译的APP需要到这个文件夹里面 编译的时候,我选择的是开发者编译打包 把.app的程序复制到刚刚创建的目录,类似这样: 1Layout/Applications/项目.app 打开Makefile文件 123456789101112export THEOS_DEVICE_IP=127.0.0.1export THEOS_DEVICE_PORT=2222include $(THEOS)/makefiles/common.mkTWEAK_NAME = SSVPNSSVPN_FILES = Tweak.xminclude $(THEOS_MAKE_PATH)/tweak.mkafter-install:: install.exec "uicache" 这个是我修改过后的Makefile文件 头两行加入是为了可以用usb调试连接手机安装 1install.exec "uicache" 这句的作用是重建缓存,因为如果不重建缓存,可能会存在APP不能显示的问题 至此构建已经完成了,打开终端 12345678// 编译make// 打包make package// 如果想打包release版本make package debug=0// 如果以上编译和打包没有问题,那么就可以安装到手机make install 剩下的就是上传到源 对了,control文件,是插件的说明文件,如果有必要可以修改下,比如改下介绍,版本之类 感谢大家观看~]]></content>
<categories>
<category>iOS经验</category>
</categories>
</entry>
<entry>
<title><![CDATA[iOS逆向经验-实战事例]]></title>
<url>%2F2018%2F05%2F21%2FiOS%E9%80%86%E5%90%91%E7%BB%8F%E9%AA%8C-%E5%AE%9E%E6%88%98%E4%BA%8B%E4%BE%8B%2F</url>
<content type="text"><![CDATA[实战的对象我平时没事喜欢看小说,一般都是起点的小说,但基本上都是看免费的盗版小说,但是盗版小说的app很多,起初追书神器是不错的app,更新快而且及时,后来改了模式,只有一个源而且所谓的正版源需要扣除币,这种情况下我选择了另一个app,叫笔趣阁app,但这个名字的app在AppStore有很多版本,我选择的是Deborah Carpenter开发的版本,目标版本4.0 为什么要hook这个app呢?其实原本这个app的广告只是在书的列表页面,也就算了,如果你不小心退出后台,或者切换程序,回来后都要等好几秒的视频广告,实在忍无可忍 以下只用于学习,不可以用于商业 准备先看看广告是怎样的 还有一个广告是在退出后台,然后进去的时候出现 我们整理下思路 如果需要去掉广告 那么就要把自己想象成开发者,你广告会怎么添加,以对方的思路去想,然后hook代码,达到去掉广告的效果 我手上的手机是为越狱的iPhone7 所以需要一个脱壳完毕的ipa安装包,先在iPad上运行AppStore版本,脱壳拿到ipa安装包 开干! 新建项目,选择iOS下面的MonkeyApp,由于打算运行在未越狱手机,所以Target App可以不管,其他根据自己正常开发填写就好 项目只能运行在真机上,所以模拟器是不能的,会得到错误提示:Do not support the simulator, please use the real iPhone Device. 项目的文件结构可以查看官网wiki,有写清楚,前期准备工作需要先把ipa拖进/项目名/项目名/TargetApp这里面 打开项目点击Build Setting 拉到最后,找到MONKEYDEV_CLASS_DUMP 改为YES,这个操作上为了可以获取ipa的全部h声明文件,方便可以找到方法名称 主要工作在Logos/项目名Dylib.xm里面进行 准备完成后,插入手机,点击run开始运行 用Reveal进行查看 随便点一个view,可以看到它所属的控制器的名字叫ShelfViewController 这样我们就定位了控制器的名字,到项目文件夹里面有一个JWReader_Headers到文件夹,里面放的就是整个项目的h文件,我用文本编辑器拖入打开,定位打开ShelfViewController 可以看到有很多方法,这个这个思考下到底添加广告的方法在哪里,其实做法有很多,我在里面找不到有添加广告的方法,估计可能是直接在viewdidload方法里面直接初始化,或者在数据加载的时候初始化,这种情况下是无法单独分离出来,但好在我找到了一个属性@property(nonatomic) BOOL showAd; 我们可以试试这个属性能否起作用,那么在什么时候调用这个属性比较好呢 在用reveal查看的时候发现这个是一个UICollectionView所以找下代理方法 (int)numberOfSectionsInCollectionView:(id)arg1这个方法会重复调用,当view刷新的时候也会调用,比较适合拿来用,所以在项目名Dylib.xm中,我们先清空里面原来的代码,不清空也没关系,写入一下代码: 123456789101112131415// 所有属性都需要声明才可以调用,interface的名字随意写,正常情况下为了看清楚都是写当前类的名字@interface ShelfViewController@property(nonatomic) BOOL showAd;@end// hook的控制器,必须指定要hook哪个服务器,这样才能让编译器知道你要修改的控制器%hook ShelfViewController- (int)numberOfSectionsInCollectionView:(id)arg1{ self.showAd = NO; return %orig();// %orig这个是调用原代码的方法,比如源代码返回1,那么%orig也是等于1}%end 写完,就试试吧,插入手机 -> 运行 你会发现广告不见了,那么就证明你猜对了,我们通过修改属性达到了去掉首页广告,那么接下来我们继续,把每次重新打开app都会跳出全屏广告也去掉 其实按照思路,这个也很简单,我们会发现在广告的出现是在我们回到桌面或者切换app后回到app才会出现,所以调用方法就是在AppDelegate里面,我们把AppDelegate的头文件拿出来 按照app的生命周期,我们知道在AppDelegate中有些方法在退出到后台和进入app前会执行,那么我们完全可以hook那些代码,阻止运行,所以我把退出和进入都hook掉,确保不会遗漏 123456789%hook AppDelegate- (void)applicationWillTerminate:(id)arg1{}- (void)applicationDidBecomeActive:(id)arg1{}- (void)applicationWillEnterForeground:(id)arg1{}- (void)applicationDidEnterBackground:(id)arg1{}- (void)applicationWillResignActive:(id)arg1{}%end 如果方法有返回值,那么一定要返回,你可以直接返回nil,但不能不返回 如果没有返回值,那么直接什么都不写,这样原先方法就会被hook掉,不会被执行原代码 运行一波试试,退出到桌面再回来,嗯,没问题,那么就确定了,这是可以的,完美避过广告,虽然可能有些当法的多余的,但不影响使用. 这样一个简单的hook app就这样完成了,这是最简单的hook程序,还有一些困难的,比如修改源码,修改判断if,这些就需要更多的软件去辅助,比如之前介绍的ida与hopper就是用于观察app源码与修改源码,这部分需要学习汇编代码才可以,逆向可以说简单,也可以说复杂的. 学逆向不是为了去破解别人的app,对我来说,最重要的是为了防止别人破解自己的app,我们从逆向的过程中学习,想象自己的app如果被别人拿去,如何才能不被反编译,不被hook 正向和逆向不会冲突,只要一起学习,才能更好的加深自己对于开发的理解,做出更好的程序.]]></content>
<categories>
<category>iOS经验</category>
</categories>
</entry>
<entry>
<title><![CDATA[iOS逆向经验-MonkeyDev初步使用]]></title>
<url>%2F2018%2F05%2F18%2FiOS%E9%80%86%E5%90%91%E7%BB%8F%E9%AA%8C-MonkeyDev%E5%88%9D%E6%AD%A5%E4%BD%BF%E7%94%A8%2F</url>
<content type="text"><![CDATA[详细教程可以看官方wiki https://github.com/AloneMonkey/MonkeyDev/wiki ##安装 安装最新的theos 1sudo git clone --recursive https://github.com/theos/theos.git /opt/theos 安装ldid(如安装theos过程安装了ldid,跳过) 1brew install ldid 如果电脑有好几个Xcode版本,就选择自己需要安装的Xcode版本,没有则忽略 1sudo xcode-select -s /Applications/Xcode-beta.app 默认安装的Xcode为: 1xcode-select -p 安装命令: 1sudo /bin/sh -c "$(curl -fsSL https://raw.githubusercontent.com/AloneMonkey/MonkeyDev/master/bin/md-install)" 更新命令: 1sudo /bin/sh -c "$(curl -fsSL https://raw.githubusercontent.com/AloneMonkey/MonkeyDev/master/bin/md-update)" 卸载命令: 1sudo /bin/sh -c "$(curl -fsSL https://raw.githubusercontent.com/AloneMonkey/MonkeyDev/master/bin/md-uninstall)" 脱壳目前脱壳有几种方法,我觉得当下最简单的无疑是MonkeyApp提供的 之前脱壳需要手机下载脱壳程序,在命令行输入脱壳,之后还需要手动导出到电脑,没错,这些操作都是在手机上完成的!当然脱壳离不开越狱手机,所以手机一定要越狱才可以! 可以参考作者写的文章http://www.alonemonkey.com/2018/01/30/frida-ios-dump/ 脱壳需要配置好环境 找你喜欢的文件夹来clone frida-ios-dump 1git clone https://github.com/AloneMonkey/frida-ios-dump 先安装frida 安装命令: 1sudo pip install frida 里面一般都是直接安装失败,所以需要忽略six这个东东: 1sudo pip install frida --ignore-installed six 手机ssh连接到电脑,这里最好用USB连接到电脑 安装成功frida后就可以检查下是否能够读取手机上现在运行的app 1frida-ps -U 如果能够读取到手机app的信息,那么就说明安装成功,接下来就可以进行脱壳操作,这样环境也搭建好啦 手动脱壳 虽然MonkeyDev提供了自动脱壳,但我如果就是想手动脱壳呢? 前面我们clone了frida-ios-dump就是为了可以手动脱壳的 cd到frida-ios-dump的目录,编辑器打开dump.py 在前面找到ssh连接的相关属性 1234User = 'root'Password = 'alpine'Host = 'localhost'Port = 2222 如果你有修改端口或者密码,要手动改为自己的 ssh连接到iOS设备,并且打开app,输入命令: 1./dump.py + 应用显示的名字 查看app的bundle id可以输入以下命令: 1./dump.py -l 指定bundle id脱壳: 1./dump.py -b com.tencent.xin(示例) 自动脱壳 借用官方截图,首先打开Xcode创建项目 Target App,如果是越狱设备的话可以在Target App填写目标App的名字或者bundle id 在/opt/MonkeyDev/bin/dump.py里面可以指定ip、port以及password,如果有需要也要修改 其实整体很多教程,在wiki里面都有详细说明,MonkeyDev确实是一个很不错的工具,功能也到位,而且对于经常使用Xcode的人来说,确实在Xcode上进行hook很舒服,调试什么的也方便.]]></content>
<categories>
<category>iOS经验</category>
</categories>
</entry>
<entry>
<title><![CDATA[iOS逆向经验-准备工作]]></title>
<url>%2F2018%2F05%2F18%2FiOS%E9%80%86%E5%90%91%E7%BB%8F%E9%AA%8C-%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C%2F</url>
<content type="text"><![CDATA[先说一说为什么要写这个呢,其实只是写记录下自己平时的累积,怕以后忘记了. 或者说,以后重新回过头来看看以前自己写的,感觉挺喜感的,这种感觉就好像你初期写的代码,后来经验丰富了,重新回过头看看自己写的代码,就好像你平时看别人新手写的代码一样,很想吐槽,我现在也很少吐槽别人,谁不是从入门开始呢,吐槽别人并不会让你自己变得更厉害. 目前iOS逆向的环境挺好,有很多优秀的工具,所以对于是否越狱其实不是很看重,当然你如果要修改系统的东西还是需要越狱的. 准备需要的硬件: 一部iOS的设备(有没有越狱都可以) 我目前拥有一部iPad(iOS11.1.1,已越狱)&iPhone(iOS11.3.1未越狱) 需要的软件: MonkeyDev 主要工具 pp助手 管理手机工具,下载越狱ipa reveal 查看app的图层和类名 Hopper 反编译工具 IDA 著名反编译工具 MachOView Macho文件浏览器]]></content>
<categories>
<category>iOS经验</category>
</categories>
</entry>
<entry>
<title><![CDATA[Swift 关于小数限制 String 应用]]></title>
<url>%2F2017%2F04%2F16%2Fswift%20%E5%85%B3%E4%BA%8E%E5%B0%8F%E6%95%B0%E9%99%90%E5%88%B6%20string%20%E5%BA%94%E7%94%A8%2F</url>
<content type="text"><![CDATA[#原由因为需要做到金额的控制,最小金额是角,然后需要判断大于0.5元才可以开启留言功能,所以整理了下 string 的方法,希望能够帮助到需要的人. #开始123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051@IBOutlet weak var money: UITextField!@IBOutlet weak var msg: UITextField!msg.delegate = selfmoney.delegate = selfmoney.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: UIControlEvents.editingChanged)func textFieldDidChange(textField:UITextField){ if textField.text == "" { button.isEnabled = false return } let index = textField.text!.index(textField.text!.startIndex, offsetBy: 1) if textField.text?.substring(to: index) == "."{ textField.text = "" } if ((textField.text?.range(of: ".")) != nil) { if (textField.text?.components(separatedBy: ".").count)! > 2 { textField.text?.remove(at: textField.text!.index(before: textField.text!.endIndex)) } if (textField.text?.components(separatedBy: ".").count)! > 1 { let pos = textField.text?.characters.distance(from: textField.text!.startIndex, to: textField.text!.characters.index(of: ".")!) let str = textField.text?.substring(from: textField.text!.index(textField.text!.startIndex, offsetBy: pos!+1)) if str?.characters.count==2{ textField.text?.remove(at: textField.text!.index(before: textField.text!.endIndex)) } } } button.isEnabled = true }func textFieldDidEndEditing(_ textField: UITextField) { if textField == money { if textField.text == "" { return } let index = textField.text!.index(textField.text!.startIndex, offsetBy: textField.text!.characters.count-1) if textField.text?.substring(from: index) == "."{ textField.text?.append("0") } let cash = Float(textField.text!)! if cash >= 0.5 { msg.isEnabled = true msg.textColor = UIColor.black }else{ msg.isEnabled = false msg.textColor = UIColor.lightGray } } }]]></content>
<categories>
<category>iOS经验</category>
</categories>
</entry>
<entry>
<title><![CDATA[记 OC 转swift3.0 邂逅感]]></title>
<url>%2F2017%2F02%2F28%2F%E8%AE%B0%20OC%20%E8%BD%ACswift3.0%20%E9%82%82%E9%80%85%E6%84%9F%2F</url>
<content type="text"><![CDATA[#起因虽然 swift 出到现在已经有很长一段时间了,还记得最初发布的时候那时候正在流行Flappy Bird这款游戏,我也有下载去玩,那时候记得新语言刚刚放出没多久就有大神用新语言翻了一遍这个游戏,可以看出有代码基础的前提下来开发是完全没啥问题的,那时候只是觉得有趣,但是知道想普及没个几年时间是不行的,那时候也有很多这种言论,而且语法一直在发生改变,每次改变语法都会让之前的代码需要重新修改,跟 OC 这种一沉不变的语言果然是不一样的,所以那时候我也没想去学习,在swift 出3.0后我也只是微微表示下关注而已,并没有想学习的意愿,感觉后面还是 会有4.0,5.0等等..只不过在项目需要用到 chart 这个第三方图表框架,由于这个框架是从安卓那边几乎复制过来, 用 swift 语言编译,API 的相似程度官方都已经说有90多,所以官方连文档也懒得重新写,直接说看安卓的文档就行,我也是因为这样才慢慢去学习swift, 但因为只是改改源代码,所以就么有系统的学习,只是大概了解,所以对于这个语言也是一知半解,等到项目完成后有时间才重新认识下这门新语言. #OC 转 swift 会不会很难?老实说吧,如果你什么语言都不会只会 OC 的话,直接看 swift 是有些晕的,别说你会点 C 基础,没什么用,毕竟只是基础,估计都忘光了.学习这个语言有两个方向,我自己总结是这样的. 直接学习 swift 语言,系统的学习一遍 swift 以 iOS 为标准去学习 swift这两者有什么区别,区别还是有的, 前者需要大量的时间去系统的学习,耗时较久,但是效果杠杠的,充分了解这门语言,可以用于非 iOS 开发.后者其实就是完全为了 iOS 开发而学习这门语言,这种学习方式可以说是一边编程 iOS 一边学习,用到哪些知识的时候再去了解,当然前期的知识肯定是要先了解才能下手的,但这种方式弊端也是很明显,容易走弯路,只能说对于想速成或者说对自己有信息的小伙伴才选择这种方式. #举个栗子说下吧以 iOS 为前提,swift 对于 oc 的区别有什么,我大概说下吧,肯定是不全面,但是也是我自己觉得比较重要的. 属性比如是ViewController页面,属性写在ViewController这个大括号里面 懒加载swift的懒加载就是在属性前面加 lazy 关键字,在大括号内相当于新建另一个最后在 return 给懒加载的属性 宏定义define在 swift 中已经不能使用 #define来宏定义了,所以在界面头部定义可以这样写,但是由于swift 中已经不需要像 oc 一样声明某个头文件,所以如果按照我这样写,其实在其他文件都是可以访问的,相当于你的定义是写在 oc 中的全局文件中. 设置代理在 oc 中,我们设置代理后都是在@interface的类括号后面<>里面去实现,但是 swift 中不是,而是在 class 后面的集成类中直接继承你的代理或者数据源,前面的截图也是这样的. oc 混编到 swift我们很多第三方库是 oc 语言的,但是这并不妨碍我们去使用, swift 也可以直接引用 oc 中的库,使用 cocoapod 可以很容易的集成.集成后需要新建一个桥接文件,如果觉得麻烦,可以直接在项目新建一个类,但是这个类是 objectc 的类,点击创建后会问你要不要自动建立桥接文件,点击 create 后就自动新建了桥接文件并且配置好,不需要繁琐的步骤,然后就可以把刚才新建的oc 类删掉了. oc 在 swift 中的声明在桥接文件# import 你要用到的类,这样你每个类都可以使用了,只不过不会有代码提示,需要自己一个个的敲,但是如果编译不过还是会提示的. oc 在 swift 中的使用你对 swift 有一定的了解后去用的话,就会觉得其实没多大区别,我举个例子 swift 的方法swift 中方法以 func 开头,默认是公有方法,如果想变成私有方法,在 func 前面加private关键字,但其实我经常使用的也只是 func 创建方法,如果有返回值,跟 oc 不一样, oc 是写在括号里面,但是 swift 方法前面没有括号,所以是这样写. 大致意思是这样的,test 是方法名称,名称后面的括号是入参属性,由于没有入参属性所以就只有括号,->后面代表的就是返回值类型,如果你创建一个没有参数没有返回值的,可以直接写 func test(){}这样就可以了,当然括号还是必须的,返回值没有可以省略,可以有多个参数,多个返回值,只要在返回值后面加个逗号就可以继续写,当然需要有个括号包裹起来才可以,如图 点语法swift 中没有了 oc 中的那种空格调用语法,比方说[app delegate]这样的写法, swift 中以点语法为主,最简单的例子: //swift UIApplication.shared.isNetworkActivityIndicatorVisible = true //oc [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 基本上 swift 都是点语法,熟悉后会发现这类语法很常见. swift 中的 blockswift 中也有 block 这种概念,可以多参数,具体还是看图 一些其他的东西 1234567891011121314// 旋转动画let anim = CABasicAnimation(keyPath: "transform.rotation") anim.toValue = M_PI*2//旋转一圈 anim.duration = 0.8//旋转时间 anim.repeatCount = MAXFLOAT//旋转圈数 anim.isRemovedOnCompletion = true refreshBtn.imageView?.layer.add(anim, forKey: nil)//添加动画 //GDC 延迟执行 DispatchQueue.global().asyncAfter(deadline: .now()+2.0) { OperationQueue.main.addOperation { //停止旋转,记得要在主线程执行 self.refreshBtn.imageView?.layer.removeAllAnimations() } } 还有很多东西,但是一时也想不起来,未完待续吧,看有什么就补充下.]]></content>
<categories>
<category>iOS经验</category>
</categories>
</entry>
<entry>
<title><![CDATA[iOS年龄识别APP开源项目]]></title>
<url>%2F2016%2F12%2F21%2FiOS%E5%B9%B4%E9%BE%84%E8%AF%86%E5%88%ABAPP%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE%2F</url>
<content type="text"><![CDATA[年龄识别github 地址:https://github.com/chenfengfeng/AgeDistinguish 这个APP主要用于拍照或者调用相册后检测你的年龄等其他属性.没啥技术含量,这个APP可以说从14年4月就开始的上架到今天,也就是我的第一个上架的APP,维护到现在,其实原本是打算作为了解AppStore来试验的,没想到也会维护到今天,不想自己弄的APP就变成了僵尸应用,希望能够继续维持下去,下图是到现在的下载量 APP也有加入admob,也就是谷歌的广告,收益在前期算是比较客观的,毕竟之前并没有多少做这个,算是钻了个空吧~!哈哈~APP的思想很简单,就只是单独的检测年龄性别等属性,没有所谓的用户系统之分,毕竟觉得一个纯娱乐的APP不应该有太多的复杂的东西存在,下面是这个APP目前的效果图]]></content>
<categories>
<category>开源项目</category>
</categories>
</entry>
<entry>
<title><![CDATA[我与那该死的设计师的曲线之战(iOS-Charts)]]></title>
<url>%2F2016%2F12%2F21%2F%E6%88%91%E4%B8%8E%E9%82%A3%E8%AF%A5%E6%AD%BB%E7%9A%84%E8%AE%BE%E8%AE%A1%E5%B8%88%E7%9A%84%E6%9B%B2%E7%BA%BF%E4%B9%8B%E6%88%98(iOS-Charts)%2F</url>
<content type="text"><![CDATA[前言先直接上图看设计师要求的图片吧 看到这个首页效果的时候觉得微微有点蛋疼,但觉得应该是可以的,没多想后来才知道是我太年轻了。。 找了各种第三方,留给自己时间不多,基本没时间自己做一个出来,所以只能借助第三方,最后决定用 Charts,毕竟是大神而且和安卓一起开发遇到问题也可以一起讨论,start 也破万。 正文不说废话了,直接开始吧,首先由于项目决定使用的语言是 OC 语言,charts 是 swift 语言,所以只能混编,项目最低支持版本8.0 关于charts 怎么集成到 OC 代码里面,我看过简书已经写了很多了,我就不重复了,而且也没什么技术难点,无非就是拖进去就好。我没有使用 pods 毕竟需要修改源码。。想到就略蛋疼。。。 基础集成把 charts 集成好之后就可以使用了,先编译一遍确认能够正常编译通过,通过后就可以开始使用了。先说下基本的设置吧。我是用的曲线,也就是折线的分类,charts 有很多个模块,其他模块我没有去研究,毕竟没那么多时间,如果你用storyboard 创建的,那就是新建一个 view,类的名字直接为LineChartView,如果是代码创建,也是直接用这个类创建一个 view 然后设置 frame 添加到父类 view 上就好了。12345678910111213141516171819// chartview 本身的属性设置self.chartView.delegate = self;// 代理 self.chartView.backgroundColor = [UIColor clearColor];//设置背景颜色 self.chartView.descriptionText = @"";//隐藏描述文字 self.chartView.noDataText = @"暂时没有体重数据";// 设置没有数据的显示内容 self.chartView.legend.enabled = NO;//不显示图例说明 self.chartView.scaleYEnabled = NO;//取消Y轴缩放 self.chartView.scaleXEnabled = NO;//取消X轴缩放 self.chartView.scaleEnabled = NO;// 缩放 self.chartView.doubleTapToZoomEnabled = NO;//取消双击缩放 self.chartView.dragDecelerationEnabled = NO;//拖拽后是否有惯性效果 self.chartView.dragDecelerationFrictionCoef = 0;//拖拽后惯性效果的摩擦系数(0~1),数值越小,惯性越不明显 self.chartView.rightAxis.enabled = NO;//不绘制右边轴的信息 self.chartView.leftAxis.enabled = NO;//不绘制左边轴的信息 self.chartView.xAxis.enabled = NO; self.chartView.xAxis.drawGridLinesEnabled = NO;//不绘制网络线 self.chartView.xAxis.axisLineColor = [UIColor whiteColor];// x 轴的网络线颜色 self.chartView.xAxis.labelPosition = XAxisLabelPositionTopInside;// X轴的位置 self.chartView.xAxis.granularity = 1;// 间隔为1 基本上看得懂英文的都懂得这些的意思看效果图,需要点击的时候出现一个 view,跟随点的位置,charts 本身已经实现了这个功能,名字叫BalloonMarker,但是集成的时候没有集成过来,需要自己写,或者直接在 demo 里面搜索这个类拷贝到自己的项目中去修改 123456789// 显示气泡效果 BalloonMarker *marker = [[BalloonMarker alloc] initWithColor: [UIColor colorWithRed:0.384 green:0.800 blue:0.980 alpha:1.000] font: [UIFont systemFontOfSize:12.0] textColor: UIColor.whiteColor insets: UIEdgeInsetsMake(8.0, 8.0, 20.0, 8.0)]; marker.img = [UIImage imageNamed:@"marker"]; marker.chartView = self.chartView; self.chartView.marker = marker; 基础设置都设置好了,接下来就可以填充数据了,charts 你大致是可以理解为这样的工作模式: 设置 chartview 的属性 -> 设置LineChartData数据 -> 最后设置各种数据显示属性 这是我第一个坑,有一些属性是需要等后面数据填充了才可以进行设置,否者会遇到各种奇怪的问题。我们继续进行数据的填充吧,chartview 可以设置多条线,每一条线就是一个LineChartDataSet,每一条线上面的点就是ChartDataEntry,想在一条线上显示多少个点就需要多少个ChartDataEntry。12345678910111213141516171819202122232425262728293031NSMutableArray *arr = [NSMutableArray array];for (int i = 0; i < self.weights.count; i++) { ChartDataEntry *entry = [[ChartDataEntry alloc] initWithX:i y:ww]; entry.flag = model.weightflag;//自己增加的属性 entry.realValue = model.weight;//也是自己增加的属性 [arr addObject:entry];}LineChartDataSet *set = [[LineChartDataSet alloc] initWithValues:arr label:@""];//对于线的各种设置 set.drawValuesEnabled = NO;//不显示文字 set.highlightEnabled = YES;//选中拐点,是否开启高亮效果(显示十字线) set.highlightColor = [UIColor clearColor];// 十字线颜色 set.drawCirclesEnabled = YES;//是否绘制拐点 set.cubicIntensity = 0.2;// 曲线弧度 set.circleRadius = 5.0f;//拐点半径 set.drawCircleHoleEnabled = NO;//是否绘制中间的空心 set.circleHoleRadius = 4.0f;//空心的半径 set.circleHoleColor = [UIColor whiteColor];//空心的颜色 set.circleColors = @[[UIColor colorWithRed:0.114 green:0.812 blue:1.000 alpha:1.000]]; set.mode = LineChartModeCubicBezier;// 模式为曲线模式 set.drawFilledEnabled = YES;//是否填充颜色// 设置渐变效果[set setColor:[UIColor colorWithRed:0.114 green:0.812 blue:1.000 alpha:1.000]];//折线颜色 NSArray *gradientColors = @[(id)[ChartColorTemplates colorFromString:@"#FFFFFFFF"].CGColor, (id)[ChartColorTemplates colorFromString:@"#C4F3FF"].CGColor]; CGGradientRef gradientRef = CGGradientCreateWithColors(nil, (CFArrayRef)gradientColors, nil); set.fillAlpha = 1.0f;//透明度 set.fill = [ChartFill fillWithLinearGradient:gradientRef angle:90.0f];//赋值填充颜色对象 CGGradientRelease(gradientRef);//释放gradientRef// 把线放到LineChartData里面,因为只有一条线,所以集合里面放一个就好了,多条线就需要不同的 set 啦LineChartData *data = [[LineChartData alloc] initWithDataSets:@[set]]; 把线都设置好了,放在 data 里面后,还需要把 data 放在 chartview 的 data 里面,这样才算是填充了数据 self.chartView.data = [self setData]; // 加载数据 之后就进行最后的设置了1234567891011121314151617181920212223242526272829303132333435363738394041424344454647//设置最大显示值NSMutableArray *arr = [NSMutableArray array];for (NSUInteger i = 0; i < self.weights.count; i++) { FFWeightModel *model = self.weights[i]; [arr addObject:@(model.weight)]; }double max = [[arr valueForKeyPath:@"@max.doubleValue"] doubleValue];self.chartView.leftAxis.axisMaxValue = max;//设置最小显示值double min = [[arr valueForKeyPath:@"@min.doubleValue"] doubleValue];self.chartView.leftAxis.axisMinValue = min;// 设置区域显示,要显示7个数据,所以设置最大显示和最小显示[_chartView setVisibleXRangeMaximum:6];// 最大显示[_chartView setVisibleXRangeMinimum:6];// 最小显示//设计师说要数据加载的时候前面留空白3个,拖到后面也是留空白3个,保证点都是在中间为准,所以又设置了留白数据self.chartView.xAxis.axisMinimum = -3;//最前面留空白3个区域self.chartView.xAxis.axisMaximum = self.weights.count+2.1;//后面留空3个区域,别问我为什么是2.1//添加添加限制的线ChartLimitLine *limitLine = [[ChartLimitLine alloc] initWithLimit:[self.userweight[@"weight_first"] doubleValue] label:[NSString stringWithFormat:@"初始%@kg",self.userweight[@"weight_first"]]]; limitLine.lineWidth = 1; limitLine.lineDashLengths = @[@(5.0),@(5.0)]; limitLine.lineColor = [UIColor colorWithRed:1.000 green:0.671 blue:0.671 alpha:1.000]; limitLine.labelPosition = ChartLimitLabelPositionCenter;//位置 limitLine.valueTextColor = [UIColor colorWithWhite:0.502 alpha:1.000];//label文字颜色 limitLine.valueFont = [UIFont systemFontOfSize:12];//label字体 ChartLimitLine *limitLine2 = [[ChartLimitLine alloc] initWithLimit:[self.userweight[@"weight_target"] doubleValue] label:[NSString stringWithFormat:@"目标%@kg",self.userweight[@"weight_target"]]]; limitLine2.lineWidth = 1; limitLine2.lineDashLengths = @[@(5.0),@(5.0)]; limitLine2.lineColor = [UIColor colorWithRed:0.682 green:0.925 blue:1.000 alpha:1.000]; limitLine2.labelPosition = ChartLimitLabelPositionCenter;//位置 limitLine2.valueTextColor = [UIColor colorWithWhite:0.502 alpha:1.000];//label文字颜色 limitLine2.valueFont = [UIFont systemFontOfSize:12];//label字体//把限制线添加到 chartview 里面[self.chartView.leftAxis addLimitLine:limitLine];[self.chartView.leftAxis addLimitLine:limitLine2];//最后每次打开都自动高亮最后一个数据,所以需要设置FFWeightModel *model = self.weights.lastObject;[self.chartView highlightValueWithX:self.weights.count-1 y:model.realWeight dataSetIndex:0 callDelegate:NO];//由于每次打开都是显示在最前面的点,所以需要移动显示的位置[_chartView moveViewToX:self.weights.count];// 移动到那个点//最后显示出动画[self.chartView animateWithYAxisDuration:1];//动画 其实以上都是简单的设置,只要花时间就能设置出来,但是难点永远不是这些,是那些坑爹的需要,是那些不知道技术实现起来很难以为只是很简单的,所以需求总是天天有,只能拼命改改改T_T ##说一些 charts 的一些坑吧 ###集成BalloonMarker的坑我是直接拿 demo 的过来用的,如果不熟悉 swift 的同学就要注意了,你把 swift 的文件集成过来后,需要编译一次,然后你是不是想说应该怎么声明这个BalloonMarker,因为你在 import 里面没有看到这个,混编的 swift 其实全部都在一个不可见的 h 文件里面,你只需要 #import “你项目的名字-swift.h”这个文件就可以了,所有混编的 swift 都会在这里声明,不过你需要先编译一次才会在里面可以找到对于BalloonMarker修改 view 的背景,他是直接画出来的,但设计师的那个是切图出来,所以你需要在BalloonMarker里面找到open override func draw(context: CGContext, point: CGPoint)这个方法,然后删除或者注释掉那个很长的属性if let color = color{},新建了一个属性叫open var img: UIImage?然后直接在被你删掉或者注释掉的地方添加123if let img = img{ img.draw(at: CGPoint(x:rect.origin.x-2,y:rect.origin.y)) } 编译一次后你就可以直接在外部调用 img 这个属性并且赋值了 ###数据源的坑如果你需要显示中文,恭喜来这个坑,目前我没找到什么好的解决办法比如想显示 x 轴的文字,就需要self.chartView.xAxis.valueFormatter = self;并且实现它的数据源代理就可以用他的方法了,- (NSString * _Nonnull)stringForValue:(double)value axis:(ChartAxisBase * _Nullable)axis;目前没有很好的利用这个方法,觉得不好用 ###代理的坑charts 主要用到有三个代理1234567@objc optional func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) // Called when nothing has been selected or an "un-select" has been made. @objc optional func chartValueNothingSelected(_ chartView: ChartViewBase) // Callbacks when the chart is moved / translated via drag gesture. @objc optional func chartTranslated(_ chartView: ChartViewBase, dX: CGFloat, dY: CGFloat) 第一个是点击后响应的方法,第二个是点击同一个点响应的方法,第三个是拖动就会响应的方法 先说第一个吧,点击后根据你点击的 x 的位置定位到你点击的那个点,并且高亮显示,如果你有用 markerview 就会显示出来,包括高亮线,由于我用不到,所以就设置高亮线为透明 我这边的要求是,不管点击哪个点,都要自动移动到中间,所以需要取出你点击的点,然后移动到中间[self.chartView moveViewToAnimatedWithXValue:entry.x-3 yValue:0 axis:AxisDependencyLeft duration:.3]; 相对来说这个是很容易实现的,毕竟你点击后能够得到对于的ChartDataEntry的值,所以算出你点击的位置然后设置在中间都是很容易的,但是滑动就难了,滑动的时候需要保证每次滑动都是在中间,随便说下,滑动方法里面的 dx 和 dy 是在你每次手指滑动的时候重新开始计算的,拿 dx 来说,你滑动左边数值是从0开始加上去的,右边滑动是从0到负数的叠加,还好 chartview 有两个属性可以用来做判断,分别是self.chartView.highestVisibleXself.chartView.lowestVisibleX取NSInteger index = self.chartView.highestVisibleX-3;拿到 index然后显示高亮状态[self.chartView highlightValueWithX:index y:model.realWeight dataSetIndex:0 callDelegate:NO];但是这样还是不行,毕竟滑动不会自动居中,所以就导致显示的点可能会不在中间,所以自己改源码增加了一个滑动结束的代理 ###高亮的坑安卓那边高亮显示可以直接用- (void)highlightValueWithX:(double)x dataSetIndex:(NSInteger)dataSetIndex;但是 iOS 这边直接用这个方法是不行的,在 github 上也有人问过此类问题,最后只能用另一个属性方法- (void)highlightValueWithX:(double)x y:(double)y dataSetIndex:(NSInteger)dataSetIndex;但由于我在滑动代理里面增加了高亮的方法,高亮方法默认是打开代理的状态,这样会导致滑动出错,所以需要用另一个高亮显示的方法- (void)highlightValueWithX:(double)x y:(double)y dataSetIndex:(NSInteger)dataSetIndex callDelegate:(BOOL)callDelegate;设置代理为 NO 就可以了 #总结其实到了最后跟设计图还是有很多不同的,放出实际图,其实多少辛酸泪不是简单两语能够说得清道得明,排版有点乱,大家请将就下哈~这是第一版,希望以后再努力的去改一改吧!]]></content>
<categories>
<category>iOS经验</category>
</categories>
</entry>
<entry>
<title><![CDATA[浅谈iOS生涯]]></title>
<url>%2F2016%2F06%2F07%2F%E6%B5%85%E8%B0%88iOS%E7%94%9F%E6%B6%AF%2F</url>
<content type="text"><![CDATA[#前言做iOS已经挺久一段时间了,从13年开始买了MacBook然后自学iOS,那时候是看着李明杰MJ的视频成长的,虽然是盗版视频,哈哈.之后在老家找到了一份从事iOS的工作,其实也算了运气好,如果找不到,或许我也不会一直走下去,毕竟当时只是自学,并没有很系统的学习,导致比较杂乱和不规范,能够进去工作表示很开心,第一份工作是很艰难的,也可以说是很难熬的,你要理解那种你什么都不会,然后还一直的拖着,导致你一度想要放弃,觉得做的真的很难,最后还是咬咬牙坚持了下来,不懂的就问同事,问百度,我并没有在面试的时候说自己有多少年多少年经验,直接说我是自学的,并没有这方面的工作经验,也感谢当初的总监能够接受并且让我入职.我知道现在很多培训的人,大多数出来就说自己有两到三年的工作经验,他们或许技术不行,但是面试这块学的不错,以至于刚毕业的学生没有一点优势,唯一的,或许是你是重点大学毕业的吧,对于我这个三流大学的人来说,是完全没有可比性的,而且我不会说话,导致面试的时候不能很好的表达自己,导致错过很多机会,这几年,我一直在不断的学习,想把自己变得更好,接触了不一样的人,了解了不一样的世界,其实对于自己来说是个很好的发展,或许我没有别人一开始就拿很高的工资(第一份iOS也只拿了3k的工资),但是经验的累积并不是说说而已,也不是培训能够培训出来的,所以我也理解为什么企业讨厌培训的,不是说培训的好不好,而是培训的并不会说自己的真实情况,大体上大家都是觉得花钱培训了,出来就应该找高工资,不应该找太少的,不然就亏了… #应该如何去学习iOS?这是我自己本人的经验总结,如果有不合理或者不认同的地方~欢迎来批判和互相学习~ 假设你是想通过培训入门iOS的 在iOS这个领域,其实说白了,很多东西都不是很难,只要你掌握了语法,用法,还有一些逻辑思维的处理,基本上你可以自己做你想做的事情,培训这个,不是说不好,如果你真的愿意去好好学习,当然是很好的事情,毕竟培训会比较系统化,从简到难,最后再学习如何做项目,培训行业的泛滥也导致很多不入流的iOS,主要是学了一点了就觉得自己很厉害什么都会了,直接就去找工作了,如此反复,其他企业怎能对培训的有好感,根本上没有起到培训的作用,如果有,那就是培训该如何面试吧. 学iOS的人有两种,一种是感兴趣的,他会想去钻研进去,学习新知识,一种是想用这个行业去赚钱,那么他只会学习能用到的东西,哪些用不上的新知识就不会去用. 我有一个好朋友,之前做移动客服,现在想转行,不知道做什么好,看我在这行做的还不错,想跟我一起做,我就叫他去培训,我知道他是因为看着这个行业工资比较高所以才想转行,并不是喜欢编程,也说不定后来接触多了也喜欢了,也不知道他能不能坚持下来.我告诉他,你想学可以,但是我希望你能够按照我说的去,首先打好基础,或许以后在工作中你觉得没用上,其实在不知不觉中,你的基础就是你以后成长的基石,因为你基础没有打好,很多逻辑思维就会跟不上,你连iOS是什么都不知道,怎么能够学习?基础学一个月学不好,那就重新读基础,以前的我不重视基础,觉得会做UI就行了,其实是错误的,基础都没打好,怎么能够去深入进步,我希望他能够以赚钱为目的的去好好学习,而不是胡乱学了一下就去外面混,对他以后也不好,现在有机会,就应该把握住,哪怕需要时间长一点,将来的收获不会比现在的更少. 假设你想自学iOS 自学iOS的,要么是对iOS本身感兴趣,想去学习,要么是没钱去培训的. 对于自学,其实我算是比较有经验的,一般来说真的很难坚持下去,特别是没有意志力的人,真的好难,我深感体会=.=!对于自学,其实比较难系统化,可能你觉得这里不会就跳过去,或许你不知道,你跳过去的东西对你以后很重要,可是你不会,你怎么办,又不知道问谁,现在还好,有各种iOS的群,那时候我自学的时候并没有加什么群,基本上都是自己拼命努力的自学.其实自学也可以系统化,就是根据你下载的视频,或者文档,没基础的直接从基础看起,有基础的,或者自认为基础不错的,从UI看起,只要能够坚持下去,其实效果并不比去培训的差,因为你能够通过培训学习到的,在视频也能够学习到,就是不能学到那些面试技巧什么的咯. 那到底该如何学习? 其实不管是自学还是培训,你都是需要了解一门语言的根本,你不能说,你学习到最后都不知道你的这门语言叫什么名字,记得我刚刚开始学习的时候,总是看到书上或者视频说打印某某,我就在想,打印出来的到底有什么作用?为什么要打印出来?后来才发现,打印只是个输出的调试作用,目的是为了能够知道数据的准确性,能够及时的修改,其实在完成后用户是看不到打印的结果,我们学习打印,是为了能够输入我们想要的结果,这是一个非常简单的事情,也是初学的第一步,不管是什么,我们都喜欢打印”helloWord”.其实严格来说,不管培训还是自学,只能够尽量的全面的了解下iOS的各个功能,各个控件,但是工作往往不是这么回事,比如说你做的是音乐类的APP,那么肯定要对音乐的库十分的了解,这不是自学或者培训能够学到的,需要你经验的累积和不断是学习,深入的去学习才能够胜任这份工作,看这个人有没有工作经验,不是看他本身简历写的怎样,而是问他对项目的理解,这是我目前来说对于面试的人最喜欢问的问题,我相信,自己的项目对自己肯定是十分的了解的. 应该怎么去深入学习iOS? 说实话对于这点,我自己本身的想法就是看企业的方向,如果你想深入学习,除非你有时间,否则就是根据项目APP的方法去学习了,大家总是说,项目是让你成长的最好的狗粮,来,大家一起干了这碗狗粮为了以后~ 面对项目这个大boss,我们做不到一下子就打死,我们只能慢慢的啃下来,当然你是大神除外,不然我们只能慢慢的一边学习一边去实践,企业现在招人的时候都会在面试上面写,有某某某相关经验的优先,其实就是只要有相关经验的,这样可以少去很多时间,做更多的事情,这是老板喜闻乐见的,但是我们并不是一开始就会,所以难免就需要去找小公司,或者外包公司去累积经验,让自己专攻一个方向或者在几个方面是精通的,就算做不到精通,也要做到不会一头雾水. #后话其实说的很多人心里知道,就比如我,我知道我哪里不好,哪里需要改,可是自己本身的惰性导致改的很慢,想着有时间慢慢来,可是真的需要用到的时候才发现根本没有多少时间了,很多事就是这样,比如说工作上,你自己本身其实觉得你做得完,在约定时间内想着自己可以完成老板给的任务,给两周,结果一周时间根本没好好工作,到了第二周才发现时间不多了,加紧时间去努力工作,时间安排的不合理导致需要加班或者延后工作周期给老板带来不好的印象,导致觉得你工作态度不好,人是个很矛盾的,懂得道理却做不了,希望能够好好的走下去,编程这件事本身就是学无止境,没有哪个人敢说自己什么都会,什么都已经不用学了,不渴望改变世界,但是却想改变自己的人生,每个人肯定想的是生活过的更好,才能有能力去追求更好的.]]></content>
<categories>
<category>闲谈</category>
</categories>
</entry>
<entry>
<title><![CDATA[iOS TextField 关于中文字数限制包含表情]]></title>
<url>%2F2016%2F04%2F22%2FiOS%20TextField%20%E5%85%B3%E4%BA%8E%E4%B8%AD%E6%96%87%E5%AD%97%E6%95%B0%E9%99%90%E5%88%B6%E5%8C%85%E5%90%AB%E8%A1%A8%E6%83%85%2F</url>
<content type="text"><![CDATA[##TextField 限制字数的方法 代理限制字数-(BOOL)textField:(UITextField )textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString )string;用这个方法来进行字数限制,但是这个方法到现在也不能限制中文,这个方法给我最多的就是用在做限制手机号码等纯数字或者密码输入等数字英文字符的限制😂 通知在viewdidload注册一个通知 1[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldEditChanged:) name:UITextFieldTextDidChangeNotification object:_textField.text]; 往textfield添加一个Target 1[_textField addTarget:self action:@selector(textFieldEditChanged:) forControlEvents:UIControlEventEditingChanged]; 就上面三种方法而言,我个人会使用第三种方法,理由嘛~就是能不用通知就不用通知~下面来说具体方法 1234567891011121314151617181920212223242526272829NSInteger length;//定义length来保存字数-(void)textFieldEditChanged:(UITextField *)textField{ //字数限制 NSInteger WordCount = 10; NSString *toBeString = textField.text; UITextRange *selectedRange = [textField markedTextRange]; UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0]; // 没有高亮选择的字,则对已输入的文字进行字数统计和限制 if (!position) { if (toBeString.length > WordCount && textField.markedTextRange == nil) { NSRange rangeIndex = [toBeString rangeOfComposedCharacterSequenceAtIndex:WordCount]; if (rangeIndex.length == 1) { textField.text = [toBeString substringToIndex:WordCount]; } else { textField.text = [toBeString substringWithRange:NSMakeRange(0, length)]; } } else { length = toBeString.length; } }} ###总结现在对于字数限制,我是比较推荐使用我现在用的这种,符合中文的需求之前其实并没有写那么复杂,只是写了如果大于字数限制,就直接切割多少个字符限制的字符串后来因为发现表情会占用两个字节,如果你最后刚好9个,多一个表情就会变成11,切割变成了10,就会照成表情的不完整,会出现比较严重的bug,在网上综合例子弄了自己最适合的,或许有更好的,欢迎拍砖~ 虽然觉得自己学的不好,但也是慢慢累积,希望有一天能够帮助到别人,不能一味的总是获取别人的成果.]]></content>
<categories>
<category>iOS经验</category>
</categories>
</entry>
</search>