PeterPlanet
PeterPlanet
PeterPlanet
전체 방문자
오늘
어제
  • 분류 전체보기 (30)
    • 블록체인 (0)
    • Flutter programming (6)
    • Side Project (1)
      • 베스트셀러 (1)
    • Kotlin programming (16)
      • 코틀린(kotlin) (12)
      • Compose (4)
    • 아이폰(xcode) (6)
    • 구글 관련 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • Objective-C
  • 앱개발
  • Flutter
  • target sdk update
  • 컨테이너에 리플효과
  • 코틀린
  • webview alert
  • flutter alert
  • system confirm
  • obj-c
  • Update Android Target SDK 32 Version
  • Kotlin
  • update target sdk
  • webview confirm
  • flutter confirm
  • Android
  • 네아로
  • 안드로이드
  • Ripple
  • compose

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
PeterPlanet

PeterPlanet

Flutter programming

[Flutter] webview_flutter에서 alert/confirm 띄우기(webview_flutter version 3.0)

2022. 8. 1. 08:31
반응형

 

프로젝트 진행중 웹에서 confirm() 함수를 호출하는 데 webview_flutter 3.0.4기준으로 안드로이드는 정상적으로 시스템 confirm창이 노출이 되는데 아이폰에서는 노출이 되지 않는 현상이 발생했습니다.

그래서 구글링 한 결과 webview_flutter 소스에서 기본적으로 지원을 하지 않고 직접 소스를 수정해서 적용하면 가능하다는 블로그를 보고 적용해봤습니다.

 

※ 경로(Mac 기준)

- 2.0.3 기준 경로 :

/Users/${사용자}/Dev/SDKs/flutter/.pub-cache/hosted/pub.dartlang.org/webview_flutter-2.0.13/ios/Classes/FlutterWebView.m

 

- 3.0.4 기준 경로 : 

/Users/${사용자}/Dev/SDKs/flutter/.pub-cache/hosted/pub.dartlang.org/webview_flutter_wkwebview-2.9.2/ios/Classes/FWFUIDelegateHostApi.m

 

 

※ 적용할 소스 

@implementation FWFUIDelegate
//...

- (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:UIAlertActionStyleCancel handler:^(UIAlertAction *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:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        completionHandler(YES);
    }]];
    [alertController addAction:[UIAlertAction actionWithTitle:@"아니오" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
        completionHandler(NO);
    }]];
    
    UIViewController *_viewController = [UIApplication sharedApplication].keyWindow.rootViewController;

    [_viewController presentViewController:alertController animated:YES completion:nil];
}

@end

 

 

 

※ 헷갈리실 분들을 위해 전문 첨부 합니다

// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "FWFUIDelegateHostApi.h"
#import "FWFDataConverters.h"

@interface FWFUIDelegateFlutterApiImpl ()
// BinaryMessenger must be weak to prevent a circular reference with the host API it
// references.
@property(nonatomic, weak) id<FlutterBinaryMessenger> binaryMessenger;
// InstanceManager must be weak to prevent a circular reference with the object it stores.
@property(nonatomic, weak) FWFInstanceManager *instanceManager;
@end

@implementation FWFUIDelegateFlutterApiImpl
- (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger
                        instanceManager:(FWFInstanceManager *)instanceManager {
  self = [self initWithBinaryMessenger:binaryMessenger];
  if (self) {
    _binaryMessenger = binaryMessenger;
    _instanceManager = instanceManager;
    _webViewConfigurationFlutterApi =
        [[FWFWebViewConfigurationFlutterApiImpl alloc] initWithBinaryMessenger:binaryMessenger
                                                               instanceManager:instanceManager];
  }
  return self;
}

- (long)identifierForDelegate:(FWFUIDelegate *)instance {
  return [self.instanceManager identifierWithStrongReferenceForInstance:instance];
}

- (void)onCreateWebViewForDelegate:(FWFUIDelegate *)instance
                           webView:(WKWebView *)webView
                     configuration:(WKWebViewConfiguration *)configuration
                  navigationAction:(WKNavigationAction *)navigationAction
                        completion:(void (^)(NSError *_Nullable))completion {
  if (![self.instanceManager containsInstance:configuration]) {
    [self.webViewConfigurationFlutterApi createWithConfiguration:configuration
                                                      completion:^(NSError *error) {
                                                        NSAssert(!error, @"%@", error);
                                                      }];
  }

  NSNumber *configurationIdentifier =
      @([self.instanceManager identifierWithStrongReferenceForInstance:configuration]);
  FWFWKNavigationActionData *navigationActionData =
      FWFWKNavigationActionDataFromNavigationAction(navigationAction);

  [self onCreateWebViewForDelegateWithIdentifier:@([self identifierForDelegate:instance])
                               webViewIdentifier:
                                   @([self.instanceManager
                                       identifierWithStrongReferenceForInstance:webView])
                         configurationIdentifier:configurationIdentifier
                                navigationAction:navigationActionData
                                      completion:completion];
}
@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:^(NSError *error) {
                                        NSAssert(!error, @"%@", error);
                                      }];
  return nil;
}

- (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:UIAlertActionStyleCancel handler:^(UIAlertAction *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:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        completionHandler(YES);
    }]];
    [alertController addAction:[UIAlertAction actionWithTitle:@"아니오" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
        completionHandler(NO);
    }]];
    
    UIViewController *_viewController = [UIApplication sharedApplication].keyWindow.rootViewController;

    [_viewController presentViewController:alertController animated:YES completion:nil];
}
@end

@interface FWFUIDelegateHostApiImpl ()
// BinaryMessenger must be weak to prevent a circular reference with the host API it
// references.
@property(nonatomic, weak) id<FlutterBinaryMessenger> binaryMessenger;
// InstanceManager must be weak to prevent a circular reference with the object it stores.
@property(nonatomic, weak) FWFInstanceManager *instanceManager;
@end

@implementation FWFUIDelegateHostApiImpl
- (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger
                        instanceManager:(FWFInstanceManager *)instanceManager {
  self = [self init];
  if (self) {
    _binaryMessenger = binaryMessenger;
    _instanceManager = instanceManager;
  }
  return self;
}

- (FWFUIDelegate *)delegateForIdentifier:(NSNumber *)identifier {
  return (FWFUIDelegate *)[self.instanceManager instanceForIdentifier:identifier.longValue];
}

- (void)createWithIdentifier:(nonnull NSNumber *)identifier
                       error:(FlutterError *_Nullable *_Nonnull)error {
  FWFUIDelegate *uIDelegate = [[FWFUIDelegate alloc] initWithBinaryMessenger:self.binaryMessenger
                                                             instanceManager:self.instanceManager];
  [self.instanceManager addDartCreatedInstance:uIDelegate withIdentifier:identifier.longValue];
}

@end

 

 

라이브러리 : https://pub.dev/packages/webview_flutter

참고 출처 : https://risha-lee.tistory.com/42?category=1001052

저작자표시 비영리 변경금지 (새창열림)

'Flutter programming' 카테고리의 다른 글

[Flutter] Container에 배경색과 Ripple 효과 넣기  (0) 2023.09.07
[Flutter] 플러터 설치 방법(개발환경 구축) for mac  (0) 2023.03.24
에러 : Exception in thread "main" java.util.zip.ZipException: zip END header not found  (0) 2022.01.03
에러 : A directory corresponding to fileSystemPath "/Users/사용자이름/.pub-cache/hosted/pub.dartlang.org/devtools-2.9.2/build" could not be found  (0) 2022.01.03
[Flutter 설치]Flutter 설치 중 발생하는 오류  (0) 2021.12.31
    'Flutter programming' 카테고리의 다른 글
    • [Flutter] Container에 배경색과 Ripple 효과 넣기
    • [Flutter] 플러터 설치 방법(개발환경 구축) for mac
    • 에러 : Exception in thread "main" java.util.zip.ZipException: zip END header not found
    • 에러 : A directory corresponding to fileSystemPath "/Users/사용자이름/.pub-cache/hosted/pub.dartlang.org/devtools-2.9.2/build" could not be found
    PeterPlanet
    PeterPlanet
    기록하기

    티스토리툴바