LKS_ExportManager.m 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #ifdef SHOULD_COMPILE_LOOKIN_SERVER
  2. //
  3. // LKS_ExportManager.m
  4. // LookinServer
  5. //
  6. // Created by Li Kai on 2019/5/13.
  7. // https://lookin.work
  8. //
  9. #import "LKS_ExportManager.h"
  10. #import "UIViewController+LookinServer.h"
  11. #import "LookinHierarchyInfo.h"
  12. #import "LookinHierarchyFile.h"
  13. #import "LookinAppInfo.h"
  14. #import "LookinServerDefines.h"
  15. #import "LKS_MultiplatformAdapter.h"
  16. @interface LKS_ExportManagerMaskView : UIView
  17. @property(nonatomic, strong) UIView *tipsView;
  18. @property(nonatomic, strong) UILabel *firstLabel;
  19. @property(nonatomic, strong) UILabel *secondLabel;
  20. @property(nonatomic, strong) UILabel *thirdLabel;
  21. @end
  22. @implementation LKS_ExportManagerMaskView
  23. - (instancetype)initWithFrame:(CGRect)frame {
  24. if (self = [super initWithFrame:frame]) {
  25. self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.35];
  26. self.tipsView = [UIView new];
  27. self.tipsView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.88];
  28. self.tipsView.layer.cornerRadius = 6;
  29. self.tipsView.layer.masksToBounds = YES;
  30. [self addSubview:self.tipsView];
  31. self.firstLabel = [UILabel new];
  32. self.firstLabel.text = LKS_Localized(@"Creating File…");
  33. self.firstLabel.textColor = [UIColor whiteColor];
  34. self.firstLabel.font = [UIFont boldSystemFontOfSize:14];
  35. self.firstLabel.textAlignment = NSTextAlignmentCenter;
  36. self.firstLabel.numberOfLines = 0;
  37. [self.tipsView addSubview:self.firstLabel];
  38. self.secondLabel = [UILabel new];
  39. self.secondLabel.text = LKS_Localized(@"May take 8 or more seconds according to the UI complexity.");
  40. self.secondLabel.textColor = [UIColor colorWithRed:173/255.0 green:180/255.0 blue:190/255.0 alpha:1];
  41. self.secondLabel.font = [UIFont systemFontOfSize:12];
  42. self.secondLabel.textAlignment = NSTextAlignmentLeft;
  43. self.secondLabel.numberOfLines = 0;
  44. [self.tipsView addSubview:self.secondLabel];
  45. self.thirdLabel = [UILabel new];
  46. self.thirdLabel.text = LKS_Localized(@"The file can be opend by Lookin.app in macOS.");
  47. self.thirdLabel.textColor = [UIColor colorWithRed:173/255.0 green:180/255.0 blue:190/255.0 alpha:1];
  48. self.thirdLabel.font = [UIFont systemFontOfSize:12];
  49. self.thirdLabel.textAlignment = NSTextAlignmentCenter;
  50. self.thirdLabel.numberOfLines = 0;
  51. [self.tipsView addSubview:self.thirdLabel];
  52. }
  53. return self;
  54. }
  55. - (void)layoutSubviews {
  56. [super layoutSubviews];
  57. UIEdgeInsets insets = UIEdgeInsetsMake(8, 10, 8, 10);
  58. CGFloat maxLabelWidth = self.bounds.size.width * .8 - insets.left - insets.right;
  59. CGSize firstSize = [self.firstLabel sizeThatFits:CGSizeMake(maxLabelWidth, CGFLOAT_MAX)];
  60. CGSize secondSize = [self.secondLabel sizeThatFits:CGSizeMake(maxLabelWidth, CGFLOAT_MAX)];
  61. CGSize thirdSize = [self.thirdLabel sizeThatFits:CGSizeMake(maxLabelWidth, CGFLOAT_MAX)];
  62. CGFloat tipsWidth = MAX(MAX(firstSize.width, secondSize.width), thirdSize.width) + insets.left + insets.right;
  63. self.firstLabel.frame = CGRectMake(tipsWidth / 2.0 - firstSize.width / 2.0, insets.top, firstSize.width, firstSize.height);
  64. self.secondLabel.frame = CGRectMake(tipsWidth / 2.0 - secondSize.width / 2.0, CGRectGetMaxY(self.firstLabel.frame) + 10, secondSize.width, secondSize.height);
  65. self.thirdLabel.frame = CGRectMake(tipsWidth / 2.0 - thirdSize.width / 2.0, CGRectGetMaxY(self.secondLabel.frame) + 5, thirdSize.width, thirdSize.height);
  66. self.tipsView.frame = ({
  67. CGFloat height = CGRectGetMaxY(self.thirdLabel.frame) + insets.bottom;
  68. CGRectMake(self.bounds.size.width / 2.0 - tipsWidth / 2.0, self.bounds.size.height / 2.0 - height / 2.0, tipsWidth, height);
  69. });
  70. }
  71. @end
  72. @interface LKS_ExportManager ()
  73. #if TARGET_OS_TV
  74. #else
  75. @property(nonatomic, strong) UIDocumentInteractionController *documentController;
  76. #endif
  77. @property(nonatomic, strong) LKS_ExportManagerMaskView *maskView;
  78. @end
  79. @implementation LKS_ExportManager
  80. + (instancetype)sharedInstance {
  81. static dispatch_once_t onceToken;
  82. static LKS_ExportManager *instance = nil;
  83. dispatch_once(&onceToken,^{
  84. instance = [[super allocWithZone:NULL] init];
  85. });
  86. return instance;
  87. }
  88. + (id)allocWithZone:(struct _NSZone *)zone{
  89. return [self sharedInstance];
  90. }
  91. #if TARGET_OS_TV
  92. - (void)exportAndShare {
  93. NSAssert(NO, @"not supported");
  94. }
  95. #else
  96. - (void)exportAndShare {
  97. UIViewController *visibleVc = [UIViewController lks_visibleViewController];
  98. if (!visibleVc) {
  99. NSLog(@"LookinServer - Failed to export because we didn't find any visible view controller.");
  100. return;
  101. }
  102. [[NSNotificationCenter defaultCenter] postNotificationName:@"Lookin_WillExport" object:nil];
  103. if (!self.maskView) {
  104. self.maskView = [LKS_ExportManagerMaskView new];
  105. }
  106. [visibleVc.view.window addSubview:self.maskView];
  107. self.maskView.frame = visibleVc.view.window.bounds;
  108. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  109. LookinHierarchyInfo *info = [LookinHierarchyInfo exportedInfo];
  110. LookinHierarchyFile *file = [LookinHierarchyFile new];
  111. file.serverVersion = info.serverVersion;
  112. file.hierarchyInfo = info;
  113. NSData *data = [NSKeyedArchiver archivedDataWithRootObject:file];
  114. if (!data) {
  115. return;
  116. }
  117. NSString *fileName = ({
  118. NSString *timeString = ({
  119. NSDate *date = [NSDate date];
  120. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  121. [formatter setDateFormat:@"MMddHHmm"];
  122. [formatter stringFromDate:date];
  123. });
  124. NSString *iOSVersion = ({
  125. NSString *str = info.appInfo.osDescription;
  126. NSUInteger dotIdx = [str rangeOfString:@"."].location;
  127. if (dotIdx != NSNotFound) {
  128. str = [str substringToIndex:dotIdx];
  129. }
  130. str;
  131. });
  132. [NSString stringWithFormat:@"%@_ios%@_%@.lookin", info.appInfo.appName, iOSVersion, timeString];
  133. });
  134. NSString *path = [NSString stringWithFormat:@"%@%@", NSTemporaryDirectory(), fileName];
  135. [data writeToFile:path atomically:YES];
  136. [self.maskView removeFromSuperview];
  137. if (!self.documentController) {
  138. self.documentController = [UIDocumentInteractionController new];
  139. }
  140. self.documentController.URL = [NSURL fileURLWithPath:path];
  141. if ([LKS_MultiplatformAdapter isiPad]) {
  142. [self.documentController presentOpenInMenuFromRect:CGRectMake(0, 0, 1, 1) inView:visibleVc.view animated:YES];
  143. } else {
  144. [self.documentController presentOpenInMenuFromRect:visibleVc.view.bounds inView:visibleVc.view animated:YES];
  145. }
  146. [[NSNotificationCenter defaultCenter] postNotificationName:@"Lookin_DidFinishExport" object:nil];
  147. // [self.documentController presentOptionsMenuFromRect:visibleVc.view.bounds inView:visibleVc.view animated:YES];
  148. // CFTimeInterval endTime = CACurrentMediaTime();
  149. // CFTimeInterval consumingTime = endTime - startTime;
  150. // NSLog(@"LookinServer - 导出 UI 结构耗时:%@", @(consumingTime));
  151. });
  152. }
  153. #endif
  154. @end
  155. #endif /* SHOULD_COMPILE_LOOKIN_SERVER */