### UI结构
- 启动图 UIView包装 GDTSplashAlignImageView
- **首页kSUScrollView**
- **推荐: KSUITableView**
- KSLayoutableTimelineFeedCellV2: KSLayoutableFeedBaseCell
- KSAdapterImageView 动画ImageView
- **关注:KSUITableView**
- KSBannerEntryView: KSBaseVuew 顶部横向collectionview
- KSLayoutableTimelineFeedCellV2:KSLayoutableFeedBaseCell 内容cell
- KSLayoutableCycleScollFeedCell: KSLaoutableFeedCell
- **直播:KSEntertainmentView:KSBaseView**
- KSHippyWrapperView: UIView
- RCTRootView: UIView (RN: RCTBridge通信)
- RCTBaseListView: UIView
- UITableView
- RCTBaseListCell
- RCTBaseListItemView: UIView cell里封装的所有UI空间
- RCTView:UIView(封装的BaseView,内有切圆角等相关处理)
- RCTBackgroundImageCacheManager:NSObject图片加载、展示、缓存、查找缓存
- **北京(附近推荐): KSUITableView**
- KSongRefreshScrollViewHeader
- KSongLoadMoreScrollViewFooterView
- KSLayoutableTimelineFeedCellV2: KSLayoutableFeedBaseCell
- KSAdapterImageView
- **直播页**
- KSLiveShowPageScrollView
- KSLiveShowVideoCantainView:UIVIew 直播封装View
- KSLiveShowVideoCDNView:UIView
- GPUImageView
RCTRootView: Ksong、抖音
### 启动
- **[KSAppDelegate didFinishLaunchingWithOptions]**
```
//1. launch 初始化,记录启动时间等
[KSLaunchManager sharedManager]finishStageTimer: withLog:@"Finish launchingWithOptions"];
[KSLaunchManager sharedManager] startStageTimer: withLog:@"Start init"];
[KSLaunchManager sharedManager] setIsStartApp]
....
// 2. 自动播放配置
setFeedAutoPlaySet
setFeedPreviewPlaySet
//NSUserDefaults_FeedPreviewPlaySetting(settingvc)
//3. 数据合并前
runLaunchTaskBeforeDatabaseComplatibleCheck];
//[KSLaunchManager executeInMain: as:@"disableLandscapeRotation"] ^ {
//}
//InitWXApiWrapper
//setupKSImgProcEnv
//KSPlugDeviveStatisManagerSetupObserver
//[KSLaunchManager sharedManager] finishStageTimer: withLog:@"finish runLaunchTaskBeforeDatabaseComplatibleCheck"]
...
//4. 初始化主界面
bool [KSCoredataManager sharedInstance] isDataBaseCompatible
if isDataBaseCompatible {
executeInMain: as:@"setupManagedObjectContexts"];
//log
[WnsSdkHelper sharedInstance]
//展示隐私弹窗,rootvc
checkAndShowPrivacyGuideIfNeeded
} else {
// 数据迁移vc
[KSDBMigrationNavVC alloc] initWithRootViewController:
setRootViewController:
//数据迁移...
setMigrationStatus
dispatch_async(global_queue) {
}
....
}
```
### SDK
ImSDK.framework
KSVideoPlayer
Lottie
```
bool -[KSAppDelegate application:didFinishLaunchingWithOptions:](void * self, void * _cmd, void * arg2, void * arg3) {
r31 = r31 - 0xc0;
*(r31 + 0x60) = r28;
*(0x70 + r31) = r27;
*(r31 + 0x70) = r26;
*(0x80 + r31) = r25;
*(r31 + 0x80) = r24;
*(0x90 + r31) = r23;
*(r31 + 0x90) = r22;
*(0xa0 + r31) = r21;
*(r31 + 0xa0) = r20;
*(0xb0 + r31) = r19;
*(r31 + 0xb0) = r29;
*(0xc0 + r31) = r30;
r20 = self;
*(r31 + 0x58) = *___stack_chk_guard;
r19 = [arg3 retain];
r0 = [*objc_cls_ref_KSLaunchManager sharedManager];
r0 = [r0 retain];
[r0 finishStageTimer:zero_extend_64(0x0) withLog:@"Finish launchingWithOptions"];
[r0 release];
r0 = [*objc_cls_ref_KSLaunchManager sharedManager];
r0 = [r0 retain];
[r0 startStageTimer:zero_extend_64(0x1) withLog:@"Start init"];
[r0 release];
[r20 setLaunchOptionsStore:r19];
r0 = [KSLaunchIdManager sharedManager];
r0 = [r0 retain];
[r0 setIsStartApp:zero_extend_64(0x1)];
[r0 release];
r0 = [KSLaunchIdManager sharedManager];
r0 = [r0 retain];
[r0 setLaunchOptions:r19];
[r0 release];
r1 = @selector(setFeedAutoPlaySet:);
r0 = r20;
asm { movn x2, #0x0 };
objc_msgSend(r0, r1);
r1 = @selector(setFeedPreviewPlaySet:);
r0 = r20;
asm { movn x2, #0x0 };
objc_msgSend(r0, r1);
[r20 runLaunchTaskBeforeDatabaseComplatibleCheck];
r0 = [KSCoredataManager sharedInstance];
r29 = r29;
r0 = [r0 retain];
r24 = [r0 isDataBaseCompatible];
[r0 release];
r0 = *(r25 + 0x8f0);
if (r24 != 0x0) {
[r0 executeInMain:0x1074e69c0 as:@"setupManagedObjectContexts"];
if ([KSWnsConfigManager boolConfig_Switch:@"EnableWnsLogOptimize"] != 0x0) {
r0 = [WnsLoggerWrapper sharedInstance];
r29 = r29;
r0 = [r0 retain];
[r0 setPrefix:@"app"];
[r0 release];
}
[[WnsSdkHelper sharedInstance] retain];
*(r31 + 0x48) = @"KS";
*(0x58 + r31) = @"INFO";
[[NSDictionary dictionaryWithObjects:r31 + 0x50 forKeys:r31 + 0x48 count:stack[2048]] retain];
[KSWnsConfigManager boolConfig_Switch:@"EnableWnsLogOptimize"];
r1 = @selector(log:file:func:line:module:EFDict:msg:);
asm { stp x8, x0, sp };
objc_msgSend(r21, r1);
[r23 release];
[r21 release];
*(r31 + 0x18) = __NSConcreteStackBlock;
*(r31 + 0x20) = *0x106e17a70;
*(r31 + 0x28) = 0x101f6d4cc;
*(0x38 + r31) = 0x1074add78;
*(r31 + 0x38) = r20;
*(r31 + 0x40) = [r19 retain];
[r20 checkAndShowPrivacyGuideIfNeeded:r31 + 0x18];
r0 = *(r31 + 0x40);
}
else {
r0 = [r0 sharedManager];
r0 = [r0 retain];
[r0 abort];
[r0 release];
r0 = [UIApplication sharedApplication];
r0 = [r0 retain];
[r0 setStatusBarHidden:zero_extend_64(0x0) withAnimation:zero_extend_64(0x0)];
[r0 release];
r0 = [r20 window];
r29 = r29;
r0 = [r0 retain];
[r0 release];
if (r0 == 0x0) {
[r20 generateWindow];
}
r25 = [[UIViewController alloc] init];
r0 = [KSDBMigrationNavVC alloc];
r0 = [r0 initWithRootViewController:r25];
r26 = r0;
[r0 setNavigationBarHidden:zero_extend_64(0x1)];
r0 = [r20 window];
r0 = [r0 retain];
[r0 setRootViewController:r26];
[r27 release];
[r26 release];
[r25 release];
r23 = [[KSDBMigrationViewController alloc] init];
[r20 setDataBaseMigrationVC:r23];
[r23 release];
r23 = [[r20 dataBaseMigrationVC] retain];
r0 = [r20 window];
r0 = [r0 retain];
[r0 setRootViewController:r23];
[r22 release];
[r23 release];
r0 = [KSCoredataManager sharedInstance];
r0 = [r0 retain];
[r0 setDelegate:r20];
[r0 release];
r0 = [KSCoredataManager sharedInstance];
r0 = [r0 retain];
[r0 setMigrationStatus:zero_extend_64(0x1)];
[r0 release];
r0 = dispatch_get_global_queue(zero_extend_64(0x2), zero_extend_64(0x0));
r0 = [r0 retain];
dispatch_async(r0, 0x1074e69e0);
r0 = r20;
}
[r0 release];
[r19 release];
if (*___stack_chk_guard == *(r31 + 0x58)) {
r0 = zero_extend_64(0x1);
}
else {
r0 = __stack_chk_fail();
}
return r0;
}
```
```
void -[KSAppDelegate checkAndShowPrivacyGuideIfNeeded:](void * self, void * _cmd, void * arg2) {
r31 = r31 - 0x80;
*(r31 + 0x30) = r26;
*(0x40 + r31) = r25;
*(r31 + 0x40) = r24;
*(0x50 + r31) = r23;
*(r31 + 0x50) = r22;
*(0x60 + r31) = r21;
*(r31 + 0x60) = r20;
*(0x70 + r31) = r19;
*(r31 + 0x70) = r29;
*(0x80 + r31) = r30;
r29 = r31 + 0x70;
r20 = self;
r19 = [arg2 retain];
if ([r20 hasUserAgreePrivacyGuide] != 0x0) {
if (r19 != 0x0) {
(*(r19 + 0x10))(r19);
}
}
else {
r0 = [KSLaunchManager sharedManager];
r0 = [r0 retain];
[r0 abort];
[r0 release];
[r20 changeWebViewUserAgent];
r0 = [r20 window];
r29 = r29;
r0 = [r0 retain];
[r0 release];
if (r0 == 0x0) {
[r20 generateWindow];
}
r21 = [[KSongBlankViewController alloc] init];
r0 = [KSBaseNavigationController alloc];
r0 = [r0 initWithRootViewController:r21];
r22 = r0;
[r0 setNavigationBarHidden:zero_extend_64(0x1)];
[r22 setSmartSupportAutorotate:zero_extend_64(0x1)];
r0 = [r20 window];
r0 = [r0 retain];
[r0 setRootViewController:r22];
[r0 release];
r23 = [[KSOperationalDialog alloc] init];
r25 = [objc_msgSend(@class(LanguageHelper), @selector(textForKey:)) retain];
[r23 setHeadingCaption:r25];
[r25 release];
r25 = [[r20 createRichTextDescView:r23] retain];
[r23 addContentView:r25];
[r25 release];
r25 = [objc_msgSend(@class(LanguageHelper), @selector(textForKey:)) retain];
*(r31 + 0x8) = __NSConcreteStackBlock;
*(r31 + 0x10) = *0x106e17a70;
*(r31 + 0x18) = 0x1022ce604;
*(0x28 + r31) = 0x1074c2500;
*(r31 + 0x28) = [r19 retain];
[r23 addControlButton:r25 emphasis:zero_extend_64(0x1) callback:stack[2048]];
[r25 release];
r24 = [objc_msgSend(@class(LanguageHelper), @selector(textForKey:)) retain];
[r23 addControlLinkButton:r24 callback:0x1074ea818];
[r24 release];
r24 = [[r21 view] retain];
[r23 showInView:r24];
[r24 release];
[r20 setPrivacyGuideDialog:r23];
[*(r31 + 0x28) release];
[r23 release];
[r22 release];
[r21 release];
}
[r19 release];
return;
}
```
```
bool -[KSAppDelegate didFinishLaunchingWithOptions:](void * self, void * _cmd, void * arg2) {
r31 = r31 - 0x140;
*(r31 + 0xd0) = d9;
*(0xe0 + r31) = d8;
*(r31 + 0xe0) = r28;
*(0xf0 + r31) = r27;
*(r31 + 0xf0) = r26;
*(0x100 + r31) = r25;
*(r31 + 0x100) = r24;
*(0x110 + r31) = r23;
*(r31 + 0x110) = r22;
*(0x120 + r31) = r21;
*(r31 + 0x120) = r20;
*(0x130 + r31) = r19;
*(r31 + 0x130) = r29;
*(0x140 + r31) = r30;
*(r31 + 0xc0) = *___stack_chk_guard;
*(r31 + 0x40) = [arg2 retain];
r22 = [[WnsSdkHelper sharedInstance] retain];
*(r31 + 0xb0) = @"KS";
*(r31 + 0xc0) = @"INFO";
*(r31 + 0x28) = @selector(dictionaryWithObjects:forKeys:count:);
[[NSDictionary dictionaryWithObjects:r31 + 0x130 - 0x78 forKeys:r31 + 0x130 - 0x80 count:stack[2048]] retain];
r0 = [KSVersion getGitCommitHash];
[r0 retain];
r1 = @selector(log:file:func:line:module:EFDict:msg:);
asm { stp x8, x0, sp };
*(r31 + 0x20) = r1;
objc_msgSend(r22, r1);
[r23 release];
[r19 release];
[r22 release];
r26 = [[NSUserDefaults standardUserDefaults] retain];
r0 = objc_msgSend(@class(WnsConfigManager), r21);
r0 = [r0 retain];
r0 = [r0 appConfig];
r0 = [r0 retain];
r0 = [r0 basicConfig];
r0 = [r0 retain];
[r26 setObject:[[r0 savedAppVer] retain] forKey:@"LastAppVersion"];
[r28 release];
[r27 release];
[r23 release];
[r19 release];
[r26 release];
[[[NSUserDefaults standardUserDefaults] retain] setObject:[[NSDate date] retain] forKey:@"LastLaunchDate"];
[r22 release];
[r19 release];
[r24 runLaunchTaskBeforeSafeModeCheck:*(r31 + 0x40)];
r0 = [WnsProtocolObjManager defaultManager];
r0 = [r0 retain];
[r0 setCheckCallChildThread:zero_extend_64(0x1)];
[r0 release];
*(r31 + 0x38) = r24;
objc_initWeak(r31 + 0x98, r24);
*(r31 + 0x70) = __NSConcreteStackBlock;
*(r31 + 0x78) = *0x106e17a70;
*(r31 + 0x80) = 0x101f6e274;
*(0x90 + r31) = 0x1074e6a00;
*(r31 + 0x30) = r31 + 0x90;
objc_copyWeak(r31 + 0x90, r31 + 0x98);
r0 = [WnsProtocolObjManager defaultManager];
r0 = [r0 retain];
[r0 setChildThreadBlock:r31 + 0x70];
[r0 release];
r0 = objc_msgSend(@class(QzoneSafeModeMgr), r21);
r29 = r29;
r0 = [r0 retain];
r27 = r0;
if ([r0 needEnterSafeMode] != 0x0) {
[r27 release];
r27 = [[WnsSdkHelper sharedInstance] retain];
*(r29 + 0xffffffffffffff70) = @"KS";
*(r29 + 0xffffffffffffff78) = @"INFO";
[objc_msgSend(@class(NSDictionary), *(r31 + 0x28)) retain];
r0 = [QzoneSafeModeMgr sharedInstance];
r0 = [r0 retain];
r22 = [r0 needEnterSafeMode];
r0 = [WnsConfigManager sharedInstance];
r0 = [r0 retain];
r0 = [r0 appConfig];
r0 = [r0 retain];
r0 = [r0 kSongSetting];
r0 = [r0 retain];
r0 = [r0 enableSafeModeForDebug];
*(r31 + 0x8) = r22;
*(0x18 + r31) = r0;
*r31 = 0x107701748;
objc_msgSend(r27, *(r31 + 0x20));
[r19 release];
[r25 release];
[r26 release];
[r28 release];
[r24 release];
[r27 release];
r0 = [KSLaunchManager sharedManager];
r0 = [r0 retain];
[r0 abort];
[r0 release];
[*(r31 + 0x38) setLaunchOptionsStore:*(0x48 + r31)];
r0 = [KSLaunchIdManager sharedManager];
r0 = [r0 retain];
[r0 setIsStartApp:zero_extend_64(0x1)];
[r0 release];
r0 = [KSLaunchIdManager sharedManager];
r0 = [r0 retain];
[r0 setLaunchOptions:*(r31 + 0x40)];
[r0 release];
[*(r31 + 0x38) enterSafeModeUI];
r0 = [QzoneSafeModeMgr sharedInstance];
r29 = r29;
r0 = [r0 retain];
[r0 reportEnterSecondLevelSafeMode];
[r0 release];
}
else {
r0 = [WnsConfigManager sharedInstance];
r0 = [r0 retain];
r22 = r0;
r0 = [r0 appConfig];
r0 = [r0 retain];
r19 = r0;
r0 = [r0 kSongSetting];
r29 = r29;
r0 = [r0 retain];
r28 = [r0 enableSafeModeForDebug];
[r0 release];
[r19 release];
[r22 release];
[r27 release];
if (r28 != 0x0) {
r27 = [[WnsSdkHelper sharedInstance] retain];
*(r29 + 0xffffffffffffff70) = @"KS";
*(r29 + 0xffffffffffffff78) = @"INFO";
[objc_msgSend(@class(NSDictionary), *(r31 + 0x28)) retain];
r0 = [QzoneSafeModeMgr sharedInstance];
r0 = [r0 retain];
r22 = [r0 needEnterSafeMode];
r0 = [WnsConfigManager sharedInstance];
r0 = [r0 retain];
r0 = [r0 appConfig];
r0 = [r0 retain];
r0 = [r0 kSongSetting];
r0 = [r0 retain];
r0 = [r0 enableSafeModeForDebug];
*(r31 + 0x8) = r22;
*(0x18 + r31) = r0;
*r31 = 0x107701748;
objc_msgSend(r27, *(r31 + 0x20));
[r19 release];
[r25 release];
[r26 release];
[r28 release];
[r24 release];
[r27 release];
r0 = [KSLaunchManager sharedManager];
r0 = [r0 retain];
[r0 abort];
[r0 release];
[*(r31 + 0x38) setLaunchOptionsStore:*(0x48 + r31)];
r0 = [KSLaunchIdManager sharedManager];
r0 = [r0 retain];
[r0 setIsStartApp:zero_extend_64(0x1)];
[r0 release];
r0 = [KSLaunchIdManager sharedManager];
r0 = [r0 retain];
[r0 setLaunchOptions:*(r31 + 0x40)];
[r0 release];
[*(r31 + 0x38) enterSafeModeUI];
r0 = [QzoneSafeModeMgr sharedInstance];
r29 = r29;
r0 = [r0 retain];
[r0 reportEnterSecondLevelSafeMode];
[r0 release];
}
else {
r0 = [QzoneSafeModeMgr sharedInstance];
r29 = r29;
r0 = [r0 retain];
r22 = [r0 needEnterFirstLevelSafeMode];
[r0 release];
if (r22 != 0x0) {
r0 = [QzoneSafeModeMgr sharedInstance];
r0 = [r0 retain];
[r0 doFirstLevelSafeModeResetWork];
[r0 release];
r0 = [KSLaunchManager sharedManager];
r0 = [r0 retain];
[r0 abort];
[r0 release];
r0 = [QzoneSafeModeMgr sharedInstance];
r29 = r29;
r0 = [r0 retain];
[r0 reportEnterFirstLevelSafeMode];
[r0 release];
}
[*(r31 + 0x38) enterMainUIWithLaunchOptions:*(0x48 + r31)];
*(r31 + 0x48) = __NSConcreteStackBlock;
*(r31 + 0x50) = *0x106e17a70;
*(r31 + 0x58) = 0x101f6e718;
*(0x68 + r31) = 0x1074add48;
*(r31 + 0x68) = *(r31 + 0x38);
[KSLaunchManager executeInMain:r31 + 0x48 as:@"setupAfterMainUICreated"];
}
}
[KSApi registerApp:@"ks649644247955316826" universalLink:@"https://kg5.qq.com/" delegate:stack[2048]];
objc_destroyWeak(*(r31 + 0x30));
objc_destroyWeak(r31 + 0x98);
[*(r31 + 0x40) release];
if (*___stack_chk_guard == *(r29 + 0xffffffffffffff90)) {
r0 = zero_extend_64(0x1);
}
else {
r0 = __stack_chk_fail();
}
return r0;
}
```