https://pub.dev/packages/webview_flutter
를 사용하여 iOS를 개발하는 와중에, 웹뷰에서 alert, confirm 이 아예 작동하지 않는
현상을 발견하였습니다. 이에따른 해결방안을 알아보도록 하겠습니다.
우선, 해당 Flutter 소스의 iOS 코드를 XCode 로 실행시켜주도록 합니다.
이후 우리는, 이미 빌드가 되어있고 .symlink 가 걸려있는
webview_flutter_wkwebview 의 인터페이스중 FWFUIDelegate 를 찾아야 합니다.
쉬운 방법은, 아무 파일에서 해당 인터페이스를 코딩하여 선언후 Jump to Definition 기능을 이용해주세요.
@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:^(NSError *error) {
NSAssert(!error, @"%@", error);
}];
return nil;
}
@end
해당 인터페이스는 FWFUIDelegateHostApi.m 에서 구현되고 있으며, 인터페이스 구현 내용은 위와같습니다.
중간에 아래 코드를 넣어주도록 하면 정상적으로 alert, confirm, prompt 기능을 이용하실 수 있습니다.
- (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];
}
이상입니다. 감사합니다.
[Flutter] iOS Apple Login 정책 가이드라인 준수 (0) | 2022.12.13 |
---|---|
[Flutter]Network 에 있는 Image 호출시 이미지 cache 문제해결 (0) | 2022.12.05 |
[Flutter] Sizer 사용후기 (0) | 2022.12.05 |
[Flutter]Adobe XD package 사용하기 (1) | 2022.11.07 |
[Flutter] CupertinoAlertdialog 사용하는 방법 (0) | 2022.11.02 |