解決問題:商業模式中會存在這樣的形式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傳給后台接口內
