AISleepCoachController.m 7.2 KB
//
//  AISleepCoachController.m
//  DreamSleep
//
//  Created by peter on 2022/4/1.
//

#import "AISleepCoachController.h"
#import <WebKit/WebKit.h>
#import <JavaScriptCore/JavaScriptCore.h>

@interface AISleepCoachController () <WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate>
@property (strong, nonatomic) WKWebView *aiWebView;
@property (strong, nonatomic) NSMutableURLRequest *request;
@property (strong, nonatomic) UIProgressView *progressView;
@property (nonatomic, strong) ExceptionDefaultView *exceptionView;
@end

@implementation AISleepCoachController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 创建WKWebView对象,添加到界面(storyboard没有控件)
    [self.view addSubview:self.aiWebView];
    [self.view addSubview:self.progressView];
    
    // 监听AI睡眠教练页面需要刷新数据通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(needUpdateAiCoach) name:NeedUpdateAICoach object:nil];
}

- (void)dealloc {
    [self.aiWebView removeObserver:self forKeyPath:@"estimatedProgress"];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:NeedUpdateAICoach object:nil];
}

#pragma mark - 关闭侧滑
- (BOOL)enableInteractivePopGestureRecognizer {
    return NO;
}

#pragma mark - 隐藏导航栏
- (BOOL)isShowNavigationBar {
    return YES;
}

#pragma mark - 品牌模式
- (NaviStyle)navigationBarStyle {
    return NaviStyleDefault;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    // 夜间模式
    if ([self.dk_manager.themeVersion isEqualToString:DKThemeVersionNight]) {
        [self.aiWebView addMask];
    } else {
        [self.aiWebView removeMask];
    }
}

#pragma mark - 登录成功后刷新
- (void)needUpdateAiCoach {
    NSHTTPCookie *sidCookie = nil;
    for (NSHTTPCookie *cookie in [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies) {
        // connect.sid是后台下发的cookie字段
        if ([cookie.name isEqualToString:@"connect.sid"]) {
            sidCookie = cookie;
            break;;
        }
    }
    // 将APP获取的cookie同步给wkwebview容器里面的cookie(wkwebview存在cookie不同步的巨坑,该同步API在iOS 11及以后支持)
    [self.aiWebView.configuration.websiteDataStore.httpCookieStore setCookie:sidCookie completionHandler:^{
        [self.aiWebView loadRequest:self.request];
    }];
}

- (void)startOpen {
    if (![LoginUtils getUserLoginData]) {
        [LoginUtils jumpToLoginControllerWithTarget:self];
    }
}

#pragma mark - WKWebView的监听方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"estimatedProgress"]) {
        self.progressView.progress = self.aiWebView.estimatedProgress;
        if (self.progressView.progress == 1) { self.progressView.hidden = YES; }
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

#pragma mark - WKNavigationDelegate
// 开始加载
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}

// 加载成功
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    self.exceptionView.hidden = YES;
    self.aiWebView.hidden = NO;
}

// 加载失败
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    self.exceptionView.hidden = NO;
    DSLog(@"加载失败:%@", error);
}

#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if ([message.name isEqualToString:@"AppModel"]) {
        NSDictionary *bodyDic = message.body;
        DSLog(@"bodyDic:%@", bodyDic);
        
        int type = [bodyDic[@"type"] intValue];
        if (type == 1) { // 未登录点击开启
            [self startOpen];
            
            // 注入js代码用于强制刷新小梦睡眠
            NSString *jsCallBack = @"window.parent.location.reload()";
            [self.aiWebView evaluateJavaScript:jsCallBack completionHandler:^(id _Nullable result, NSError * _Nullable error) {
                [self.aiWebView loadRequest:self.request];
                DSLog(@"注入成功...");
                if (error) {
                    DSLog(@"err is %@", error.domain);
                }
            }];
        }
    }
}

#pragma mark - lazy
- (WKWebView *)aiWebView {
    if (!_aiWebView) {
        // 进行配置控制器
        WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
        // 实例化对象
        configuration.userContentController = [WKUserContentController new];
        // 调用JS方法
        [configuration.userContentController addScriptMessageHandler:self name:@"AppModel"];
        
        // 进行偏好设置
        WKPreferences *preferences = [WKPreferences new];
        preferences.javaScriptCanOpenWindowsAutomatically = YES;
        preferences.javaScriptEnabled = YES;
        configuration.preferences = preferences;
        
        // 初始化WKWebView
        _aiWebView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight - kTabBarHeight) configuration:configuration];
        _aiWebView.backgroundColor = DSWhite;
        _aiWebView.UIDelegate = self;
        _aiWebView.hidden = YES;
        _aiWebView.scrollView.bounces = NO;
        [_aiWebView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
        _aiWebView.navigationDelegate = self;
        _aiWebView.scrollView.showsVerticalScrollIndicator = NO;
        _aiWebView.scrollView.showsHorizontalScrollIndicator = NO;
        // 解决页面顶部出现白色问题
        _aiWebView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        self.request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:AICoachURL] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0];
        [_aiWebView loadRequest:self.request];
    }
    return _aiWebView;
}

- (UIProgressView *)progressView {
    if (!_progressView) {
        _progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 0)];
        _progressView.tintColor = HighlightColor;
        // 通过放大Y轴来改变高度
        _progressView.transform = CGAffineTransformMakeScale(1.0f, 3.0f);;
    }
    return _progressView;
}

- (ExceptionDefaultView *)exceptionView {
    if (!_exceptionView) {
        WS(weakSelf);
        _exceptionView = [[ExceptionDefaultView alloc] initWithType:ExceptionTypeNet block:^{
            weakSelf.progressView.hidden = NO;
            weakSelf.progressView.progress = 0;
            weakSelf.exceptionView.hidden = YES;
            [weakSelf.aiWebView loadRequest:self.request];
        } superView:self.view];
    }
    return _exceptionView;
}

@end