A few days ago, I met a requirement, need to use JS injection client local login data, to call H5 JS method, return the client want data. This encapsulates a helper class that calls different methods for different actions

1. Create a JSHandler helper class that inherits from NSObject

/// Multiple WebViews need to be initialized by JSHander. @interface JSHandler : NSObject<WKScriptMessageHandler> @property (nonatomic, weak) WKWebView *webView; @property (nonatomic, copy) NSMutableDictionary *JSCallbacks; // initialize the webView, // @param webView passes in the webView control that needs to respond to the action // @param callback + (void)handlerJSLogin:(WKWebView *)webView onXXXClicked:(void (^)(id))callback; + (void)refreshJSUserData:(NSString *)userData; // remove web callback + (void)removeAllCallback;Copy the code

2. Initialize wkWebView and js variables

- (void)setWebView:(WKWebView *)webView {
    if (_webView == nil) {
        WKUserScript *usrScript = [[WKUserScript alloc] initWithSource:@"var xxx={};"
                                                         injectionTime:WKUserScriptInjectionTimeAtDocumentStart
                                                      forMainFrameOnly:YES];
        [webView.configuration.userContentController addUserScript:usrScript];
    }
    _webView = webView;
}

Copy the code

3. Add the callback that calls the Action and returns the callback

- (void)addAction:(NSString *)action onClicked:(void (^)(id))callback { assert(self.webView); NSString *jsToOCAction = [NSString stringWithFormat:@"JS injection code ",action,action]; WKUserScript *usrScript = [[WKUserScript alloc] initWithSource:jsToOCAction injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]; [self.webView.configuration.userContentController addUserScript:usrScript]; [self.webView.configuration.userContentController addScriptMessageHandler:self name:action]; callback? [self.JSCallbacks setObject:callback forKey:action]:nil; }Copy the code

4. Expose methods to provide local calls

Note that only single WebView calls are supported. Multiple WebViews need to be initialized again

+ (void)handlerJSXXX (WKWebView *)webView onXXXClicked (void (^)(id))callback{// Add the response method if([JSHandler shareInstance].webView&&[JSHandler shareInstance].webView ! = webView) NSLog(@"Warning: webView response before singleton overwrites "); [JSHandler shareInstance].webView = webView; [[JSHandler shareInstance] addAction:@"XXXX" onClicked:callback]; }Copy the code

5.VC invoke instance

[JSHandler handlerJSXXX: self wkWebView onLoginClicked: ^ (id _Nonnull args) {/ / jump actions or other processing args can be h5 returned parameters NSLog(@"%@",args); }];Copy the code