본문 바로가기
카테고리 없음

플러터에서 웹뷰를 쉽게 구현하는 패키지: flutter_inappwebview

by Maccrey 2024. 6. 7.
반응형
 

안녕하세요!

오늘은 플러터 앱에서 웹뷰를 간편하게 구현할 수 있도록 도와주는 강력한 패키지 flutter_inappwebview에 대해 자세히 알아보겠습니다.

마치 웹 브라우저를 앱 내에 삽입하는 것처럼, flutter_inappwebview를 사용하면 다양한 웹 콘텐츠를 앱에서 자연스럽게 표시하고 상호 작용할 수 있습니다.

 

1. flutter_inappwebview란 무엇일까요?

 

flutter_inappwebview는 플러터 앱에서 웹뷰를 구현하는 데 사용되는 오픈 소스 패키지입니다.

기본적인 웹 브라우징 기능뿐만 아니라, 쿠키 관리, 자바스크립트 실행, 심지어 PDF 렌더링까지 다양한 기능을 제공합니다.

 

2. flutter_inappwebview의 주요 기능

 

  • 기본 웹 브라우징: URL을 통해 웹 페이지를 로드하고, 뒤로 가기, 앞으로 가기, 새로 고침 등 기본적인 웹 브라우징 기능을 제공합니다.

 

  • 쿠키 관리: 웹 페이지에서 설정된 쿠키를 관리하고, 쿠키 저장 여부를 제어할 수 있습니다.

 

  • 자바스크립트 실행: 웹 페이지에서 자바스크립트 코드를 실행하고, 앱 코드와 상호 작용할 수 있습니다.

 

  • HTML 컨텐츠 로드: HTML 코드를 직접 로드하여 웹 페이지를 구현할 수 있습니다.

 

  • PDF 렌더링: PDF 파일을 로드하고 앱 내에서 직접 표시할 수 있습니다.

 

  • 사용자 정의 헤더 및 푸터: 웹 페이지에 사용자 정의 헤더 및 푸터를 추가할 수 있습니다.

 

  • 프로그레스바: 웹 페이지 로딩 과정을 보여주는 프로그레스바를 제공합니다.

 

  • 자바스크립트 인터페이스: 자바스크립트 코드와 앱 코드 간에 상호 작용을 위한 다양한 인터페이스를 제공합니다.

3. flutter_inappwebview 사용법

 

3.1. 패키지 설치:

 
flutter pub add flutter_inappwebview
 

3.2. WebView 위젯 사용:

 
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

class WebViewPage extends StatefulWidget {
  @override
  _WebViewPageState createState() => _WebViewPageState();
}

class _WebViewPageState extends State<WebViewPage> {
  final InAppWebView _webView = InAppWebView(
    initialUrl: 'https://flutter.dev/',
    initialOptions: InAppWebViewOptions(
      debuggingEnabled: true,
    ),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter InAppWebView'),
      ),
      body: _webView,
    );
  }
}
 

3.3. 주요 기능 사용

 

앞서 flutter_inappwebview의 기본적인 사용법을 알아보았습니다. 이제 주요 기능들을 심층적으로 살펴보고, 실제 개발에 활용할 수 있는 구체적인 코드 예시와 활용 팁을 소개합니다.

 

3.3.1. URL 로드

 
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

class WebViewPage extends StatefulWidget {
  @override
  _WebViewPageState createState() => _WebViewPageState();
}

class _WebViewPageState extends State<WebViewPage> {
  final InAppWebView _webView = InAppWebView(
    initialUrl: 'https://flutter.dev/',
    initialOptions: InAppWebViewOptions(
      debuggingEnabled: true,
    ),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter InAppWebView'),
      ),
      body: _webView,
    );
  }
}
 
  • initialUrl 속성: 로드할 웹 페이지의 URL을 지정합니다.
  • onLoadUrl 이벤트: 웹 페이지 로딩이 완료되었을 때 호출되는 이벤트입니다.
  • onLoadError 이벤트: 웹 페이지 로딩에 실패했을 때 호출되는 이벤트입니다.

예시: 특정 URL로 직접 이동하는 경우

 
_webView.loadUrl('https://www.google.com/search?q=flutter');
 

3.3.2. 뒤로 가기, 앞으로 가기, 새로 고침

 
_webView.goBack(); // 이전 페이지로 이동
_webView.goForward(); // 다음 페이지로 이동
_webView.reload(); // 현재 페이지를 다시 로드
 
  • goBack() 메서드: 이전 페이지로 이동합니다. 이전 페이지가 없으면 아무 작업을 수행하지 않습니다.
  • goForward() 메서드: 다음 페이지로 이동합니다. 다음 페이지가 없으면 아무 작업을 수행하지 않습니다.
  • reload() 메서드: 현재 페이지를 다시 로드합니다. 캐시된 콘텐츠를 지우고 서버에서 최신 콘텐츠를 다시 가져옵니다.

3.3.3. 쿠키 관리

 
_webView.cookiesEnabled = true; // 쿠키 사용 허용
_webView.getCookies().then((cookies) {
  print('Cookies: ${cookies.map((cookie) => cookie.toString()).toList()}');
});
 
  • cookiesEnabled 속성: 쿠키 사용 여부를 제어합니다. true로 설정하면 웹 페이지에서 쿠키를 설정하고 사용할 수 있습니다.
  • getCookies() 메서드: 현재 웹 페이지에서 설정된 쿠키 정보를 가져옵니다.

3.3.4. 자바스크립트 실행

 
_webView.executeJavascript("alert('Hello from Flutter!');");
 
  • executeJavascript() 메서드: 웹 페이지에서 자바스크립트 코드를 실행합니다. 코드 실행 결과는 onJsResultReceived 이벤트를 통해 받아볼 수 있습니다.

3.3.5. HTML 컨텐츠 로드

 
String htmlContent = '''
<!DOCTYPE html>
<html>
<head>
  <title>My Web Page</title>
</head>
<body>
  <h1>Hello from Flutter!</h1>
</body>
</html>
''';

_webView.loadHtml(htmlContent);
 
  • loadHtml() 메서드: 직접 작성한 HTML 코드를 웹 페이지로 로드합니다.

3.3.6. PDF 렌더링:

 
_webView.loadFile('https://flutter.dev/docs/assets/fonts/Roboto-Regular.ttf');
 
  • loadFile() 메서드: 로컬 파일이나 URL로부터 PDF 파일을 로드하고 렌더링합니다.

3.3.7. 사용자 정의 헤더 및 푸터

 

앞서 사용자 정의 헤더 및 푸터를 추가하는 방법을 간략하게 살펴보았습니다.

이 섹션에서는 실제 개발에 활용할 수 있는 구체적인 코드 예시와 활용 팁을 소개합니다.

 

3.3.7.1. 사용자 정의 헤더

  • 요청 헤더 추가: 웹 페이지 로드 시 요청 헤더에 사용자 정의 정보를 추가할 수 있습니다. 예를 들어, 인증 토큰이나 사용자 에이전트 정보를 헤더에 포함하여 웹 서버와의 상호 작용을 제어할 수 있습니다.
Map<String, String> customHeaders = {
  'Accept': 'application/json',
  'Authorization': 'Bearer YOUR_TOKEN',
  'User-Agent': 'MyCustomUserAgent/1.0',
};

_webView.customHeaders = customHeaders;
 
  • 헤더 변경: 웹 페이지 로딩 중에 헤더를 변경할 수도 있습니다. 예를 들어, 사용자 로그인 후 인증 토큰을 헤더에 추가하거나, 특정 요청에만 적용되는 헤더를 설정할 수 있습니다.
_webView.setHeader('X-My-Custom-Header', 'MyCustomValue');
 

3.3.7.2. 사용자 정의 푸터

  • 고정 푸터: 웹 페이지 아래에 고정되는 사용자 정의 푸터를 추가하여 네비게이션 버튼, 광고, 저작권 정보 등을 표시할 수 있습니다.
_webView.customFooter = Container(
  height: 50,
  color: Colors.grey[200],
  child: Row(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      Text('Copyright © 2024 My Company'),
      TextButton(
        onPressed: () {
          // 푸터 버튼 클릭 시 처리
        },
        child: Text('Contact Us'),
      ),
    ],
  ),
);
 
  • 동적 푸터: 웹 페이지 로딩 상황이나 사용자 상호 작용에 따라 동적으로 변화하는 푸터를 구현할 수 있습니다. 예를 들어, 로딩 중 프로그레스바를 표시하거나, 로그인 여부에 따라 로그인/로그아웃 버튼을 표시할 수 있습니다.
_webView.addOnProgressChangedListener((controller, progress) {
  if (progress == 100) {
    _webView.customFooter = Container(
      height: 50,
      color: Colors.green,
      child: Center(
        child: Text('Page Loaded'),
      ),
    );
  }
});
 

3.3.7.3. 활용 팁

  • 헤더 및 푸터 디자인: 웹 페이지 디자인과 일관되도록 헤더 및 푸터 디자인을 신중하게 선택하고 구현합니다.
  • 반응형 디자인: 다양한 화면 크기와 해상도에 맞게 헤더 및 푸터가 적절하게 표시되도록 합니다.
  • 접근성 고려: 시각 장애인을 포함한 모든 사용자가 헤더 및 푸터 정보를 쉽게 접근하고 이해할 수 있도록 합니다.
  • 성능 최적화: 불필요한 헤더 및 푸터 정보는 추가하지 않고, 성능 저하를 방지합니다.

3.3.8. 추가 주요 기능

  • 프로그레스바: 웹 페이지 로딩 진행 상황을 표시하는 프로그레스바를 사용합니다.
  • 자바스크립트 인터페이스: 자바스크립트 코드와 앱 코드 간에 상호 작용을 위한 다양한 인터페이스를 제공합니다.
  • URL 로딩 제어: 특정 URL 로딩을 차단하거나 처리합니다.
  • 인증 처리: 웹 페이지에서 인증을 요청할 때 처리합니다.
  • 내부 브라우저 사용: 내부 브라우저 컨텍스트를 사용합니다.

4. flutter_inappwebview 활용 예시

 

4.1. 뉴스 앱

  • 뉴스 기사 목록을 표시하는 ListView 위젯을 사용하여 뉴스 앱을 구현합니다.
  • 각 뉴스 기사 아이템을 클릭하면 InAppWebView 위젯을 사용하여 해당 기사를 로드합니다.
  • 뉴스 기사 목록은 API를 통해 불러오고, 각 기사의 URL은 뉴스 기사 객체에 저장합니다.
class NewsItem {
  final String title;
  final String url;

  NewsItem({required this.title, required this.url});
}

class NewsPage extends StatefulWidget {
  @override
  _NewsPageState createState() => _NewsPageState();
}

class _NewsPageState extends State<NewsPage> {
  final List<NewsItem> _newsItems = [];

  @override
  void initState() {
    super.initState();
    // API를 통해 뉴스 기사 목록을 불러오고 _newsItems에 저장합니다.
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('News'),
      ),
      body: ListView.builder(
        itemCount: _newsItems.length,
        itemBuilder: (context, index) {
          final newsItem = _newsItems[index];
          return ListTile(
            title: Text(newsItem.title),
            onTap: () {
              final webView = InAppWebView(
                initialUrl: newsItem.url,
                initialOptions: InAppWebViewOptions(
                  debuggingEnabled: true,
                ),
              );

              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => WebViewPage(webView: webView),
                ),
              );
            },
          );
        },
      ),
    );
  }
}
 

4.2. 쇼핑 앱

  • 웹 스토어를 앱 내에 표시하고 제품 검색 및 구매를 가능하게 하는 쇼핑 앱을 만들 수 있습니다.
  • InAppWebView 위젯을 사용하여 웹 스토어 페이지를 로드하고, 자바스크립트 인터페이스를 사용하여 제품 검색, 장바구니 관리, 구매 처리 등의 기능을 구현합니다.
class ShoppingPage extends StatefulWidget {
  @override
  _ShoppingPageState createState() => _ShoppingPageState();
}

class _ShoppingPageState extends State<ShoppingPage> {
  final InAppWebView _webView = InAppWebView(
    initialUrl: 'https://www.example-store.com/',
    initialOptions: InAppWebViewOptions(
      debuggingEnabled: true,
    ),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Shopping'),
      ),
      body: _webView,
    );
  }

  @override
  void initState() {
    super.initState();

    _webView.addOnJsResultReceivedListener((controller, result) {
      if (result.message == 'addProductToCart') {
        // 제품 ID를 받아 장바구니에 추가합니다.
        final productId = result.data;
        // 장바구니에 제품을 추가하는 로직을 구현합니다.
      }
    });
  }
}
 

4.3. 소셜 미디어 앱

class SocialMediaPage extends StatefulWidget {
  @override
  _SocialMediaPageState createState() => _SocialMediaPageState();
}

class _SocialMediaPageState extends State<SocialMediaPage> {
  final InAppWebView _webView = InAppWebView(
    initialUrl: 'https://www.example-social-media.com/',
    initialOptions: InAppWebViewOptions(
      debuggingEnabled: true,
    ),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Social Media'),
      ),
      body: _webView,
    );
  }

  @override
  void initState() {
    super.initState();

    _webView.addOnJsResultReceivedListener((controller, result) {
      if (result.message == 'postCreated') {
        // 게시물 내용을 받아 서버에 저장합니다.
        final postContent = result.data;
        // 게시물을 저장하는 로직을 구현합니다.
      }
    });
  }
}
 

4.4. 게임 앱

  • 웹 기반 게임을 앱 내에 표시하고 플레이할 수 있도록 하는 게임 앱을 만들 수 있습니다.
  • InAppWebView 위젯을 사용하여 게임 페이지를 로드하고, 자바스크립트 인터페이스를 사용하여 게임 조작, 점수 관리, 광고 표시 등의 기능을 구현합니다.
class GamePage extends StatefulWidget {
  @override
  _GamePageState createState() => _GamePageState();
}

class _GamePageState extends State<GamePage> {
  final InAppWebView _webView = InAppWebView(
    initialUrl: 'https://www.example-game.com/',
    initialOptions: InAppWebViewOptions(
      debuggingEnabled: true,
    ),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Game'),
      ),
      body: _webView,
    );
  }

  @override
  void initState() {
    super.initState();

    _webView.addOnJsResultReceivedListener((controller, result) {
      if (result.message == 'gameOver') {
        // 게임 결과를 받아 처리합니다.
        final score = result.data;
        // 게임 결과를 처리하는 로직을 구현합니다.
      }
    });
  }
}
 

4.5. 교육 앱

  • 웹 기반 교육 콘텐츠를 앱 내에 표시하고 학습자와 교사 간의 상호 작용을 지원하는 교육 앱을 만들 수 있습니다.
  • InAppWebView 위젯을 사용하여 교육 콘텐츠 페이지를 로드하고, 자바스크립트 인터페이스를 사용하여 학습 진행 관리, 퀴즈 풀이, 토론 참여 등의 기능을 구현합니다.
class EducationPage extends StatefulWidget {
  @override
  _EducationPageState createState() => _EducationPageState();
}

class _EducationPageState extends State<EducationPage> {
  final InAppWebView _webView = InAppWebView(
    initialUrl: 'https://www.example-education.com/',
    initialOptions: InAppWebViewOptions(
      debuggingEnabled: true,
    ),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Education'),
      ),
      body: _webView,
    );
  }

  @override
  void initState() {
    super.initState();

    _webView.addOnJsResultReceivedListener((controller, result) {
      if (result.message == 'quizAnswered') {
        // 퀴즈 답변을 받아 채점합니다.
        final answer = result.data;
        // 퀴즈 답변을 채점하는 로직을 구현합니다.
      }
    });
  }
}
 

5. 결론

 

flutter_inappwebview는 플러터 앱에서 웹뷰를 간편하게 구현하고 다양한 기능을 활용할 수 있도록 하는 강력한 패키지입니다.

웹 콘텐츠를 앱에 통합하고 사용자 경험을 향상시키는 데 매우 유용한 도구입니다.

이 블로그 게시글을 통해 flutter_inappwebview의 기본적인 사용법, 주요 기능 활용, 활용 예시, 추가 자료 등을 이해하셨기를 바랍니다. 더 궁금한 점이나 알아보고 싶은 기능이 있다면 언제든지 댓글 남겨주세요!

 

6. 추가 팁

  • flutter_inappwebview를 사용하기 전에 공식 문서를 꼼꼼하게 읽어보는 것이 좋습니다.
  • 예시 코드를 참고하여 실제 개발에 활용해보세요.
  • 문제 발생 시 Github Issues 또는 Stack Overflow에서 도움을 요청하세요.
  • 커뮤니티에 참여하여 다른 개발자들과 교류하고 정보를 공유하세요.

flutter_inappwebview를 활용하여 멋진 앱을 개발하시기 바랍니다!

 

수발가족을 위한 일기장 “나비일기장”

 

https://play.google.com/store/apps/details?id=com.maccrey.navi_diary_release

 

비공개테스트를 위한 20명의 테스터모집 앱 "테스터 쉐어"

 

https://play.google.com/store/apps/details?id=com.maccrey.tester_share_release

반응형