-
[flutter] webview 사용할 때 아이폰, 아이패드에서 alert 창 활성화 되지 않는 현상flutter/flutter 기타 등등 2023. 5. 26. 20:07
flutter_webview 를 이용해서 내부에서 사용중인 사이트를 불러왔는데 alert 이 활성화 되지 않는 현상이 나타났습니다.
안드로이드는 되는데 아이폰, 아이패드에서만 안되네요.
webview 라이브러리에서 추가하는 방법은 찾지 못해서 iOS 에 추가하는 방법을 적용하였습니다.
1. flutter 프로젝트에서 iOS 코드를 Xcode 로 오픈
2. Pods > Development Pods > webview_flutter_kwwebview >...>C lasses > FWFUIDelegateHostApi.m 선택
3. FWFUIDelegateHostApi.m 파일 @implementation FWFUIDelegate 와 @end 사이에 내용을 추가해줍니다. 추가할 내용은 아래에 있습니다.
< 기존 코드 >
@implementation FWFUIDelegate - (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger instanceManager:(FWFInstanceManager *)instanceManager { self = [super initWithBinaryMessenger:binaryMessenger instanceManager:instanceManager]; if (self) { _UIDelegateAPI = [[FWFUIDelegateFlutterApiImpl alloc] initWithBinaryMessenger:binaryMessenger instanceManager:instanceManager]; } return self; } - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures { [self.UIDelegateAPI onCreateWebViewForDelegate:self webView:webView configuration:configuration navigationAction:navigationAction completion:^(FlutterError *error) { NSAssert(!error, @"%@", error); }]; return nil; } @end
< 추가할 코드 >
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert]; [alertController addAction:([UIAlertAction actionWithTitle:@"확인" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler(); }])]; UIViewController *_viewController = [UIApplication sharedApplication].keyWindow.rootViewController; [_viewController presentViewController:alertController animated:YES completion:nil]; } - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert]; [alertController addAction:([UIAlertAction actionWithTitle:@"취소" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { completionHandler(NO); }])]; [alertController addAction:([UIAlertAction actionWithTitle:@"확인" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler(YES); }])]; UIViewController *_viewController = [UIApplication sharedApplication].keyWindow.rootViewController; [_viewController presentViewController:alertController animated:YES completion:nil]; } - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert]; [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { textField.text = defaultText; }]; [alertController addAction:([UIAlertAction actionWithTitle:@"" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler(alertController.textFields[0].text?:@""); }])]; UIViewController *_viewController = [UIApplication sharedApplication].keyWindow.rootViewController; [_viewController presentViewController:alertController animated:YES completion:nil]; }
< 내용 추가 완료한 코드 >
@implementation FWFUIDelegate - (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger instanceManager:(FWFInstanceManager *)instanceManager { self = [super initWithBinaryMessenger:binaryMessenger instanceManager:instanceManager]; if (self) { _UIDelegateAPI = [[FWFUIDelegateFlutterApiImpl alloc] initWithBinaryMessenger:binaryMessenger instanceManager:instanceManager]; } return self; } - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures { [self.UIDelegateAPI onCreateWebViewForDelegate:self webView:webView configuration:configuration navigationAction:navigationAction completion:^(FlutterError *error) { NSAssert(!error, @"%@", error); }]; return nil; } - (void)webView:(WKWebView *)webView requestMediaCapturePermissionForOrigin:(WKSecurityOrigin *)origin initiatedByFrame:(WKFrameInfo *)frame type:(WKMediaCaptureType)type decisionHandler:(void (^)(WKPermissionDecision))decisionHandler API_AVAILABLE(ios(15.0)) { [self.UIDelegateAPI requestMediaCapturePermissionForDelegateWithIdentifier:self webView:webView origin:origin frame:frame type:type completion:^(WKPermissionDecision decision) { decisionHandler(decision); }]; } - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert]; [alertController addAction:([UIAlertAction actionWithTitle:@"확인" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler(); }])]; UIViewController *_viewController = [UIApplication sharedApplication].keyWindow.rootViewController; [_viewController presentViewController:alertController animated:YES completion:nil]; } - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert]; [alertController addAction:([UIAlertAction actionWithTitle:@"취소" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { completionHandler(NO); }])]; [alertController addAction:([UIAlertAction actionWithTitle:@"확인" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler(YES); }])]; UIViewController *_viewController = [UIApplication sharedApplication].keyWindow.rootViewController; [_viewController presentViewController:alertController animated:YES completion:nil]; } - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert]; [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { textField.text = defaultText; }]; [alertController addAction:([UIAlertAction actionWithTitle:@"" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler(alertController.textFields[0].text?:@""); }])]; UIViewController *_viewController = [UIApplication sharedApplication].keyWindow.rootViewController; [_viewController presentViewController:alertController animated:YES completion:nil]; } @end
FWFUIDelegateHostApi.m 파일 안에 코드를 추가해주고 다시 실행해보면 alert 실행이 가능합니다.
'flutter > flutter 기타 등등' 카테고리의 다른 글
[flutter] http 로 시작하는 URL android, iOS 에서 사용할 수 있도록 하기 (0) 2023.05.25 [flutter] figma to code (피그마에서 플러터 코드 자동 생성하기) (0) 2023.04.07 [flutter] vscode 에서 새폴더, 새파일 단축키 지정하기 (0) 2023.02.15 [flutter] 플러터에서 package name, bundle id 찾기 (0) 2023.02.13 [flutter] vscode 에서 사용 편리성을 높이기 위한 기본 셋팅 2가지 (0) 2023.02.07