iOS tips 4

2015-11-18 | 阅读

iOS消息推送证书

对于消息推送,需要去开发者中心申请证书,证书还分成两份,开发环境和生产环境.登陆开发者账号后,Member Center - Certificates,Identifiers & profiles - Certificates.对于已经建立App ID的应用,在Certificates选项中添加新的消息推送证书,当然也可以去在App ID中对推送选项进行修改.

创建推送证书时,需要选择是测试环境Development还是生产环境Production.生产证书还需要一个CRS文件.在Mac的钥匙串访问中,选择顶部菜单的 证书助理 - 从证书颁发机构请求证书,生成一个CSR文件.提交该文件后,就可以成功生成证书了.

下载证书后,双击以进行钥匙串访问,但是出现错误不能修改“System Roots”钥匙串.解决方法,点击钥匙串界面左侧的登陆按键,进入登陆钥匙列表,然后将.cer文件直接拖入钥匙列表中.

钥匙串访问中对推送证书右击,选择导出,导出时将文件保存为.p12文件,并输入一个密码.然后进入终端,运行一下命令将p12文件转换为pem证书文件:

openssl pkcs12 -in MyApnsCert.p12 -out MyApnsCert.pem -nodes

百度云推送所需要要的推送证书,就是这个pem格式的证书.

使用消息推送后出错

当前在iOS9中没有问题,在iOS8中运行时出错,爆异常:

application:didFailToRegisterForRemoteNotificationsWithError:] line:420 content:DeviceToken Error Domain=NSCocoaErrorDomain Code=3000 "未找到应用程序的“aps-environment”的授权字符串"

异常原因是因为证书问题,使用消息推送,一定要确保 app id ,bundle id ,以及profile等文件全部正确,尤其是profile,一定不能使用通配符的profile文件.

而且很有趣的是,在profile不正确地时候,iOS9中依然可以正常推送消息,而iOS8中推送消息报以上异常.对于distribution也就是生产的profile,在Xcode中,只有打生产包的时候才能使用该类profile,其他情况下,企图在build Setting中修改profile,Xcode会爆UUID异常的奇怪错误,以致无法进行修改.

然后后台出现一个错误,是bad ios device token,原因后台使用了百度推送的 生产模式,而APP中使用的是 开发模式, 这里也是需要配置一致的.

OC字面量语法

字符串,NSNumber的字面量语法都很好记,就是字典和数组的语法比较少用,所以记忆不清晰,在这里再记录一下:

NSArrary *animals = @[@"cat",@"dog",@"mouse",@"badger"];
NSString dog = animals[1];

字面量语法终究只是语法糖而已,对于数组的创建,实际上是先创建一个数组,然后再将方括号内的对象加到这个数组中,所以,如果对于一下两种写法,会得到不同的结果:

NSArray *arrayA = [NSArray arrayWithObjects:object1,object2,object3,nil];
NSArray *arrayB = @[object1,object2,object3];

如果object2为nil,则第一种写法会得到只包含object1的数组,而第二种写法会报错-[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[1].

字典的写法如下:

NSDictionary *personData = @{@"firstName":@"Matt",@"lastName":@"Golloway",@"age":@28};

当然,创建字典的时候与创建数组一样,如果有nil值,就会抛出异常.也有与数组相同的下标访问字面量语法:

NSString *firstName = personData[@"firstName"];

关于NSNotificationCenter的传参消息

// 传消息时,anObject放入消息,一般为 NSDictionary的消息对象.
- (void)postNotificationName:(NSString *)aName object:(nullable id)anObject;
// 接收消息时,数据由NSNotification中获取出来.
- (void)loginSuccessNotification:(NSNotification*)notification{
	NSDictionary *dic = [notification object];

XCode调试,僵尸模式NSZombieEnabled

在跟踪对象过程中,使用僵尸模式,设置NSZombieEnabled属性,启动后会用一个僵尸对象来替换原来默认的dealloc实现.也就是说,在引用计数为0时,该僵尸对象会继续接受你发送的消息,并跳入调试器.

Scheme 中勾选Enable Zombie Objects选项.然而只有模拟器才有Zombie,然后,为了更好得抓取某些数据,必须去 profile - instruments中来获取.

通过UIView获取UIViewController

UIView和UIViewController都继承与 UIResponder ,而在消息者链中, UIView的上层是 自己的ViewController或者supView. 所以,一直访问 nextResponder就可以得到一个UIView所属的ViewController.

- (UIViewController *)findViewController:(UIView *)sourceView
{
    id view=sourceView;
    while (view) {
        view = ((UIResponder *)view).nextResponder;
        if ([view isKindOfClass:[UIViewController class]]) {
            break;
        }
    }
    return view;
}

C语言中的Struct相等判断

必须判断其每个属性都相等,不能直接使用==进行判断,因为Struct的名称只是表示其成员变量的第一个元素.

iOS7中NavigationController的pop push动画

快速的执行多个动画操作,会导致崩溃,所以,在iOS7中要对这些动画进行管理,建议写一个队列来保存当前执行中和将要执行的动画,在动画完成时,即动画执行的 viewController的 viewDidAppear和viewDidDisappear时,设定动画完成,并检测当前序列中是否有其他动画需要执行,然后执行.

inline函数中有static变量

使用inline函数中有static变量,突然害怕,inline是在编译期将代码直接拷贝到函数调用的地方,那这个static变量不就危险了?

即使编译器将inline函数内部的代码复制到多个地方,但是,static变量是相互联系的,共同指向一个全局数据区的数据,所以不会多次初始化,只会执行第一次初始化,也就是安全的.

JS中的Call和apply

JS中的函数也是一个对象.call和apply都是去调用js方法,然后劫持另一个对象的this指针.call与apply的区别在于前者接受多个参数,而后者只接受两个参数,一个this指针对象,一个是参数数组.

function Person(name,age) {    
this.name=name;    
this.age=age;    
this.money = 250;  
}   
  
function myFun(name,age) {
	alert(name + age)       
    alert(this.money);  
}  

var money = 100;  
// window表示当前对象,这里的window有一个属性为money = 100,而劫持this指针的意思,执行的函数是myFun,但是其中的this指针并不是指向myFun对象,而是指向第一个参数window.参数数组为空.
myFun.apply(window,['1','2']);
//两者效果相同
myFun.call(window,'1','2');

对于apply,其接受的是参数数组,但是依旧会将以正常参数的形式使用.

JAVA中的AES加密

java中的AES加密,默认是 ECB模式,以及PKCS5Padding的填充方式.

PKCS5PaddingPKCS7Padding两种填充方式相似,除了规定的Block块的大小不同.前者规定的块大小为16位,后者为1-255位之间,填充算法是填固定值:

value = k - (l mod k)// k= 块大小,l= 数据长度

所以,对于8位的PKCS7Padding就是与PKCS5Padding填充方式完全一样.

iOS开发时,实现委托时,一定要仔细看其介绍,理解每个参数的值,不要想当然.

查询数组时,数组下标不是自己创建的,那就是绝对不安全的,一定要加上越界判断,否则有极大可能性数组越界.