添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
光明磊落的黄豆  ·  权威发布 | ...·  2 月前    · 
风流的芹菜  ·  如何利用 python ...·  1 年前    · 
·  阅读

推送开发时通过方法 didRegisterForRemoteNotificationsWithDeviceToken 获取到的DeviceToken转成NSString, 可以用来测试推送是否可用

之前网上查找的方法都是使用NSData的descriptio属性来获取到NSString, 然后去掉大小于号跟空格:

NSString *strToken1 = [[[deviceToken.description stringByReplacingOccurrencesOfString: @"<" withString: @""]
                        stringByReplacingOccurrencesOfString: @">" withString: @""]
                       stringByReplacingOccurrencesOfString: @" " withString: @""];

但是今天调试的时候发现这样, 得到的strToken1打印在控制台上, 是这样的格式:

po strToken1
{length=32,bytes=0x654d21d6e832f37a53f517ec77e2e0b6...手动打码0f1031a4}

中间被 ... 省略了.根本没办法复制去调试. 于是, 换个思路, 其实直接打印deviceToken对象可以得到:

po deviceToken
<654d21d6 e832f37a 53f517ec 77e2e0b6 06dc49bb 手动打码 手动打码 0f1031a4>

通过description属性, 去掉两端大小于号跟空格, 太简单粗暴了,而且不能保证未来一直这样不会出错, 比如现在打印不出来结果就尴尬了. 最好的方法就是直接去按字节读取一边Data然后十六进制输出就行了嘛, 走起:

//OC写法:
UInt8 buffer;//一个个字节读取
NSString *strToken = @"";
for (NSInteger idx = 0; idx < deviceToken.length; idx ++) {
    //一次读一个字节, 读一个就写入strToken里一个
    [deviceToken getBytes:&buffer range:NSMakeRange(idx, 1)];
    //注意补0
    NSString *strBuffer = [NSString stringWithFormat:@"%02x", buffer];
    strToken = [strToken stringByAppendingString:strBuffer];
//Swift写法:
//一句话搞定...真香! 原理: 转成UInt8数组, map转成16进制String, 然后joined成String
let strToken = Array<UInt8>.init(deviceToken).map({String.init(format: "%02x", $0)}).joined(separator: "")

输出看看:

po strToken
654d21d6e832f37a53f517ec77e2e0b606dc49bb手动打码手动打码0f1031a4

突发奇想:

  • 一个字节一个字节读太慢了,是否可以两个字节或者4个,8个字节, 用UInt16, UInt32, UInt64读取呢?岂不是快很多?
    //OC写法:
    UInt16 buffer2;
    NSString *test2 = @"";
    for (NSInteger idx = 0; idx < deviceToken.length; idx += sizeof(UInt16)) {
        [deviceToken getBytes:&buffer2 range:NSMakeRange(idx, sizeof(UInt16))];
        NSString *strBuffer = [NSString stringWithFormat:@"%04x", buffer2];
        test2 = [test2 stringByAppendingString:strBuffer];
    

    输出看看:

    4d65d62132e87af3f553ec17e277b6e0dc06bb49手动打码手动打码100fa431
    

    两两字节反了...因为iOS是小端模式存储的数据, 低位数据会被存放在低位地址, 当一次读两个字节时, 自动会把高地位互换读取, 比如对于字节: 0x4d65, 读取两次一字节打印可以输出4d65,但是如果一次读取2字节, 就会被当作654d读取输出. 因此如果想要一次多度几个字节来加快读取速度, 记得手动换位.

  • 判断大小端模式:
  • //两字节int 放个1, 如果是小端, 会把1存放在低地址位, 然后读低地址字节
    //读到1说明是小端, 否则是大端
    UInt16 t = 1;
    char *p = (char*)&t;
    if (*p == 1) {
        printf(@"小端");
    } else {
        printf(@"大端");
    
  • 验证小端模式:
  •     //一个个字节写入
        UInt8 tint;
        NSMutableData *writer = [NSMutableData new]; //打印writer: <11223344>
        tint = 0x11;
        [writer appendBytes:&tint length:1];
        tint = 0x22;
        [writer appendBytes:&tint length:1];
        tint = 0x33;
        [writer appendBytes:&tint length:1];
        tint = 0x44;
        [writer appendBytes:&tint length:1];
        //用4字节读取
        UInt32 iread;
        [writer getBytes:&iread range:NSMakeRange(0, 4)];
        NSString *strIread = [NSString stringWithFormat:@"%08x", iread]; //输出44332211
    

    如有错误, 欢迎评论指出~谢谢~

  • 分类:
    iOS
    标签: