自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

iOS 是如何獲取夜間模式啟動(dòng)圖緩存路徑?

移動(dòng)開(kāi)發(fā)
本文通過(guò)對(duì) applicationState.db 進(jìn)行一系列的分析,最終實(shí)現(xiàn)了在模擬器下獲取獲取夜間模式啟動(dòng)圖緩存路徑的訴求。

你是否了解過(guò)iOS 是如何獲取夜間模式啟動(dòng)圖緩存路徑??

百度APP技術(shù)團(tuán)隊(duì)曾經(jīng)發(fā)布過(guò)一篇深夜暗坑 - iOS啟動(dòng)圖異常修復(fù)方案。

該文章分享了一些關(guān)于啟動(dòng)圖的研究,但是通過(guò)文章的內(nèi)容,我們?nèi)匀粺o(wú)法解決這個(gè)問(wèn)題:iOS 是如何獲取夜間模式啟動(dòng)圖緩存路徑?

[[353923]]

經(jīng)過(guò)一系列的研究,作者獲了模擬器場(chǎng)景下的方案,現(xiàn)分享作者的研究記錄。

方案一:嘗試通過(guò)啟動(dòng)圖文件名判斷緩存圖是否屬于夜間模式

我們首先對(duì) 深夜暗坑 - iOS啟動(dòng)圖異常修復(fù)方案 提供的信息進(jìn)行提煉。

原文提供了以下2個(gè)信息:

  • 緩存啟動(dòng)圖的文件名具有規(guī)則,但其規(guī)則我們不得而知
  • 4 張啟動(dòng)圖的文件名
  1. ├── 1FFD332B-EBA0-40C9-8EEE-BEC9AEF7C41A@3x.ktx 
  2. ├── 96920D11-6312-4D69-BBDB-AFBB52DBDDB3@3x.ktx 
  3. ├── 98F7B5B1-5B3B-478B-93A8-ED3DE6492AD1@3x.ktx 
  4. └── D9D48845-8565-42CE-A834-479CC9CC8BAD@3x.ktx 

通過(guò) 4 個(gè)文件名,我們可以發(fā)現(xiàn)4張圖片的命名都符合以下規(guī)則:

  1. xxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx 

再結(jié)合蘋(píng)果官方文檔 NSUUID 的內(nèi)容:

  1. `NSUUID`conform to RFC 4122 version 4 and are created with random bytes. 

我們可以得到以下結(jié)論:

  • 4 個(gè)文件名的都是通過(guò) NSUUID 動(dòng)態(tài)生成
  • 文件名只包含版本 4,不再包含其它有效的信息

方案二:通過(guò)系統(tǒng)文件進(jìn)行分析

方案一失敗后,我們猜測(cè) iOS 是通過(guò)其它方式保存夜間模式啟動(dòng)圖緩存路徑信息。

經(jīng)過(guò)一系列的測(cè)試,作者發(fā)現(xiàn)了 applicationState.db 文件。

applicationState.db

系統(tǒng)會(huì)通過(guò) applicationState.db 保存程序狀態(tài)等各類(lèi)信息,當(dāng)然,也會(huì)包括夜間模式啟動(dòng)圖緩存路徑信息。

本文分析的文件位于 ~/Library/Developer/CoreSimulator/Devices/1F9B22C5-E446-4881-AFE4-3373E3513C59/data/Library/FrontBoard/applicationState.db

其中,1F9B22C5-E446-4881-AFE4-3373E3513C59代表 iOS 模擬器的設(shè)備ID。

模擬器的完整ID列表可以通過(guò)命令 plutil -p ~/Library/Developer/CoreSimulator/Devices/device_set.plist 查看

測(cè)試環(huán)境

為了方便對(duì)系統(tǒng)文件進(jìn)行分析,本文以 iOS 14 模擬器為目標(biāo)進(jìn)行分析。

版本信息如下所示:

  1. (lldb) platform status 
  2.   Platform: ios-simulator 
  3.     Triple: x86_64h-apple-macosx 
  4. OS Version: 10.15.6 (19G2021) 
  5.     Kernel: Darwin Kernel Version 19.6.0: Thu Jun 18 20:49:00 PDT 2020; root:xnu-6153.141.1~1/RELEASE_X86_64 
  6.   Hostname: 127.0.0.1 
  7. WorkingDir: / 
  8.   SDK Path: "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk" 
  9. No devices are available. 

另外,后續(xù)的代碼會(huì)假定 Bundle identifier 是 test.SplashTest

解析 applicationState.db

先嘗試通過(guò) file命令獲取 applicationState.db文件類(lèi)型:

  1. file ~/Library/Developer/CoreSimulator/Devices/1F9B22C5-E446-4881-AFE4-3373E3513C59/data/Library/FrontBoard/applicationState.db 

輸出:

  1. SQLite 3.x databaselast written using SQLite version 3032003 

測(cè)試成功,通過(guò) file 命令的輸出可以看到文件類(lèi)型是 SQLite 3.x。

db 結(jié)構(gòu)

下面,再通過(guò) SQLite 相關(guān)的工具對(duì)該文件進(jìn)行dump,我們可以得到以下信息:

  1. sqlite> .schema 
  2. CREATE TABLE schema(version INT NOT NULL); 
  3. CREATE TABLE key_tab (id INTEGER PRIMARY KEYkey TEXT NOT NULLUNIQUE(key)); 
  4. CREATE TABLE application_identifier_tab (id INTEGER PRIMARY KEY, application_identifier TEXT NOT NULLUNIQUE(application_identifier)); 
  5. CREATE TABLE kvs (    id INTEGER PRIMARY KEY,    application_identifier INT REFERENCES application_identifier_tab(id),    key INT REFERENCES key_tab(id),    value BLOB,    UNIQUE(application_identifier, key)); 
  6. CREATE INDEX kvs_keys ON kvs(key); 
  7. CREATE INDEX kvs_application_identifiers ON kvs(application_identifier); 
  8. CREATE VIEW kvs_debug AS     SELECT application_identifier_tab.application_identifier, key_tab.key, value FROM application_identifier_tab, key_tab, kvs WHERE         kvs.application_identifier=application_identifier_tab.id         AND kvs.key=key_tab.id 
  9. /* kvs_debug(application_identifier,"key",value) */; 

application_identifier_tab 保存了設(shè)備安裝的應(yīng)用列表( id 是主鍵,application_identifier 是 APP 的Bundle identifier)

key_tab 負(fù)責(zé)記錄常量字符串。

經(jīng)過(guò)測(cè)試,夜間模式啟動(dòng)圖緩存路徑的路徑屬于 XBApplicationSnapshotManifest。

 

  1. sqlite> .schema key_tab 
  2. CREATE TABLE key_tab (id INTEGER PRIMARY KEYkey TEXT NOT NULLUNIQUE(key)); 
  3. sqlite> .width 2 50 
  4. sqlite> select * from key_tab; 
  5. id  key 
  6. --  -------------------------------------------------- 
  7. 1   SBLaunchImageIngestionInfo 
  8. 2   XBApplicationSnapshotManifest 
  9. 3   _SBScenes 
  10. 4   SBApplicationShortcutItems 
  11. 5   compatibilityInfo 
  12. 6   SBApplicationRecentlyUpdated 
  13. 7   SBApplicationRecentlyUpdatedTimerStartDate 

kvs_debug 負(fù)責(zé)串聯(lián)上面的3個(gè)表:

  1. kvs.application_identifier=application_identifier_tab.id 
  2. kvs.key=key_tab.id 

通過(guò) test.SplashTest,可以獲取到4個(gè)結(jié)果,其中第2負(fù)責(zé)保存快照相關(guān)信息

  1. sqlite> .width 15 32 8 
  2. sqlite> SELECT * FROM kvs_debug WHERE application_identifier = 'test.SplashTest'
  3. application_ide  key                               value 
  4. ---------------  --------------------------------  -------- 
  5. test.SplashTest  _SBScenes                         bplist00 
  6. test.SplashTest  XBApplicationSnapshotManifest     bplist00 
  7. test.SplashTest  SBApplicationRecentlyUpdated      0 
  8. test.SplashTest  compatibilityInfo                 bplist00 

導(dǎo)出XBApplicationSnapshotManifest

經(jīng)過(guò)一番研究,我們發(fā)現(xiàn) XBApplicationSnapshotManifest 對(duì)應(yīng)的value 就是 SplashBoard 庫(kù) XBApplicationSnapshotManifestImpl 類(lèi)的持久化結(jié)果。

所以,我們可以通過(guò)通過(guò)以下代碼,對(duì) value 的內(nèi)容進(jìn)行 dump。

  1. +(void)load {     
  2.     void *lib  =  dlopen("/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/SplashBoard.framework/SplashBoard", RTLD_NOW); 
  3.     printf("%p", lib); 
  4.     [self dump:@"/Users/test/Library/Developer/CoreSimulator/Devices/1F9B22C5-E446-4881-AFE4-3373E3513C59/data/Library/FrontBoard/XBApplicationSnapshotManifest.plist"]; 
  5.  
  6. +(void)dump:(NSString *)path { 
  7.     NSData *data0 = [NSData dataWithContentsOfFile:path]; 
  8.     NSPropertyListFormat f = -1; 
  9.     NSError *error = nil; 
  10.     NSData *data1 = [NSPropertyListSerialization propertyListWithData:data0 options:NSPropertyListReadStreamError format:&f error:&error]; 
  11.     if (f==kCFPropertyListXMLFormat_v1_0) { 
  12.         NSLog(@"kCFPropertyListXMLFormat_v1_0"); 
  13.     } 
  14.     id obj = [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:data1 error:&error]; 
  15.     NSLog(@"%@",obj); 

dump 結(jié)果:

  1. <XBApplicationSnapshotManifestImpl: 0x600000050d80; clientCount: 0> { 
  2.     containerIdentity = 0x0; 
  3.     snapshots = { 
  4.         <XBApplicationSnapshotGroup: 0x600002e65ea0; identifier: test.SplashTest - {DEFAULT GROUP}> { 
  5.             <XBApplicationSnapshot: 0x7fcb53f04d90; identifier: CE275D00-5732-4AFD-88FD-00BAE541EC12; launchInterfaceIdentifier: __from_UILaunchStoryboardName__; contentType: GeneratedDefault; referenceSize: {375, 812}; interfaceOrientation: LandscapeLeft; userInterfaceStyle: Dark> { 
  6.                 creationDate = September 27, 2020 at 6:08:50 PM GMT+8; 
  7.                 keepsImageAccessUntilExpiration = NO
  8.                 hasGenerationContext = NO
  9.                 context = { 
  10.                     contentType = GeneratedDefault; 
  11.                     fullScreen = YES; 
  12.                     referenceSize = {375, 812}; 
  13.                     interfaceOrientation = LandscapeLeft; 
  14.                     userInterfaceStyle = Dark; 
  15.                     additionalContext = { 
  16.                         statusBarSettings = <XBStatusBarSettings: 0x600002c580f0; hidden: YES; style: 0x0; backgroundActivityEnabled: NO>; 
  17.                     } 
  18.                 } 
  19.                 imageContext = { 
  20.                     scale = 3.0; 
  21.                     opaque = YES; 
  22.                     fileRelativeLocation = default
  23.                     fileFormat = png; 
  24.                 } 
  25.             }; 
  26.             <XBApplicationSnapshot: 0x7fcb57004830; identifier: B9DAB53E-29D9-47D2-873E-5772DE9220D1; launchInterfaceIdentifier: __from_UILaunchStoryboardName__; contentType: GeneratedDefault; referenceSize: {375, 812}; interfaceOrientation: Portrait; userInterfaceStyle: Light> { 
  27.                 creationDate = September 27, 2020 at 6:08:50 PM GMT+8; 
  28.                 lastUsedDate = September 27, 2020 at 6:08:50 PM GMT+8; 
  29.                 keepsImageAccessUntilExpiration = NO
  30.                 hasGenerationContext = NO
  31.                 context = { 
  32.                     contentType = GeneratedDefault; 
  33.                     fullScreen = YES; 
  34.                     referenceSize = {375, 812}; 
  35.                     interfaceOrientation = Portrait; 
  36.                     userInterfaceStyle = Light; 
  37.                     additionalContext = { 
  38.                         statusBarSettings = <XBStatusBarSettings: 0x600002c5c1a0; hidden: NO; style: 0x0; backgroundActivityEnabled: NO>; 
  39.                     } 
  40.                 } 
  41.                 imageContext = { 
  42.                     scale = 3.0; 
  43.                     opaque = YES; 
  44.                     fileRelativeLocation = default
  45.                     fileFormat = png; 
  46.                 } 
  47.             }; 
  48.             <XBApplicationSnapshot: 0x7fcb57004b60; identifier: 6B84614D-0867-4048-BE04-8E22E6742DDF; launchInterfaceIdentifier: __from_UILaunchStoryboardName__; contentType: GeneratedDefault; referenceSize: {375, 812}; interfaceOrientation: Portrait; userInterfaceStyle: Dark> { 
  49.                 creationDate = September 27, 2020 at 6:08:50 PM GMT+8; 
  50.                 keepsImageAccessUntilExpiration = NO
  51.                 hasGenerationContext = NO
  52.                 context = { 
  53.                     contentType = GeneratedDefault; 
  54.                     fullScreen = YES; 
  55.                     referenceSize = {375, 812}; 
  56.                     interfaceOrientation = Portrait; 
  57.                     userInterfaceStyle = Dark; 
  58.                     additionalContext = { 
  59.                         statusBarSettings = <XBStatusBarSettings: 0x600002c5c2d0; hidden: NO; style: 0x0; backgroundActivityEnabled: NO>; 
  60.                     } 
  61.                 } 
  62.                 imageContext = { 
  63.                     scale = 3.0; 
  64.                     opaque = YES; 
  65.                     fileRelativeLocation = default
  66.                     fileFormat = png; 
  67.                 } 
  68.             }; 
  69.             <XBApplicationSnapshot: 0x7fcb57005140; identifier: D3E8D00C-EE33-466B-98A6-7E60865D8001; launchInterfaceIdentifier: __from_UILaunchStoryboardName__; contentType: GeneratedDefault; referenceSize: {375, 812}; interfaceOrientation: LandscapeLeft; userInterfaceStyle: Light> { 
  70.                 creationDate = September 27, 2020 at 6:08:50 PM GMT+8; 
  71.                 keepsImageAccessUntilExpiration = NO
  72.                 hasGenerationContext = NO
  73.                 context = { 
  74.                     contentType = GeneratedDefault; 
  75.                     fullScreen = YES; 
  76.                     referenceSize = {375, 812}; 
  77.                     interfaceOrientation = LandscapeLeft; 
  78.                     userInterfaceStyle = Light; 
  79.                     additionalContext = { 
  80.                         statusBarSettings = <XBStatusBarSettings: 0x600002c5c400; hidden: YES; style: 0x0; backgroundActivityEnabled: NO>; 
  81.                     } 
  82.                 } 
  83.                 imageContext = { 
  84.                     scale = 3.0; 
  85.                     opaque = YES; 
  86.                     fileRelativeLocation = default
  87.                     fileFormat = png; 
  88.                 } 
  89.             }; 
  90.         }; 
  91.     } 

SplashBoard 部分類(lèi)圖

通過(guò)類(lèi)信息,整理如下所示(只包含關(guān)鍵屬性):

獲取夜間模式啟動(dòng)圖緩存路徑

通常上面的內(nèi)容,我們可以對(duì) iOS 獲取夜間模式啟動(dòng)圖緩存路徑的流程進(jìn)行合理的猜測(cè)

啟動(dòng)時(shí),會(huì)先通過(guò) XBApplicationSnapshotGroup的identifier 獲取test.SplashTest - {DEFAULT GROUP} 的啟動(dòng)圖列表

再通過(guò) XBApplicationSnapshot 的 userInterfaceStyle = Dark; 和 interfaceOrientation = Portrait;等信息,判斷啟動(dòng)時(shí)應(yīng)該使用

  1. <XBApplicationSnapshot: 0x7fcb57004b60; identifier: 6B84614D- 
  2. 0867-4048-BE04-8E22E6742DDF; launchInterfaceIdentifier:  
  3. __from_UILaunchStoryboardName__; contentType: GeneratedDefault;  
  4. referenceSize: {375, 812}; interfaceOrientation: Portrait;  
  5. userInterfaceStyle: Dark> 

最后再通過(guò) XBApplicationSnapshot的 _relativePath 拼接啟動(dòng)圖的真實(shí)路徑

  1. ~/Library/Developer/CoreSimulator/Devices/1F9B22C5-E446-4881- 
  2. AFE4-3373E3513C59/data/Containers/Data/Application 
  3. /FA902232-17D2-495F-B23E-410349A9921C/Library/SplashBoard/Snapshots 
  4. /test.SplashTest - {DEFAULT GROUP}/6B84614D-0867-4048- 
  5. BE04-8E22E6742DDF@3x.ktx 

總結(jié)

本文通過(guò)對(duì) applicationState.db 進(jìn)行一系列的分析,最終實(shí)現(xiàn)了在模擬器下獲取獲取夜間模式啟動(dòng)圖緩存路徑的訴求。

 

責(zé)任編輯:未麗燕 來(lái)源: 酷酷的哀殿的博客
相關(guān)推薦

2021-06-28 14:35:36

iOSAPP緩存

2020-05-06 19:16:45

Windows 10Windows微軟

2018-08-17 15:56:07

APP夜間模式理性思考

2021-05-06 06:22:36

手機(jī)夜間模式藍(lán)光

2019-02-01 09:10:01

2017-03-31 14:31:08

QQ瀏覽器修復(fù)功能特性

2020-12-28 12:37:36

緩存擊穿穿透

2021-08-26 17:36:42

Floyd算法數(shù)據(jù)結(jié)構(gòu)

2018-06-22 13:25:14

2020-03-30 18:00:39

微信iOS應(yīng)用移動(dòng)應(yīng)用

2021-10-30 20:49:24

算法 Xpath路徑

2022-02-27 15:46:55

iOS省電模式技巧

2019-01-03 09:45:02

Ubuntu救援模式

2019-04-15 14:23:00

Windows 10Windows操作系統(tǒng)

2009-06-18 15:23:49

緩存控制器模式Ajax模式

2021-11-29 10:27:24

設(shè)計(jì)模式程序員

2011-09-30 09:28:40

蘋(píng)果謠言

2011-02-24 11:22:12

Konqueror

2020-01-14 11:45:31

安全模式Windows 10Windows

2011-07-25 16:50:24

Windows安全模式
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)