달력

5

« 2024/5 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
반응형

며칠 전, Flutter에서 webview_flutter(https://pub.dev/packages/webview_flutter)로 띄운 소스에서

alert가 보이지 않으니 해결해달라는 요청을 받아 처리하게 되었습니다.

찾아보니 webview_flutter는 alert&confirm을 지원하지 않는다고 합니다.

flutter와 html에서 약속을 해서 새로운 function을 만들고 호출하는 방법도 있지만,

(참조: https://cording-cossk3.tistory.com/103)

저는 html 개발하시는 분과 직접 소통하는 것도 아니고, 최대한 네이티브 소스는 건드리지 않기 위하여

그냥 기존에 있는 alert를 flutter의 toast로 작업하는 방식으로 처리하였습니다.

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:toast/toast.dart';
import 'package:webview_flutter/webview_flutter.dart';

class WebviewPage extends StatelessWidget {
  WebViewController _webViewController;

  @override
  void initState() {
    if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
  }

  @override
  Widget build(BuildContext context) {
    return WebView(
      initialUrl: '${yourUrl}',
      javascriptMode: JavascriptMode.unrestricted,
      javascriptChannels: <JavascriptChannel>{
        _alertJavascriptChannel(context),
      },
      onWebViewCreated: (WebViewController webViewController) {
        _webViewController = webViewController;
      },
      onPageFinished: (url) async {
        try {
          var javascript = '''
                             window.alert = function (e){
                               Alert.postMessage(e);
                             }
                           ''';
          await _webViewController?.evaluateJavascript(javascript);
        } catch (_) {}
      },
    );
  }

  JavascriptChannel _alertJavascriptChannel(BuildContext context) {
    return JavascriptChannel(
        name: 'Alert',
        onMessageReceived: (JavascriptMessage message) {
          Toast.show(message.message, context,
              duration: Toast.LENGTH_LONG,
              gravity: Toast.CENTER,
              backgroundColor: Colors.black38,
              backgroundRadius: 5);
        });
  }
}

이 방법으로 하면 confirm도 처리되긴 합니다.

그런데 confirm이 하나일땐 크게 문제 없겠지만 (위와 같이 confirm을 정의해서 flutter 내에서 dialog 호출해서 처리)

여러 개일때는 confirm마다 기능이 다르다면 결국 html 개발자와 같이 상의해서 개발해야 할 것입니다.

confirm도 처리해야 할 때는 android는 webview_flutter를 2.0.13 버전 이상으로 업 하면 해결됩니다.

ios는 다음 글을 참고하여 처리하여 주세요. (다음 글 : https://risha-lee.tistory.com/42)

 

 

참고 출처 : https://github.com/flutter/flutter/issues/30358

 

 

 

 

 

 

 

반응형
:
Posted by 리샤씨
반응형

최근 ionic앱에 모바일 접근성(Mobile Accessibility)을 적용할 일이 생겼다.

 

ionic에는 크게 ionic-angular, ionic-native로 나누어지는데 플러그인들이 많은데 toast도 그중 하나다.

나는 평소 ionic을 테스트할 때 초반엔 ionic serve 명령어를 이용하여 웹으로 보기 때문에

toast를 포함하여 대부분의 기능을 ionic-angular에서 제공하는 것으로 사용하고 있었다.

 

그러나 ionic-angular에서 제공하는 것은 웹에서도 사용 가능하다는 장점이 있지만

cordova를 이용하여 디바이스(Android, IOS)에 올렸을 때,

native가 기본적으로 제공해주는 기능을 못 사용하는 경우가 있다는 걸 최근에 절실히 깨닫고 있다.

(코드를 꽤 많이 고쳐야 하는 경우도 생긴다)

 

아무튼 ionic-angular toast도 모바일 접근성을 테스트할 때 알게 된 사실인데,

삼성 안드로이드 폰에서 Voice Assistant를 이용하여 들으면

ionic 앱에서 ionic-angular toast를 읽어주지 않는다는 치명적인 단점이 있었다.

 

그래서 좀 찾아보고 직접 적용하여 테스트해 본 결과,

ionic-angular, ionic-native를 모두 적용하여 platform.is('cordova')로 분기를 태워 코드를 작성하면

웹과 앱 모두 적절한 toast를 사용할 수 있다.

(ionic-native toast를 사용하면 삼성 안드로이드 폰에서 Voice Assistant를 이용하여 들었을 때,

안드로이드 native로 작성된 앱의 toast처럼 정말 잘 읽어준다..!)

 

또한, ionic-angular http를 사용하면 apk를 release 했을 때 https://로 시작하는 URI를 제대로 동작시키지 못하지만,

이것도 위와 같은 방법으로 하면 해결된다. (ionic-angular, ionic-native 분기 적용)

=> https://로 시작하는 URI를 제대로 동작시키지 못하는 이유는 서버에서 SSL을 제대로 적용 못해서였고 서버에서 제대로 적용해주면 ionic-angular http를 사용해도 apk를 release 했을 때 제대로 동작함을 확인했음 (2020. 09. 03)

 

본론으로 들어가 코드를 작성해본다면 다음과 같다.

 

1. ionic-native toast를 설치한다.

$ ionic cordova plugin add cordova-plugin-x-toast 
$ npm install @ionic-native/toast --save

 

2. app.module.ts에서 ionic-native toast를 providers에 넣는다.

import { Toast } from '@ionic-native/toast';

@NgModule({
   .....
providers: [
     .....
     Toast
  ]
})

 

3. ts 파일을 작성한다.

import { Component } from '@angular/core';
import { Platform, ToastController } from 'ionic-angular';
import { Toast } from '@ionic-native/toast';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  constructor(public platform: Platform,
              public toastCtrl: ToastController,
              public toast: Toast) {
      if (this.platform.is('cordova') == false) {
        let toast = toastCtrl.create({
            message: "test~",
            duration: 3000,
            position: "middle",
            cssClass: "toast-default"
        });
        toast.present();
      } else {
        this.toast.show("test~", "3000", "center").subscribe(
          toast => {
            console.log(toast);
          }
        );
      }
    }
  }

 

웹에서 보는 ionic-angular toast / 앱에서 보는 ionic-native toast

그러나 후에 ios에서 테스트해보았는데 ios의 voice over 기능으로는 toast message를 읽어주지 않았다.

나중에 작성하겠지만 간단히 설명하자면 ios에서는 phonegap-plugin-mobile-accessibility plugin을 설치하고

(<any>window).MobileAccessibility.speak(msg);

위 코드를 이용하여 원하는 메시지를 읽어주면 된다.

 

↓자세한 내용은 아래 링크에 작성해놓았다.

2019/09/18 - [개발/ionic2, Angular] - ionic에서 Voice Over/Voice Assistant/Talk Back이 켜져 있을 때 원하는 문장을 읽어주는 법 (모바일 접근성)

반응형
:
Posted by 리샤씨


반응형
반응형