698 words in content
6 minutes for read
사용자 상호작용을 위한 Native Home Widget 개발

인식한 상황#

푸시 알림, 사용자 채팅이 만들어진 MVP에 GA를 적용한 이후 사용자들의 참여도가 떨어지는 것을 확인했다. 이 부분에 있어 팀원과의 회의와 베타 테스터 설문 조사를 통해 다음과 같은 문제점이 있는 것을 확인했다.

  1. 앱을 열지 않고도 사용자들이 참여할 수 있는 방법이 필요하다.
  2. 방해금지 기능, 알림 설정 등으로 인해 푸시 알림이 제대로 전달되지 않는 경우가 있다.

즉, 앱 내에서만 사용자와 상호작용이 이루어져, 재방문율과 참여도를 높이는 데 한계가 있다. (아…)

해결 과정#

게이미피케이션의 요소 중 “많이 보일수록 참여한다”라는 점에서 알림은 부족하다는 의견이 나왔고, 새롭게 할 수 있는 것이 무엇이 있을까 생각 중 홈의 캘린더 위젯이 눈에 보였다. 계속 보인다는 점에서 매력이 있었고, 앱을 보지 않더라도 캐릭터의 상태를 나타낼 수 있기에 Home Widget을 만들기로 결정했다.

이를 위해 Flutter의 Home Widget Library를 활용하기로 했다. 하지만, 기본적으로 Library를 사용하더라도 Home Widget은 Native Code로 작성해야 하기에 Flutter에서는 Method Channel을 통해 Native Code를 호출하였다.

abstract class WidgetUtil {
  static const String appGroupIdentifier = 'group.earthAndI.userInfoWidget';
  static const String iOSWidgetName = 'userInfoWidget';
  static const String androidWidgetName = 'UserInfoWidget';

  static Future<void> onInit() async {
    await HomeWidget.setAppGroupId(appGroupIdentifier);
  }

  static void setInformation({
    required double positiveDeltaCO2,
    required double negativeDeltaCO2,
    required bool isHealthCondition,
    required bool isMentalCondition,
    required bool isCashCondition,
  }) {
    // Saving Character Asset
    HomeWidget.saveWidgetData<String>(
      WidgetUtilExtension.characterAsset,
      _toCharacterAssetPath(
        positiveDeltaCO2: positiveDeltaCO2,
        negativeDeltaCO2: negativeDeltaCO2,
        isHealthCondition: isHealthCondition,
        isMentalCondition: isMentalCondition,
        isCashCondition: isCashCondition,
      ),
    );

    // Saving Positive Delta CO2
    // 안드로이드 아이폰 경우의 수 나누기, 안드로이드는 int 값으로, 아이폰은 double 값으로 저장
    if (foundation.defaultTargetPlatform == foundation.TargetPlatform.android) {
      HomeWidget.saveWidgetData<int>(WidgetUtilExtension.positiveDeltaCO2,
          (positiveDeltaCO2.abs() * 10000).round());
    } else {
      HomeWidget.saveWidgetData<double>(
          WidgetUtilExtension.positiveDeltaCO2, positiveDeltaCO2.abs());
    }

    // Saving Negative Delta CO2
    if (foundation.defaultTargetPlatform == foundation.TargetPlatform.android) {
      HomeWidget.saveWidgetData<int>(WidgetUtilExtension.negativeDeltaCO2,
          (negativeDeltaCO2 * 10000).round());
    } else {
      HomeWidget.saveWidgetData<double>(
          WidgetUtilExtension.negativeDeltaCO2, negativeDeltaCO2);
    }

    // Update Widget
    HomeWidget.updateWidget(
      iOSName: iOSWidgetName,
      androidName: androidWidgetName,
    );
  }

  static String _toCharacterAssetPath({
    required double positiveDeltaCO2,
    required double negativeDeltaCO2,
    required bool isHealthCondition,
    required bool isMentalCondition,
    required bool isCashCondition,
  }) {
    String eco = positiveDeltaCO2.abs() >= negativeDeltaCO2 ? '1' : '2';
    String health = isHealthCondition ? '1' : '2';
    String mental = isMentalCondition ? '1' : '2';
    String cash = isCashCondition ? '1' : '2';

    return '${eco}_${health}_${mental}_$cash';
  }
}

결과#

아래는 만들어진 Widget의 모습이다.

AndroidiOS
WidgetWidget

이후 개발된 홈 위젯을 테스트 사용자 그룹에 배포한 결과, 위젯이 들어간 버전을 Update한 이후 사용자들의 12% 높아진 것을 확인할 수 있었다. 하지만, 실제로 Widget에서 앱에서 할 수 있는 사용 사례를 할 수 없다는 점에서 한계점이 존재했다…