SPSBHtmlViewController.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. //
  2. // SPSBHtmlViewController.m
  3. // 我的社保
  4. //
  5. // Created by shanp on 2021/4/26.
  6. //
  7. #import "SPSBHtmlViewController.h"
  8. #import <WebKit/WebKit.h>
  9. #import "SPSBUIGeneralHeader.h"
  10. #import "SPSBBaseNetworkModel.h"
  11. #import "UIViewController+SPSBNavigationBar.h"
  12. #import "UIViewController+SPSBInitialization.h"
  13. #import "SPSBConfirmAlertViewController.h"
  14. #import "SPSBShareViewController.h"
  15. @interface SPSBShareWebViewModel : SPSBBaseNetworkModel
  16. @property (nonatomic, copy) NSString *spsb_title;
  17. @property (nonatomic, copy) NSString *spsb_content;
  18. @property (nonatomic, copy) NSString *spsb_url;
  19. @property (nonatomic, copy) NSString *spsb_imageUrl;
  20. @end
  21. @implementation SPSBShareWebViewModel
  22. @end
  23. @interface SPSBHtmlViewController ()<WKUIDelegate, WKNavigationDelegate> {
  24. UIButton *_shareButton;
  25. SPSBShareWebViewModel *_shareWebViewModel;
  26. UIActivityIndicatorView *_activity;
  27. NSString *_alert;
  28. UIButton *_backButton;
  29. UIButton *_directBackButton;
  30. }
  31. @end
  32. @implementation SPSBHtmlViewController
  33. - (void)viewDidLoad {
  34. [super viewDidLoad];
  35. [self setupUI];
  36. }
  37. #pragma mark - JS Action
  38. - (void)webexit:(NSString *)sender {
  39. if (self.navigationController.viewControllers.count == 1) {
  40. [self directCancelAction];
  41. } else {
  42. [self directBackAction];
  43. }
  44. if (_spsb_callBack) {
  45. NSDictionary *dic = jxh_jsonToDictionary([sender stringByRemovingPercentEncoding]);
  46. _spsb_callBack(dic);
  47. }
  48. }
  49. - (void)setData:(NSString *)data {
  50. NSDictionary *dic = jxh_jsonToDictionary(data);
  51. if (dic[@"exitHint"]) {
  52. _alert = dic[@"exitHint"];
  53. }
  54. }
  55. - (void)setHtmlTitle:(NSString *)data {
  56. NSString *data1 = [data stringByRemovingPercentEncoding];
  57. self.spsb_titleLabel.text = data1;
  58. }
  59. #pragma mark - Action
  60. - (void)shareAction {
  61. if (!_shareWebViewModel) return;
  62. id image;
  63. if (![_shareWebViewModel.spsb_imageUrl isEqualToString:@""]) {
  64. image = _shareWebViewModel.spsb_imageUrl;
  65. } else {
  66. image = [UIImage imageNamed:SPSBLogo];
  67. }
  68. SPSBShareModel *model = [[SPSBShareModel alloc] initWithTypeArray:@[SPSBShareCircleOfFriends, SPSBShareWechat, SPSBShareMiniProgram, SPSBShareQQ, SPSBShareQzone, SPSBShareSinaWeibo] content:_shareWebViewModel.spsb_content image:image title:_shareWebViewModel.spsb_title url:_shareWebViewModel.spsb_url mediaType:SSDKContentTypeWebPage eventId:nil finish:nil];
  69. SPSBShareViewController *vc = SPSBShareViewController.new;
  70. vc.spsb_data = model;
  71. [self presentViewController:vc animated:false completion:nil];
  72. }
  73. - (void)backAction {
  74. if ([_spsb_webView canGoBack]) {
  75. _directBackButton.hidden = false;
  76. [_spsb_webView goBack];
  77. return;
  78. }
  79. [self directBackAction];
  80. }
  81. - (void)directBackAction {
  82. if (_alert) {
  83. SPSBConfirmAlertViewController *vc = [SPSBConfirmAlertViewController alertWithTitle:_alert content:nil];
  84. [vc setCancelButtonTitle:nil titleColor:nil action:^{
  85. }];
  86. @weakify(self)
  87. [vc setConfirmButtonTitle:nil titleColor:nil action:^{
  88. @strongify(self)
  89. [self.navigationController popViewControllerAnimated:true];
  90. }];
  91. [self presentViewController:vc animated:false completion:nil];
  92. return;
  93. }
  94. [self.navigationController popViewControllerAnimated:true];
  95. }
  96. - (void)cancelAction {
  97. if ([_spsb_webView canGoBack]) {
  98. _directBackButton.hidden = false;
  99. [_spsb_webView goBack];
  100. return;
  101. }
  102. [self directCancelAction];
  103. }
  104. - (void)directCancelAction {
  105. if (_alert) {
  106. SPSBConfirmAlertViewController *vc = [SPSBConfirmAlertViewController alertWithTitle:_alert content:nil];
  107. [vc setCancelButtonTitle:nil titleColor:nil action:^{
  108. }];
  109. @weakify(self)
  110. [vc setConfirmButtonTitle:nil titleColor:nil action:^{
  111. @strongify(self)
  112. [self dismissViewControllerAnimated:true completion:nil];
  113. }];
  114. [self presentViewController:vc animated:false completion:nil];
  115. return;
  116. }
  117. [self dismissViewControllerAnimated:true completion:nil];
  118. }
  119. - (void)setTitle {
  120. @weakify(self)
  121. [_spsb_webView evaluateJavaScript:@"document.title" completionHandler:^(id _Nullable title, NSError * _Nullable error) {
  122. @strongify(self)
  123. if (title) {
  124. self.spsb_titleLabel.text = title;
  125. }
  126. }];
  127. }
  128. #pragma mark - WKUIDelegate
  129. - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
  130. completionHandler();
  131. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
  132. [alertController addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  133. }]];
  134. [self presentViewController:alertController animated:true completion:nil];
  135. }
  136. - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {
  137. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
  138. [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  139. completionHandler(false);
  140. }]];
  141. [alertController addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  142. completionHandler(true);
  143. }]];
  144. [self presentViewController:alertController animated:true completion:nil];
  145. }
  146. - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler {
  147. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
  148. [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
  149. textField.text = defaultText;
  150. }];
  151. [alertController addAction:[UIAlertAction actionWithTitle:@"完成" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  152. completionHandler(alertController.textFields[0].text?:@"");
  153. }]];
  154. [self presentViewController:alertController animated:true completion:nil];
  155. }
  156. #pragma mark - WKWebViewDelegate
  157. - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
  158. _activity.hidden = false;
  159. [_activity startAnimating];
  160. }
  161. - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
  162. _activity.hidden = true;
  163. [_activity stopAnimating];
  164. @weakify(self)
  165. [webView evaluateJavaScript:@"spIosShare()" completionHandler:^(id _Nullable data, NSError * _Nullable error) {
  166. @strongify(self)
  167. if ([data isKindOfClass:[NSString class]]) {
  168. NSString *shareString = data;
  169. NSData *jsonData = [shareString dataUsingEncoding:NSUTF8StringEncoding];
  170. NSError *err;
  171. NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
  172. options:NSJSONReadingMutableContainers
  173. error:&err];
  174. if (!err) {
  175. self->_shareButton.hidden = false;
  176. self->_shareWebViewModel = SPSBShareWebViewModel.new;
  177. [self->_shareWebViewModel handleDataWithDictionary:dic];
  178. }
  179. }
  180. }];
  181. [self setTitle];
  182. }
  183. - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
  184. debugLog(@"asss");
  185. bool isAllow = [self handleRequest:navigationAction.request];
  186. if (isAllow) {
  187. //处理电话
  188. NSURL *URL = navigationAction.request.URL;
  189. NSString *scheme = [URL scheme];
  190. if ([scheme isEqualToString:@"tel"]) {
  191. NSString *resourceSpecifier = [URL resourceSpecifier];
  192. NSString *callPhone = [NSString stringWithFormat:@"telprompt://%@", resourceSpecifier];
  193. [[UIApplication sharedApplication] openURL:[NSURL URLWithString:callPhone]];
  194. decisionHandler(WKNavigationActionPolicyCancel);
  195. return;
  196. }
  197. //如果是跳转一个新页面
  198. if (navigationAction.targetFrame == nil) {
  199. [webView loadRequest:navigationAction.request];
  200. }
  201. decisionHandler(WKNavigationActionPolicyAllow);
  202. [self setTitle];
  203. } else {
  204. decisionHandler(WKNavigationActionPolicyCancel);
  205. }
  206. }
  207. - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
  208. decisionHandler(WKNavigationResponsePolicyAllow);
  209. }
  210. #pragma mark - Request
  211. - (bool)handleRequest:(NSURLRequest *)request {
  212. NSMutableString *requestString = [[[request URL] absoluteString] mutableCopy];
  213. debugLog(@"--------%@", requestString);
  214. if ([requestString hasPrefix:@"alipay"]) {
  215. [jxh_application() openURL:[NSURL URLWithString:requestString]];
  216. return false;
  217. }
  218. if ([requestString hasPrefix:@"weixin://wap/pay?"]) {
  219. [jxh_application() openURL:[NSURL URLWithString:requestString]];
  220. return false;
  221. }
  222. if ([requestString containsString:@"//itunes.apple.com/"] || [requestString containsString:@"//apps.apple.com"]) {
  223. [jxh_application() openURL:[NSURL URLWithString:requestString]];
  224. return false;
  225. }
  226. if (_spsb_isJsMethod) {
  227. NSArray *array = [requestString componentsSeparatedByString:@":"];
  228. debugLog(@"++++++%@", array);
  229. if (array.count > 1 && [array[0] isEqualToString:@"iosvsjs"]) {
  230. if (array.count > 2) {
  231. [requestString deleteCharactersInRange:NSMakeRange(0, ((NSString *)array[0]).length + ((NSString *)array[1]).length + 2)];
  232. SEL action = NSSelectorFromString([NSString stringWithFormat:@"%@:", array[1]]);
  233. #pragma clang diagnostic push
  234. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  235. [self performSelector:action withObject:requestString];
  236. #pragma clang diagnostic pop
  237. }
  238. else {
  239. SEL action = NSSelectorFromString(array[1]);
  240. #pragma clang diagnostic push
  241. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  242. [self performSelector:action];
  243. #pragma clang diagnostic pop
  244. }
  245. return false;
  246. }
  247. }
  248. return true;
  249. }
  250. #pragma mark - Network Action
  251. #pragma mark - UI
  252. - (void)setupUI {
  253. self.spsb_isHiddenNavigationBar = true;
  254. [self createNavigationBar];
  255. [self addWebView];
  256. [self addActivity];
  257. [self addDirectBackButton];
  258. [self addShareButton];
  259. }
  260. - (void)addWebView {
  261. NSURLCache * cache = [NSURLCache sharedURLCache];
  262. [cache removeAllCachedResponses];
  263. [cache setDiskCapacity:0];
  264. [cache setMemoryCapacity:0];
  265. _spsb_webView = [[WKWebView alloc] init];
  266. _spsb_webView.UIDelegate = self;
  267. _spsb_webView.navigationDelegate = self;
  268. _spsb_webView.scrollView.bounces = false;
  269. _spsb_webView.allowsLinkPreview = false;
  270. _spsb_webView.scrollView.showsVerticalScrollIndicator = false;
  271. if (_spsb_jsString) {
  272. WKUserScript *script = [[WKUserScript alloc] initWithSource:_spsb_jsString injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
  273. [_spsb_webView.configuration.userContentController addUserScript:script];
  274. }
  275. if (@available(iOS 11.0, *)) {
  276. _spsb_webView.scrollView.contentInsetAdjustmentBehavior = UIApplicationBackgroundFetchIntervalNever;
  277. }
  278. [self.view addSubview:_spsb_webView];
  279. [_spsb_webView makeConstraints:^(JXHConstraintMaker *make) {
  280. make.leading.and.trailing.and.bottom.equalTo(0);
  281. make.top.equalTo(self.spsb_navigationBar.bottom);
  282. }];
  283. if (![_spsb_url hasPrefix:@"http"]) {
  284. _spsb_url = [NSString stringWithFormat:@"http://%@", _spsb_url];
  285. }
  286. NSDate *date = [NSDate new];
  287. NSTimeInterval time = [date timeIntervalSince1970] * 1000;
  288. NSURL *url;
  289. if ([_spsb_url containsString:@"?"]) {
  290. url = [NSURL URLWithString:[NSString stringWithFormat:@"%@&time=%lf", _spsb_url, time]];
  291. } else {
  292. url = [NSURL URLWithString:[NSString stringWithFormat:@"%@?time=%lf", _spsb_url, time]];
  293. }
  294. [_spsb_webView loadRequest:[NSURLRequest requestWithURL:url]];
  295. }
  296. - (void)addActivity {
  297. _activity = [[UIActivityIndicatorView alloc] init];
  298. [_activity setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
  299. [self.view addSubview:_activity];
  300. [_activity makeConstraints:^(JXHConstraintMaker *make) {
  301. make.center.equalTo(0);
  302. }];
  303. }
  304. - (void)addDirectBackButton {
  305. [self.spsb_titleLabel makeConstraints:^(JXHConstraintMaker *make) {
  306. make.leading.update(120);
  307. make.trailing.update(-120);
  308. }];
  309. [self.spsb_barBackButton removeFromSuperview];
  310. _backButton = [UIButton convenienceWithTarget:nil action:nil];
  311. [_backButton setImage:jxh_getImage(arrow_back_blue) state:JXHButtonControlStateNormal];
  312. [_backButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
  313. [self.spsb_navigationBar addSubview:_backButton];
  314. [_backButton makeConstraints:^(JXHConstraintMaker *make) {
  315. make.leading.equalTo(SPSBFixMargin);
  316. make.bottom.equalTo(0);
  317. make.size.equalTo((CGSize){50, jxh_navigationViewHeight()});
  318. }];
  319. _directBackButton = [UIButton convenienceWithTarget:nil action:nil];
  320. [_directBackButton setImage:jxh_getImage(nav_del) state:JXHButtonControlStateNormal];
  321. [_directBackButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
  322. [self.spsb_navigationBar addSubview:_directBackButton];
  323. [_directBackButton makeConstraints:^(JXHConstraintMaker *make) {
  324. make.leading.equalTo(self->_backButton.trailing);
  325. make.centerY.equalTo(self->_backButton);
  326. make.size.equalTo((CGSize){50, jxh_navigationViewHeight()});
  327. }];
  328. _directBackButton.hidden = true;
  329. if (self.navigationController.viewControllers.count == 1) {
  330. [_directBackButton addTarget:self action:@selector(directCancelAction) forControlEvents:UIControlEventTouchUpInside];
  331. [_backButton addTarget:self action:@selector(cancelAction) forControlEvents:UIControlEventTouchUpInside];
  332. } else {
  333. [_directBackButton addTarget:self action:@selector(directBackAction) forControlEvents:UIControlEventTouchUpInside];
  334. [_backButton addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];
  335. }
  336. }
  337. - (void)addShareButton {
  338. _shareButton = [UIButton convenienceWithTarget:self action:@selector(shareAction)];
  339. [_shareButton setImage:jxh_getImage(share_btn) state:JXHButtonControlStateNormal];
  340. [_shareButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight];
  341. [self.spsb_navigationBar addSubview:_shareButton];
  342. [_shareButton makeConstraints:^(JXHConstraintMaker *make) {
  343. make.trailing.equalTo(-SPSBFixMargin);
  344. make.centerY.equalTo(self->_backButton);
  345. make.size.equalTo((CGSize){64, jxh_navigationViewHeight()});
  346. }];
  347. _shareButton.hidden = true;
  348. }
  349. @end