[React-Native] 앱에서 위젯 추가하기 (native modules)

HongDuHyeon·2024년 6월 12일
1
post-thumbnail
반년만에 블로그 ㅎㅎ

반년만에 조금은 재미있는 스프린트를 진행해서 기억하기 위해 블로그를 써본다.

먼저 앞서 제목에서 알 수 있다. RN앱에서 바로 위젯을 추가할 수 있는 기능을 만들어야했다.
유저의 리텐션을 높히기 위해선 위젯의 존재를 알려야하고 더 쉽게 앱에 진입할 수 있는 경로라고 생각했다.
처음엔 아무것도 모르는 미지의 영역이고 불확실한 상황이었지만 팀에서 계속 연습했던 불확실한 상황에서 살아남기(?)를 연습할 수 있는 좋은 기회였다.

⛔️주의⛔️

아쉽지만 위젯을 만드는 법이 아니라 이미 있는 위젯을 더 효과적으로
나타낼 수 있는 블로그이기 때문에 관련이 없을 수도 있는 점 양해부탁드립니다.

💡 PendingIntent란?

다들 코드를 Android Studio에서 코드를 조금이라도 쳐봤다면 Intent와 PendingIntent를 한번쯤은 봤을 것이다.

PendingIntent는 현재 내가 갖고 있는 intent를 바로 실행을 시키는게 아니라 특정 시점, 특정 액션에 수행할 수 있는 특징을 갖고 있다.

💡 code

@ReactMethod
    public fun createWidgetInApp() {
        val context: Context = reactApplicationContext
        val appWidgetManager = AppWidgetManager.getInstance(context)
        val intent = Intent()

        val provider = ComponentName(context, Widget::class.java)

        // SDK > 26 (android 8.0)
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appWidgetManager.isRequestPinAppWidgetSupported){
            val intent = Intent(context, AndroidAppWidget::class.java)
            val successCallback = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)

            appWidgetManager.requestPinAppWidget(provider, null, successCallback)
        }
    }
  • 우선 react-native에서 nativeModules로 사용할 것이기 때문에 상단에 @ReactMethod를 적어준다.

  • ConponentName은 내가 가진 위젯을 import 해주면 되고
    이번에 사용할 requestPinAppWidget 이 친구는 안타깝게도 android 8.0 이상만 지원해주기 때문에 if문에서 SDK 버전별로 걸러줘야한다.

💡PendingIntent Parameter

PendingIntent에 파라미터로

  1. context (reactApplicationContext)
  2. requestCode
    • PendingIntent를 가져올 때 구분하기 위한 고유 코드
  3. 실행할 Intent
  4. flag

이렇게 4가지 넣어주면 된다. 1번과 2번은 어느정도 알 수 있겠지만
내 경우엔 3번 Intent엔 데이터 트래킹을 위한 amplitude 코드를 넣어줬어야했다.

class AndroidAppWidget: BroadcastReceiver() {
    private val amplitude = Amplitude.getInstance()
    
    override fun onReceive(context: Context?, intent: Intent?) {
        amplitude.logEvent(AmplitudeEvents.이벤트_네임)
    }
}

successCallback이 성공적으로 실행이 되었을 때 트래킹을 위해 직접 만들어서 넣어줬다.

4번 flag는 아래와 같이 몇가지가 있다.

  • FLAG_CANCEL_CURRENT: 사용할 Intent에 대해 한 번에 하나만 활성화해야 하는 경우 사용하며, 이전에 생성한 PendingIntent를 취소한 후 새로 생성한다.
  • FLAG_IMMUTABLE: 생성된 PendingIntent가 불변(변경될 수 없음)이라는 것을 나타낸다.
  • FLAG_MUTABLE: 생성된 PendingIntent가 변경 가능해야한다는 것을 나타낸다.
  • FLAG_NO_CREATE: PendingIntent가 아직 존재하지 않는 경우 생성하는 대신 단순 null을 반환함을 나타낸다.
  • FLAG_ONE_SHOT: 해당 PendingIntent를 한 번만 사용할 수 있음을 나타낸다.
  • FLAG_UPDATE_CURRENT: 기존에 생성된 PendingIntent가 있다면 새로운 값으로 업데이트한다.

굳이 내가 사용한 FLAG_UPDATE_CURRENT가 아니더라도 상황에 맞게 사용하면 될 것 같다 !
라고 했지만

targeting s+ (version 31 and above) requires that one of flag_immutable or flag_mutable be specified when creating a pendingintent.

이라는 에러가 나왔다 ㅎㅎ.....
PendingIntent를 생성할 때 s+(버전 31 이상)를 타겟팅하려면 flag_immutable 또는 flag_mutable 중 하나를 지정해야 한다고 한다..

허허..

그리고 추가적으로 에러의 내용을 보면 google docs에서 일부 변경이 가능한 PendingIntent에 의존하는 경우에만 FLAG_MUTABLE을 사용하고, 다른 경우에는 FLAG_IMMUTABLE 사용을 강력히 권고한다고 한다.

💡 마무리

이번에 앱에서 위젯 추가하면서 자연스럽게 유저들에게 위젯을 온보딩해주는 기능을 만들어봤다.
이걸 만듦으로써 좋은 데이터와 좋은 결과가 나와서 유저들이 앱을 더 잘 사용했으면 좋겠다 :)

profile
마음이 시키는 프론트엔드.. RN과 IOS를 곁들인..

0개의 댓글