시간이 곧 돈인 기업에서 특히 중소규모의 기업에서 목업 디스플레이를 일일이 flutter 코드로 바꾸는 것은 쉽지 않다. 물론 숙련된 개발자와 함께 오랫동안 쌓아온 보일러 코드가 있다면 금방 개발하겠지만
현재 우리 사내 app을 도입하는 것은 처음이고 나에게 준 시간을 그리 많지 않았다.
그래서 생각한 것이 바로 webview이다.
그래서 이번에는 web view와 왼쪽에선 front-end frame-work 서버를 돌리고 오른쪽에서는 flutter 앱을 돌려서 바로바로 확인할 수 있는 환경을 구성해보자.
포트 번호
를 밑에 실행할 url값 뒤에 붙여줘야한다.우선 노트북이 유선 Lan에 연결되어있다면 wi-fi로 바꿔주자. 왜냐하면 pc, 폰이 같은 망을 공유해야하기 때문이다.
ipconfig
를 치면 위 사진처럼 IPv4에 대한 주소값을 얻어올 수 있는데 이 뒤에 포트번호까지 넣어주면 된다.class HomeScreen extends StatefulWidget {
const HomeScreen({required this.token, Key? key}) : super(key: key);
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
WebViewController? webViewController;
Set<JavascriptChannel>? channel;
final homeUrl = 'http://주소값/:포트번호';
void initState() {
super.initState();
}
void dispose() {
super.dispose();
}
Widget build(BuildContext context) {
final appDir = syspaths.getApplicationDocumentsDirectory();
return WebView(
initialUrl: homeUrl,
onWebViewCreated: (WebViewController webViewController) {
this.webViewController = webViewController;
},
javascriptMode: JavascriptMode.unrestricted,
javascriptChannels: <JavascriptChannel>{
JavascriptChannel(
name: 'flutterGetImage',
onMessageReceived: (JavascriptMessage message) {
_getImage();
},
),
},
);
}
}
이때 android => app => src => main => AndroidManifest.xml 에 application tag안에
<application
android:label="test"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true" <= 이부분
>
<activity
...
를 넣어주면 해결된다.
class _MyHomePageState extends State<MyHomePage> {
WebViewController controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..loadRequest(Uri.parse('http를 허용하고 싶은 url'));
@override
Widget build(BuildContext context) {
return Scaffold(
body: WebViewWidget(
controller: controller,
));
}
}
controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
// Update loading bar.
},
onPageStarted: (String url) {},
onPageFinished: (String url) {},
onWebResourceError: (WebResourceError error) {},
onNavigationRequest: (NavigationRequest request) {
if (request.url.startsWith('https://www.youtube.com/')) {
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
),
)
..loadRequest(Uri.parse('https://flutter.dev'));
WebViewController
: 웹뷰의 컨트롤러이고 이 객체를 통해 웹뷰의 동작을 제어한다.setJavaScriptMode(JavaScriptMode.unrestricted)
: JavaScript 실행 모드를 설정한다. unrestricted는 JavaScript가 제한 없이 실행될 수 있음을 의미한다.setBackgroundColor(const Color(0x00000000))
: 웹뷰의 배경색을 설정한다. 참고로 저 값은 투명을 뜻한다.setNavigationDelegate(NavigationDelegate(...))
: 네비게이션 동작에 대한 위임자(delegate)를 설정한다.onProgress
: 페이지 로딩 진행률이 변경될 때 호출되는 콜백 함수.onPageStarted
: 페이지 로딩이 시작될 때 호출되는 콜백 함수.onPageFinished
: 페이지 로딩이 완료될 때 호출되는 콜백 함수.onWebResourceError
: 웹 리소스 로딩 중 에러가 발생했을 때 호출되는 콜백 함수.onNavigationRequest
: 네비게이션 요청이 발생했을 때 호출되는 콜백 함수이다.https://www.youtube.com/
로 시작하는 경우 네비게이션을 방지하도록 되어있다. 즉, YouTube 링크 클릭 시 해당 링크로 이동하지 않도록 하는 기능을 제공한다.loadRequest(Uri.parse('https://flutter.dev'))
: 주어진 URL의 웹 페이지를 로드한다.* 우선 앞서 .xml 파일에 넣은 android:usesCleartextTraffic="true"
이 설정은 앱이 평문 네트워크 트래픽 즉, HTTP
을 사용할 수 있도록 한다.
* 하지만 이 설정은 전체 앱에 적용되므로, 가능한 한 구체적인 도메인에 대해서만 예외를 설정하는 것이 좋다. 그러기 위해서는 networkSecurityConfig
리소스를 사용하여 더 세밀한 제어를 할 수 있다.
1. res/xml/
path에 network_security_config.xml
파일을 만들어준다. 만약에 res에 xml 폴더가 없다면 생성하면 된다.
2. 코드생성
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">http를 허용할 url</domain>
</domain-config>
</network-security-config>
3. AndroidMinifest.xml에 설정 잡기
<application
...
android:networkSecurityConfig="@xml/network_security_config"
...>
...
</application>