zoukankan      html  css  js  c++  java
  • iOS渠道分包2种模式之包内注入文件分包(iOS13验证签名问题)

    解决问题:商业模式中会存在这样的形式1款app需要不同的运用团队(工会)去分包推广,谁推广的包下载的人数都会在服务器记录,不同渠道的标示唯一来区分。

    iOS渠道分包模式有两种着重讲第二种

    一、IDFA模式

    IDFA全称应该是Identifier For Advertising, 一个跟device相关的唯一标识符,可以理解为广告id,apple公司提供的用于追踪用户的广告标识符,可以用来打通不同app之间的广告。适用于对外:例如广告推广,换量等跨应用的用户追踪等。比如你在淘宝里搜索了某个商品之后,你在用浏览器去浏览网页的时候,那个网页的广告就会给你展示相应的那个商品的广告。当然你可以重置你的IDFA,使别人不能再track到你的行为。

    缺点:如果用户完全重置系统((设置程序 -> 通用 -> 还原 -> 还原位置与隐私) ,这个广告标示符会重新生成。 另外如果用户明确的还原广告(设置程序-> 通用 -> 关于本机 -> 广告 -> 还原广告标示符) ,那么广告标示符也会重新生成

    因为IDFA是可以改变的,所以之前很多人都想拿到一个唯一不变的值比如说UDID(Unique Device Identifier, 这个是跟手机绑定的,用户不能更改),但是Apple后来禁止苹果应用获取UDID。所以现在IDFA成为了iphone用户的标识符的标准。

    IDFA是一串16进制的32位串。有了IDFA之后,相当于广告追踪,你所有的浏览历史都会被别的商家利用,给你推相同或相似的广告。

    另外一个apple上可以用到的标识符是UUID,Universally Unique IDentifier,在应用程序使用生命期间,这个 UUID保持不变。但如果用户重新安装,那么这个 UUID 就会发生变化。

    还有一个类似的标识符叫做IDFV,Identifier for Vendor, 来自同一个开发商比如亚马逊下边的购物app和kindle app,此值是相同的。这样可以做到同一开发商下的不同app做到信息共享。

    关于广告标示符的还原,有一点需要注意:如果程序在后台运行,此时用户“还原广告标示符”,然后再回到程序中,此时获取广 告标示符并不会立即获得还原后的标示符。必须要终止程序,然后再重新启动程序,才能获得还原后的广告标示符。

    在同一个设备上的所有App都会取到相同的值,是苹果专门给各广告提供商用来追踪用户而设的,用户可以在 设置|隐私|广告追踪 里重置此id的值,或限制此id的使用,故此id有可能会取不到值,但好在Apple默认是允许追踪的,而且一般用户都不知道有这么个设置,所以基本上用来监测推广效果,是戳戳有余了。

    注意:由于idfa会出现取不到的情况,故绝不可以作为业务分析的主id,来识别用户。 

    因此,IDFA就是用来跟踪广告推广的,而UUID虽然每次不同,但是可以自己手动存入Keychain来进行唯一性的确保,这么说来IDFA就是广告商投放的时候使用,而UUID就是自己后台来判断用户是否换了设备,或者信息不一致需要重新登录的业务。

    好了, 总结一下这三个标识符:

    UUID, app之内信息共享。

    IDFV, 同一开发商下的不同app信息共享。

    IDFA,同一设备下的不同app信息共享。

    二、母包(没有种植文件的叫母包,种植完文件的叫子包,母包只有一个用来种植,子包可以多个)种植文件的形式

    1、我们随便打一个ipa包;

    2、然后通过后台或者window电脑注入一个文件-我们定义文件名为channel_xxxx(xxxx为渠道id);

    key:关键来了我们怎么注入一个文件才能在用户打开app的时候取到这个文件名?

    3、然后会有一个文件路径12345->Payload->bixinlive,然后bixinlive显示包内容:里边有一个_CodeSignature文件(这个文件是验证签名的文件),在他的路径下注入一个名字问channel_EFS89V的文件;

    4、代码取到这个文件的文件名; 

     NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
              NSString *path = [NSString stringWithFormat:@"%@/%@", bundlePath, @"_CodeSignature"];
        NSFileManager *manager = [NSFileManager defaultManager];
        NSString *channel = @"";
        if ([manager fileExistsAtPath:path]) {
           NSArray *allPath =[manager subpathsAtPath:path];
              //4.遍历所有的子路径
              for (NSString *subPath in allPath) {
                  if ([subPath containsString:@"channel_"]) {
                      channel = [subPath substringFromIndex:@"channel_".length];
                  }
              }
        }
    //然后请求接口把渠道id传给后台。

    iOS13签名验证这种方式会验证签名不通过;

    三、解决iOS13的问题

    iOS13会验签_CodeSignature的文件的所有内容文件;

    所以我们要换一种方案;

    偶然发现苹果在验证签名的时候不会验签文件夹。所以我们只需要在_CodeSignature同一级别文件夹(非子文件夹)种植一个文件夹channel,文件夹内同样的有一个文件夹(记住都要是文件夹)名字为channel_EFS89V通过二的方式去文件夹的名字。

    然后取文件夹的名字作为渠道id

     AFHTTPSessionManager *session = [AFHTTPSessionManager manager];
        NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
        NSString *path2 = [NSString stringWithFormat:@"%@/%@", bundlePath, @"channel"];
    
       NSFileManager *manager = [NSFileManager defaultManager];
       NSString *channel = @"";
        if ([NSString isEmpty:channel]) {
            if ([manager fileExistsAtPath:path2]) {
                NSArray *allPath =[manager subpathsAtPath:path2];
                //4.遍历所有的子路径
                for (NSString *subPath in allPath) {
                    if ([subPath containsString:@"channel_"]) {
                        channel = [subPath substringFromIndex:@"channel_".length];
                    }
                }
            }
        }
    //取到的channel问渠道id,然后吧channel作为渠道id传给后台接口内
  • 相关阅读:
    迭代器
    LinkedList存储一副扑克牌,实现洗牌功能。
    线程
    堆栈、队列
    路由-第7集
    javascript中split字符串分割函数
    this的用法
    什么是AOP面向切面编程
    Servlet与JSP的区别
    堆(heap)、栈(stack)、方法区(method)
  • 原文地址:https://www.cnblogs.com/PeterWolf/p/11660007.html
Copyright © 2011-2022 走看看