vtostar / blog Goto Github PK
View Code? Open in Web Editor NEWMy Blog
My Blog
Mantle 让我们能简化 Cocoa 和 Cocoa Touch 应用的 model 层。简单点说,程序中经常要进行网络请求,请求到得一般是 json 字符串,我们一般会建一个 Model 类来存放这些数据。这就要求我们编写一系列的序列化代码,来把 json 转换为 Model 。这很费时间,容易错,不容易修改。 Mantle 很好的解决了这个问题,而且更易用。
IB 时代,如果你还在用代码绝对布局就太 low 了。随着苹果发布 iPhone6 、 iPhone 6 plus 。 iOS 设备将会出现越来越丰富的屏幕尺寸,我们不可能根据每个尺寸做一套布局。所以,使用 autolayout 就很有必要了。在 storyboard 中,可以非常方便的使用 autolayout ,但是为了更好的协作开发,有些公司依然在手写布局,令人沮丧的是苹果提供的 autolayout 语法晦涩难懂,非常影响效率(你可以在 这里 动态查看 autolayout 的语法)。 Masonry 就是设计来解决复杂的手写 autolayout 。如何优雅的使用 autolayout ,且看 Masonry 。
移动互联网时代,应该很少有应用是不需要网络连接的吧。监测网络连接状态几乎是必不可少的一部分。 Reachability 可以完美的完成这一任务。
下载链接: github地址
参考:使用方法,请看 README
Cocoapods集成:pod 'Reachability', '~> 3.2'
BlocksKit绝对是 Objective-C 的知心伴侣,它为 OC 常用类提供了强大的 Block 语法支持,使得编写 OC 代码变得舒适、快速、优雅。反正我是绝对离不开它。
下载链接 github地址
cocoapods集成:pod 'BlocksKit', '~> 2.2.5'
如果你在项目中有使用 KVO ,那么 KVOController 绝对是个好选择。它是 facebook 开源的一个 KVO 增强框架。有以下几个特性:
还有什么理由不使用 KVOController 呢?
下载链接 github地址
参考:KVOController : facebook 开源的 KVO ( Key-value Observing )工具
cocoapods集成:pod 'KVOController', '~> 1.0.3'
一个老牌、经典的通知组件,如果你们美工没有专门设计等待和通知视图,那就用它吧!
下载链接 github地址
参考:参照README
cocoapods集成:pod 'MBProgressHUD', '~> 0.9'
很多公司都自己设计下拉刷新视图,比如网易新闻 iOS 客户端,下拉的时候会有广告出现。如果你只是需要一个下拉刷新,那么可以考虑 ODRefreshControl ,它是原 iOS6 上的橡皮糖刷新样式,很有意思。现在也很多大的 App 在用,比如虾米音乐和 QQ 客户端。
下载链接 github地址
参考:参照README
cocoapods集成:pod 'ODRefreshControl', '~> 1.1.0'
又是 Facebook 开源的。大名鼎鼎的 pop ,做动画的不二之选。收下它吧。
下载链接 github地址
cocoapods集成: pod 'pop', '~> 1.0.7'
不用多解释,Objective-C下第一网络请求库。
hello world!
function sayHello($name)
{
$time = date('Y-m-d H:i:s');
$weather = 'what a sunshinny day!';
echo "Hello $name!";
}
症状:可能编程的时候买的股票刚升职、刚交了女朋友,心情格外的好,随便写上点什么?可能之前做需求变更时,代码逻辑没有删干净?可能在练习打字。
解毒:提交代码库前,自己做review,看能够让自己满意么?如果你真检查了,就是要保留上述代码,那么,恭喜你,做程序员太委屈了你,其实你应该去做产品经理!
症状:废了好大的劲,最终没有调用。猜测代码逻辑是一开始有用的,但是后续需求调整,从动态请求变成一张静态图片了,做需求的人没有认真看代码逻辑,直接修改了最终展示图片的位置,而没有管其他的逻辑,导致这种空跑逻辑的存在。
解毒:修改别人代码的时候是需要谨小慎微的,但是也不能容忍垃圾代码的存在,拿不准的可以找人结对或者review。没有代码洁癖的程序不是好产品经理!
症状:我中有你,你中有我。相互调用前没有沟通清楚?还是就是一个人写的?死循环调用,直至到达系统设置的最大执行时间或者内存溢出,进程挂掉。
解毒:在加入版本库前走读代码,自检一下,看人脑能跑通么?多问问自己如果出错了怎么办?总不能只考虑正常逻辑吧。
$p = new Person();
$p->name = 'Tom';
$p->sex = 'male';
$p->address = 'balizhuang #1 1-1-101, chaoyang district, beijing, china';
$p->save();
//确保存入db
sleep(3);
$p->save();
症状:数据来的不容易,一定要保障数据的可靠性,要存入db。担心系统忙,万一当时系统真的很忙呢,还是多保存一遍比较稳妥,心理踏实。
解毒:额,这个么,建议你写代码时候桌子上摆个关公再点上三炷香,似乎更靠谱。尝试用系统执行的角度去思考代码的运行状况,或者step by step的进行debug调试,能够帮助我们思考,识别出无用的代码。如果第一次save()报错,那就让他报错好了
try
{
$p = new Person();
$p->name = 'Tom';
$p->sex = 'male';
$p->address = 'balizhuang #1 1-1-101, chaoyang district, beijing, china';
$p->save();
}
catch (Exception $e)
{
//再次尝试下看db能保存么?
if (false == $p->save())
{
throw new MyException('保存db失败了');
}
}
症状:这是上个问题的升级版,也许是想加强对错误的处理,起码再努力看看?实在不成再抛出一个我的异常。捕获异常进行错误重试未尝不可,但是首先要注意是否只捕获了你关心的异常?而不是一揽子全收了,再次失败后,再抛出了一个新的异常,那底层带上来的上下文信息可就被吞并了,上层更无法判断是什么问题了。
解毒:只捕获业务关心的异常,不要吞噬上下文信息。
function getUser($userName)
{
$user = getUserByDB($userName);
//取用户相关微信号
$api = new WeixinAPI();
$user->code = $api->callWeixinHttpApi('http://weixin.qq.com/xxxx');
return $user;
}
症状:在本系统调用过程中,同步调用了外部系统(微信)的远程接口,如果外部服务挂了,接口返回不正常时,本系统也无法正常使用。
解毒:依赖外部服务的功能分成:强依赖,比如这个功能是调用对方提供的接口来打电话,如果对方不可用,本系统即不可用;和弱依赖,比如只是在页面右侧广告位显示下微信的二维码,如果对方不可用,不要影响我方其它业务。
要加入错误捕获或者放入消息队列进行异步处理,不要让其阻断本系统的其它功能。如:
function getUser($userName)
{
$user = getUserByDB($userName);
try
{
$api = new WeixinAPI();
$user->code = $api->callWeixinHttpApi('http://weixin.qq.com/xxxx');
}
catch (WeixinException $e)
{
//add logs here
}
return $user;
}
一旦微信不可用,WeixinAPI抛出异常,会导致整个系统也不可用。主动捕获可能发生的异常,不要让其阻碍本系统的正常使用。
症状:HTMLHelper,UserManager,XString... 具体可以参考: xstring.php。在各种helper,manager类中,往往混杂了大量说不清楚,或者职责模棱两可的地方,于是我们发明了粘合剂类,用于填充那些谁也不管的功能。
解毒:粘合剂不是一定不能有,但是要在设计时就考虑清楚其职责,而不是笼统的起一个xxxHelper来放。其他人可不知道你这个到底是干嘛的,也不敢用。久而久之就成了垃圾箱。
进阶:深层次的问题是在面向对象开发过程中的职责不清,到底什么逻辑放到service中,什么逻辑放到实体或者知识类中?可以参考:message系统服务.
推荐阅读:
书的图片可以点击哦。
这篇文章主要是介绍一下在iOS开发中使用到的一些可以提升开发效率的方法和工具。
首先要说的肯定是IDE了,说到IDE,Xcode不能跑,当然你也可能同时在使用AppCode等其他的IDE,在这里主要介绍Xcode中提升开发效率的方法。
快捷键是开发中必不可少的,当你善于使用快捷键的时候,十指在键盘上飞舞,那画面太美,我不敢想象。
开发中有一些常用的代码,可以放到代码片段中,然后下次你就可以使用快捷方法来使用这些代码了,给大家看下我的Xcode中部分代码片段:
那些不能错过的Xcode插件
快速Add #import
查看项目的’TODO’,’FIXME’等
你可能想,如果没有我要用的插件怎么办?少年,这个时候就要自己动手丰衣足食了,我想你可以看看这个Xcode6插件开发入门
DHC 在线调试接口,支持HTTP和HTTPS。
Postman 一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。
马克鳗 它有免费和收费2个版本,免费版本可以使用基本功能,感觉还不错。
Pixel Winch 试了一下,比马克鳗好使。
tinypng,保质压缩,我感觉还不错,推荐给我们UI和后台,他们用过之后都说好
tinypng批量压缩图片脚本 配套使用更佳。
AppIcon只需要UI提供一张1024*1024的图就可以了,具体的icon可以用Prepo生成
假设这么一种情况:公司用的是SVN,公司一台公司电脑,家里一台自己电脑,有时候可能想回来后接着敲代码,怎么办?
再假设这么一种情况:公司用的是SVN,产品想实现一种效果,但是你又不确定能不能写出来,所以你可能会纠结要不要在公司项目上改动,怎么办?
如果有上述两种烦恼,那么Github 和 Bitbucket 是您的首选,具体选哪个,这里有一篇对比文章:GitHub vs. Bitbucket 不只是功能不同.
Github上好的开源项目太多,一个一个的star,太慢了,怎么破?
这个其实就是Github的Advanced search功能:
另外Github Advanced Search 可以用来寻找小伙伴哦—— Github Advanced Search猎头大法
在iOS开发中,经常用到宏定义或者用const修饰一些数据类型,而很多开发者不知道怎么正确使用,导致项目中乱用宏与const修饰
你能区分下面的吗?知道什么时候用吗?
#define HSCoder @"哈哈哈"
NSString *HSCoder = @"哈哈哈";
extern NSString *HSCoder;
extern const NSString *HSCoder;
static const NSString *HSCoder = @"哈哈哈";
const NSString *HSCoder = @"哈哈哈";
NSString const *HSCoder = @"哈哈哈";
NSString * const HSCoder = @"哈哈哈";
当我们想全局共用一些数据时,可以用宏、变量、常量
宏:
#define HSCoder @"哈哈哈"
变量
NSString *HSCoder = @"哈哈哈";
常量
四种写法:
static const NSString *HSCoder = @"哈哈哈";
const NSString *HSCoder = @"哈哈哈";
NSString const *HSCoder = @"哈哈哈";
NSString * const HSCoder = @"哈哈哈";
宏与常/变量的选择?
宏:只是在预处理器里进行文本替换,没有类型,不做任何类型检查,编译器可以对相同的字符串进行优化。只保存一份到 .rodata 段。甚至有相同后缀的字符串也可以优化,你可以用GCC 编译测试,”Hello world” 与 “world” 两个字符串,只存储前面一个。取的时候只需要给前面和中间的地址,如果是整形、浮点型会有多份拷贝,但这些数写在指令中,占的只是代码段而已,大量用宏会导致二进制文件变大
变量:共享一块内存空间,就算项目中N处用到,也不会分配N块内存空间,可以被修改
常量:共享一块内存空间,就算项目中N处用到,也不会分配N块内存空间,可以根据const修饰的位置设定能否修改
尽量使用const,在苹果API中就是使用常量多些,如下图:
常量区分
全局常量:不管你定义在任何文件夹,外部都能访问
NSString *HSCoder = @"哈哈哈";
例如:
在ViewController定义一个 HSCoder 字符串全局常量:
在AppDelegate中访问:
局部常量:用static修饰后,不能提供外界访问
static NSString *HSCoder = @"哈哈哈";
例如:
在ViewController定义一个 HSCoder 字符串局部常量:
编译时报错:
const修饰位置不同,代表什么?
1.const NSString *HSCoder = @"哈哈哈";
2.NSString const *HSCoder = @"哈哈哈";
3.NSString * const HSCoder = @"哈哈哈";
1.const NSString *HSCoder = @"哈哈哈";
"*HSCoder"不能被修改, "HSCoder"能被修改
2.NSString const *HSCoder = @"哈哈哈";
"*HSCoder"不能被修改, "HSCoder"能被修改
3.NSString * const HSCoder = @"哈哈哈";
"HSCoder"不能被修改,"*HSCoder"能被修改
注意:1和2其实没什么区别
结论:const右边的总不能被修改
所以一般我们定义一个常量又不想被修改应该这样:
NSString * const HSCoder = @"哈哈哈";
在项目中,定义全局常量,一般会写在一个独立文件里
在开发过程中,我们不仅要去看别人的代码,也要让别人看我们的代码。那么,有一个良好的编码习惯将会非常重要。下面将会罗列使用Objective-C来开发iOS的编码建议。
【1】任意函数长度不得超过50行。(其实很容易就超过50行,这就要考虑代码抽取了。)
【2】任意行代码不能超过80字符。(其实也很容易超过80字符,可以考虑多行显示,比如有多个参数时,可以每个参数放一行。)可以在Xcode中设置超过80个字符的提醒,选中“Page guide at column”.设置完之后就会在代码80个字符处有一条竖线。
【3】在每个方法的定义前留白一行,也就是在方法和方法之间留空一行。
【4】功能相近的方法要放在一起,并推荐使用#pragma mark - ***来导航代码,切分代码块。这样可以方便函数的查找。并且可以使用快捷键control+6 来快速查找方法的位置。
【5】二元运算符和参数之间要有一个空格,如赋值号=左右各留一个空格。
self.myString = @"235423rew523452345";
【6】一元运算符和参数之间不放置空格,比如!非运算符,&按位与,|按位或。
BOOL isOpen = true;
BOOL isClose = !isOpen;
【7】强制类型转换和参数之间不放置空格。
NSString *str3 = (NSString*)self.myString;
【8】长的变量值应该拆分为多行。尤其体现在使用数组或者字典。以下也分别是快速声明数组@[]和字典@{}的方法。
NSArray *array = @[@"111",
@"2222222222",
@"3333333",
@"wwwwwwwwwwww"
];
NSDictionary *dict = @{@"name":@"jack",
@"age":@"20",
@"gender":@"female",
@"isMarried":@"false"
};
【9】尽量使用有意义的名字命名,拒绝使用i,j等无意义字符命名。类的命名首字母大写,其他变量的命名首字符小写,并使用驼峰式分割单词。
【10】尽量减少在代码中直接使用数字常量,而使用宏定义等方式。如:MAX_NUMBER_PHONE替代8等等。这样我们搜索也比较方便。
【11】尽量减少代码中的重复计算,比如代码中多处要使用屏幕宽度,然后计算:[[UIScreenmainScreen] bounds].size.width ,很多次,闲得很繁琐,代码也冗长。不如直接宏定义:
##define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
【12】合理使用约定俗成的缩略词:
【13】宏定义全部字母大写。
【14】函数长度不要超过50行,小函数比大函数可读性更强。函数的参数不宜过多,零元函数最好,一元函数也不错,高于三元的函数虚重构。
【15】合理范围内使用链式编程:
NSString *myName = [[NSString alloc] init];
但是嵌套不宜超过3层,超过3层需进行重构。
【16】函数调用时所有参数在同一行。如果参数过多,则可以每行一个参数,每个参数以冒号对齐。
【17】对传入参数的保护或者说是否为空的判断,尽量不要使用if(!obj),而使用NSAssert断言来处理。NSAssert是系统定义的宏。
NSAssert(myName != nil, @"myName参数为空");
如果条件判断为真,则程序继续执行。
如果判断条件为假,则抛出异常,异常内容为后面定义的字符串。
【18】方法参数名前一般使用"an","the","new"来进行修饰。如:
-(void)setPersonInfo:(NSString*)theID theName:(NSString*)theName theAge:(NSInteger*)theAge
【19】if-else超过四层的时候,就要考虑重构,多层的if-else结构很难维护。
【20】当需要一定条件才执行某项操作时,不要将最重要的代码内嵌到if中。
如良好的风格是:
- (void) someMethod {
if(![someOther boolValue]) {
return;
}
//最重要的代码写在这里;
}
反面例子:
- (void) someMethod {
if([someOther boolValue]) {
//重要代码;
}
}
【21】所有的逻辑块都使用{}花括号包围,就算只是一行代码。
【22】明确指定构造函数,并有适当的注释。
【23】不要在init方法中把变量或者说属性初始化为0或者nil,因为没有必要。
【24】UIView的子类初始化的时候,不要进行任何的布局操作。布局操作应该在layoutSubviews里面做;需要重新布局的时候调用setNeedsLayout,而不要直接调用layoutSubviews。
【25】保持公共API简单,也就是保持.h文件简单。放在.h中声明的函数都是会被公开的,如果根本就没必要对其他类公开,再不要在.h中声明。OC中的方法都是公有方法,没有私有方法一说。
【26】一个文件只实现一个类。同一个文件中不要有多个类。
【27】Protocol单独用一个文件来创建,尽量不要与相关类混在一个文件中。
【28】在类定义中使用到自己定义类的时候,尽量不要在头文件中引入自己定义类的头文件,使用@Class替代。而在实现文件中引入头文件。
【29】布局时尽量使用相对布局,比如使用子View在父View中的相对位置。
【30】代码折叠,这个可能是关于开发效率的,我也写在编码规范中,因为这个很有用。Xcode7默认没有开启代码折叠,如果你的方法体行数很长,看起来会很不方便,此时你就可以把方法“收起来”,一个类中的结构就会很清晰。开启方法如下:Xcode菜单-->Preferences-->Text Editing-->勾选Code folding ribbon.如图
【31】推荐方法的第一个花括号直接跟在方法体后,而不是另起一行,这样可以减少代码行。
【32】推荐方法体中的第一行留空,最后一行不留空,这样一个方法就会比较清晰。如图
但是如果该花括号里面又是一个if,for之类的带花括号的语句块,那么上述的第一行可以不留空。
同样,如果花括号内第一行是注释的话,第一行也可以不留空。注释也起到了分隔代码的作用,看起来比较清晰。
再者,如果花括号内只有一行代码,第一行可以不留空。
【33】block中第一行也要留空,同方法体中的第一行留空,使代码清晰。
【34】代表类方法和实例方法的"+"加号,"-"减号后需要一个空格。这是一个非常小的细节,系统默认的方法都是这样的,我们自己声明或者实现一个方法的时候最好也这样。
【35】这一条有点像编程经验了,就是为解决某个问题估算时间。比如要开发某个功能、调试某个bug、给自己一个时间限制,如果在这期间不能解决问题,那么就去寻求帮助。这既是给自己一个压力,也为了不浪费时间。虽然,这一条其实很难做到,我往往由于不甘心而无限拖延时间去解决问题。
【36】由于提到编程经验,就不得不提到版本控制。务必去学会SVN或者Git,就算你是独立开发,也要学会控制自己的代码,当然,你要经常备份你的代码。
UIWebView* webView = [[UIWebView alloc] initWithFrame:CGRectZero];
NSString* secretAgent = [webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
我们在声明一个NSString属性时,对于其内存相关特性,通常有两种选择(基于ARC环境):strong与copy。那这两者有什么区别呢?什么时候该用strong,什么时候该用copy呢?让我们先来看个例子。
我们定义一个类,并为其声明两个字符串属性,如下所示:
@interface TestStringClass ()
@property (nonatomic, strong) NSString *strongString;
@property (nonatomic, copy) NSString *copyedString;
@end
上面的代码声明了两个字符串属性,其中一个内存特性是strong,一个是copy。下面我们来看看它们的区别。
首先,我们用一个不可变字符串来为这两个属性赋值,
- (void)test {
NSString *string = [NSString stringWithFormat:@"abc"];
self.strongString = string;
self.copyedString = string;
NSLog(@"origin string: %p, %p", string, &string);
NSLog(@"strong string: %p, %p", _strongString, &_strongString);
NSLog(@"copy string: %p, %p", _copyedString, &_copyedString);
}
其输出结果是:
origin string: 0x7fe441592e20, 0x7fff57519a48
strong string: 0x7fe441592e20, 0x7fe44159e1f8
copy string: 0x7fe441592e20, 0x7fe44159e200
我们要以看到,这种情况下,不管是strong还是copy属性的对象,其指向的地址都是同一个,即为string指向的地址。如果我们换作MRC环境,打印string的引用计数的话,会看到其引用计数值是3,即strong操作和copy操作都使原字符串对象的引用计数值加了1。
接下来,我们把string由不可变改为可变对象,看看会是什么结果。即将下面这一句
NSString *string = [NSString stringWithFormat:@"abc"];
改成:
NSMutableString *string = [NSMutableString stringWithFormat:@"abc"];
其输出结果是:
origin string: 0x7ff5f2e33c90, 0x7fff59937a48
strong string: 0x7ff5f2e33c90, 0x7ff5f2e2aec8
copy string: 0x7ff5f2e2aee0, 0x7ff5f2e2aed0
可以发现,此时copy属性字符串已不再指向string字符串对象,而是深拷贝了string字符串,并让_ copyedString对象指向这个字符串。在MRC环境下,打印两者的引用计数,可以看到string对象的引用计数是2,而_copyedString对象的引用计数是1。
此时,我们如果去修改string字符串的话,可以看到:因为_ strongString与string是指向同一对象,所以_ strongString的值也会跟随着改变(需要注意的是,此时_ strongString的类型实际上是NSMutableString,而不是NSString);而_ copyedString是指向另一个对象的,所以并不会改变。
由于NSMutableString是NSString的子类,所以一个NSString指针可以指向NSMutableString对象,让我们的strongString指针指向一个可变字符串是OK的。
而上面的例子可以看出,当源字符串是NSString时,由于字符串是不可变的,所以,不管是strong还是copy属性的对象,都是指向源对象,copy操作只是做了次浅拷贝。
当源字符串是NSMutableString时,strong属性只是增加了源字符串的引用计数,而copy属性则是对源字符串做了次深拷贝,产生一个新的对象,且copy属性对象指向这个新的对象。另外需要注意的是,这个copy属性对象的类型始终是NSString,而不是NSMutableString,因此其是不可变的。
这里还有一个性能问题,即在源字符串是NSMutableString,strong是单纯的增加对象的引用计数,而copy操作是执行了一次深拷贝,所以性能上会有所差异。而如果源字符串是NSString时,则没有这个问题。
所以,在声明NSString属性时,到底是选择strong还是copy,可以根据实际情况来定。不过,一般我们将对象声明为NSString时,都不希望它改变,所以大多数情况下,我们建议用copy,以免因可变字符串的修改导致的一些非预期问题。
关于字符串的内存管理,还有些有意思的东西,可以参考。
self.navigationController.navigationBar.barTintColor = [UIColor orangeColor];
self.navigationController.navigationBar.titleTextAttributes = [NSDictionary dictionaryWithObject:[UIColor whiteColor] forKey:NSForegroundColorAttributeName];
这是系统默认的效果
这是改变后的效果
1.在info.plist添加View controller-based status bar appearance字段并将值设置成NO
2.然后在Appdelegate里面添加:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[application setStatusBarHidden:NO];
[application setStatusBarStyle:UIStatusBarStyleLightContent];
return YES;
}
3.给navigationController设置新的背景色和字体颜色
self.navigationController.navigationBar.barTintColor = [UIColor orangeColor];
self.navigationController.navigationBar.titleTextAttributes = [NSDictionary dictionaryWithObject:[UIColor whiteColor] forKey:NSForegroundColorAttributeName];
只需要这简单的三步即可实现
像是一切都戛然而止,
于是把所有留在身后。
谢谢曾经所有的用心和敷衍,
所有的骄傲和卑微,
所有的在乎和辜负,
所有的慷慨和苛刻,
如果不说再见,就一定会再见面,
所以我不说,但把眼泪留在这里。
时光不老,我们不散!
Xcode7采用HTTP请求时,获取到的NSData数据为空, 所以在调用
JSONObjectWithData: 方法时出现错误. 检验http链接可以正常访问. 后来发现在iOS9应用通讯安全策略进行了升级, 已不再支持http这种不安全的协议(What's New in iOS 9.0)
至于为什么http是不安全的, http是超文本传输协议, 信息采用明文传输, 而https则使用SSL加密传输协议进行传输. 既然服务器的链接并不是我们前端所能决定的, 如果一定要发送http协议的请求, 可以修改当前项目的Info.plist文件来实现:
当然, 以上方法还是建立在所访问的请求是HTTP类型的基础上, 一劳永逸的方法就是让服务端升级使用TLS 1.2 SSL加密请求的HTTPS协议.
服务器已支持TLS 1.2 SSL ,但iOS9上还是不行,还要进行链接里的适配操作。”那是因为:ATS只信任知名CA颁发的证书,小公司所使用的 self signed certificate,还是会被ATS拦截。对此,建议使用链接中给出的NSExceptionDomains,并将你们公司的域名挂在下面。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.