πŸ” Flutter Background Service κΆŒν•œ μš”μ²­ 및 ꢌ리 μ„€μ • μ™„λ²½ κ°€μ΄λ“œ | μ•ˆλ“œλ‘œμ΄λ“œμ™€ iOS ν•„μˆ˜ 체크리슀트






Flutter Background Service κΆŒν•œ μš”μ²­ 및 ꢌ리 μ„€μ • μ™„λ²½ κ°€μ΄λ“œ


λ°°κ²½ μ„œλΉ„μŠ€λž€ 무엇인가

Flutter κ°œλ°œμ„ ν•˜λ©΄μ„œ 앱이 λ°±κ·ΈλΌμš΄λ“œμ—μ„œλ„ νŠΉμ • μž‘μ—…μ„ 계속 μˆ˜ν–‰ν•΄μ•Ό ν•  κ²½μš°κ°€ μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, GPS μœ„μΉ˜ 정보λ₯Ό μˆ˜μ§‘ν•˜κ±°λ‚˜, ν‘Έμ‹œ μ•Œλ¦Όμ„ λ°›κ±°λ‚˜, 데이터λ₯Ό λ™κΈ°ν™”ν•˜λŠ” λ“±μ˜ μž‘μ—…λ“€μ΄ κ·Έλ ‡μŠ΅λ‹ˆλ‹€.

이런 μƒν™©μ—μ„œ μ‚¬μš©ν•˜λŠ” 것이 flutter_background_service νŒ¨ν‚€μ§€μž…λ‹ˆλ‹€. 이 νŒ¨ν‚€μ§€λ₯Ό 톡해 앱이 ν¬κ·ΈλΌμš΄λ“œμ— μžˆμ§€ μ•Šμ•„λ„ λ°±κ·ΈλΌμš΄λ“œμ—μ„œ μ•ˆμ •μ μœΌλ‘œ μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ’‘ μ•Œμ•„λ‘κΈ°: λ°±κ·ΈλΌμš΄λ“œ μ„œλΉ„μŠ€λŠ” λ‹¨μˆœνžˆ μ½”λ“œλ§Œ μž‘μ„±ν•΄μ„œλŠ” μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 운영체제 μ°¨μ›μ—μ„œμ˜ κΆŒν•œ 섀정이 ν•„μˆ˜μ μž…λ‹ˆλ‹€.

μ™œ κΆŒν•œ 섀정이 μ€‘μš”ν•œκ°€

슀마트폰 μ‚¬μš©μžλ“€μ˜ ν”„λΌμ΄λ²„μ‹œ 보호λ₯Ό μœ„ν•΄ μ•ˆλ“œλ‘œμ΄λ“œμ™€ iOS λͺ¨λ‘ μ—„κ²©ν•œ κΆŒν•œ 관리 μ‹œμŠ€ν…œμ„ μš΄μ˜ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 앱이 λ°±κ·ΈλΌμš΄λ“œμ—μ„œ μ‹€ν–‰λ˜λ €λ©΄ μ‚¬μš©μžμ˜ λ™μ˜ ν•˜μ— ν•„μš”ν•œ κΆŒν•œλ“€μ„ 미리 νšλ“ν•΄μ•Ό ν•©λ‹ˆλ‹€.

κΆŒν•œ 없이 λ°±κ·ΈλΌμš΄λ“œ μž‘μ—…μ„ μ‹œλ„ν•˜λ©΄:

  • 앱이 μ€‘λ‹¨λ˜κ±°λ‚˜ κ°•μ œ μ’…λ£Œλ  수 μžˆμŠ΅λ‹ˆλ‹€
  • κΈ°κΈ° μ„±λŠ₯이 μ €ν•˜λ  수 μžˆμŠ΅λ‹ˆλ‹€
  • 배터리λ₯Ό κ³Όλ„ν•˜κ²Œ μ†ŒλΉ„ν•  수 μžˆμŠ΅λ‹ˆλ‹€
  • μ‚¬μš©μžμ—κ²Œ μ‹ λ’°λ₯Ό μžƒμ„ 수 μžˆμŠ΅λ‹ˆλ‹€
  • μ•± μŠ€ν† μ–΄μ— 등둝할 λ•Œ 심사 λΆˆν†΅κ³Όλ  수 μžˆμŠ΅λ‹ˆλ‹€

⚠️ μ€‘μš”: 특히 Google Playλ‚˜ App Store에 앱을 배포할 κ³„νšμ΄λΌλ©΄, μš”κ΅¬λ˜λŠ” κΆŒν•œλ“€μ— λŒ€ν•΄ λͺ…ν™•ν•œ μ‚¬μœ λ₯Ό μ„€λͺ…ν•΄μ•Ό ν•©λ‹ˆλ‹€. κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ 심사 κ±°λΆ€λ₯Ό λ‹Ήν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ•ˆλ“œλ‘œμ΄λ“œ κΆŒν•œ μ„€μ • μ™„λ²½ 정리

ν•„μš”ν•œ μ£Όμš” κΆŒν•œλ“€

μ•ˆλ“œλ‘œμ΄λ“œμ—μ„œ λ°±κ·ΈλΌμš΄λ“œ μ„œλΉ„μŠ€λ₯Ό κ΅¬ν˜„ν•  λ•ŒλŠ” μ—¬λŸ¬ κΆŒν•œμ΄ ν•„μš”ν•©λ‹ˆλ‹€. 각각의 역할을 μ΄ν•΄ν•˜κ³  적절히 μ„€μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.

FOREGROUND_SERVICE κΆŒν•œ

FOREGROUND_SERVICEλŠ” λ°±κ·ΈλΌμš΄λ“œ μ„œλΉ„μŠ€λ₯Ό ν¬κ·ΈλΌμš΄λ“œ λͺ¨λ“œλ‘œ μ‹€ν–‰ν•  λ•Œ ν•„μˆ˜ κΆŒν•œμž…λ‹ˆλ‹€. ν¬κ·ΈλΌμš΄λ“œ μ„œλΉ„μŠ€λŠ” μ‚¬μš©μžκ°€ 인지할 수 μžˆλ„λ‘ 항상 μ•Œλ¦Όμ„ ν‘œμ‹œν•©λ‹ˆλ‹€. μ΄λŠ” 배터리 μ†ŒλΉ„λ₯Ό 쀄이고 μ‹œμŠ€ν…œμ΄ 앱을 μ’…λ£Œν•˜μ§€ μ•Šλ„λ‘ λ³΄ν˜Έν•΄μ€λ‹ˆλ‹€.

AndroidManifest.xml νŒŒμΌμ— λ‹€μŒμ„ μΆ”κ°€ν•΄μ•Ό ν•©λ‹ˆλ‹€:

<uses-permission android:name=”android.permission.FOREGROUND_SERVICE” />

λ˜ν•œ service νƒœκ·Έμ—λ„ foregroundServiceType을 λͺ…μ‹œν•΄μ€˜μ•Ό ν•©λ‹ˆλ‹€. μ•±μ˜ λͺ©μ μ— 따라 λ‹€μ–‘ν•œ νƒ€μž…μ΄ μžˆμŠ΅λ‹ˆλ‹€:

  • location: μœ„μΉ˜ 정보λ₯Ό μ§€μ†μ μœΌλ‘œ μˆ˜μ§‘ν•˜λŠ” 경우
  • health: 건강 κ΄€λ ¨ 데이터λ₯Ό μˆ˜μ§‘ν•˜λŠ” 경우
  • media_playback: μŒμ•…μ΄λ‚˜ λΉ„λ””μ˜€ μž¬μƒ
  • data_sync: 데이터 동기화

ACCESS_BACKGROUND_LOCATION κΆŒν•œ

λ°±κ·ΈλΌμš΄λ“œμ—μ„œ GPS μœ„μΉ˜ 정보λ₯Ό μˆ˜μ§‘ν•΄μ•Ό ν•œλ‹€λ©΄ ACCESS_BACKGROUND_LOCATION κΆŒν•œμ΄ ν•„μš”ν•©λ‹ˆλ‹€. μ΄λŠ” 맀우 λ―Όκ°ν•œ κΆŒν•œμ΄λ―€λ‘œ μ£Όμ˜κ°€ ν•„μš”ν•©λ‹ˆλ‹€.

⚠️ 주의: ACCESS_BACKGROUND_LOCATION κΆŒν•œμ„ μ‚¬μš©ν•˜λ €λ©΄ Google Play에 앱을 등둝할 λ•Œ κΆŒν•œμ΄ ν•„μš”ν•œ μ •λ‹Ήν•œ μ‚¬μœ λ₯Ό μ œμΆœν•΄μ•Ό ν•©λ‹ˆλ‹€. λͺ…ν™•ν•œ 이유 없이 μ‚¬μš©ν•˜λ©΄ 심사 λΆˆν†΅κ³Όλ  κ°€λŠ₯성이 λ†’μŠ΅λ‹ˆλ‹€.

λ§Žμ€ κ°œλ°œμžλ“€μ΄ 이 κΆŒν•œ λ•Œλ¬Έμ— 어렀움을 κ²ͺκ³  μžˆμŠ΅λ‹ˆλ‹€. λŒ€μ‹  ν¬κ·ΈλΌμš΄λ“œ μ„œλΉ„μŠ€μ™€ μ œν•œλœ λ°±κ·ΈλΌμš΄λ“œ μž‘μ—…μ„ μ‘°ν•©ν•΄μ„œ 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 방법도 μžˆμŠ΅λ‹ˆλ‹€.

POST_NOTIFICATIONS κΆŒν•œ

Android 13(API 레벨 33) μ΄μƒμ—μ„œλŠ” μ•Œλ¦Όμ„ ν‘œμ‹œν•˜κΈ° μœ„ν•΄ POST_NOTIFICATIONS κΆŒν•œμ΄ ν•„μˆ˜μž…λ‹ˆλ‹€.

<uses-permission android:name=”android.permission.POST_NOTIFICATIONS” />

이 κΆŒν•œμ΄ μ—†μœΌλ©΄ λ°±κ·ΈλΌμš΄λ“œ μ„œλΉ„μŠ€μ˜ μ•Œλ¦Όμ΄ ν‘œμ‹œλ˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

AndroidManifest.xml 전체 μ˜ˆμ‹œ

μ‹€μ œλ‘œ ν•„μš”ν•œ κΆŒν•œλ“€μ„ AndroidManifest.xml에 μ •μ˜ν•˜λŠ” 방식은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

<manifest …>
<uses-permission android:name=”android.permission.FOREGROUND_SERVICE” />
<uses-permission android:name=”android.permission.POST_NOTIFICATIONS” />
<uses-permission android:name=”android.permission.ACCESS_BACKGROUND_LOCATION” />

<application>

<service
android:name=”id.flutter.flutter_background_service.BackgroundService”
android:foregroundServiceType=”location” />
</application>
</manifest>

λŸ°νƒ€μž„ κΆŒν•œ μš”μ²­

AndroidManifest.xml에 κΆŒν•œμ„ μ„ μ–Έν•˜λŠ” κ²ƒλ§ŒμœΌλ‘œλŠ” λΆ€μ‘±ν•©λ‹ˆλ‹€. Android 6.0 μ΄μƒμ—μ„œλŠ” λŸ°νƒ€μž„μ— μ‚¬μš©μžμ—κ²Œ κΆŒν•œμ„ λͺ…μ‹œμ μœΌλ‘œ μš”μ²­ν•΄μ•Ό ν•©λ‹ˆλ‹€.

λ°±κ·ΈλΌμš΄λ“œ μ„œλΉ„μŠ€λ₯Ό μ‹œμž‘ν•˜κΈ° 전에, μ„œλΉ„μŠ€κ°€ ν•„μš”λ‘œ ν•˜λŠ” κΆŒν•œλ“€μ΄ 이미 λΆ€μ—¬λ˜μ–΄ μžˆλŠ”μ§€ 확인해야 ν•©λ‹ˆλ‹€. λ§Œμ•½ κΆŒν•œμ΄ μ—†λ‹€λ©΄ μ‚¬μš©μžμ—κ²Œ κΆŒν•œμ„ μš”μ²­ν•˜λŠ” λŒ€ν™”μƒμžλ₯Ό λ„μ›Œμ•Ό ν•©λ‹ˆλ‹€.

πŸ’‘ 팁: Flutter의 permission_handler νŒ¨ν‚€μ§€λ₯Ό μ‚¬μš©ν•˜λ©΄ κΆŒν•œ μš”μ²­ ν”„λ‘œμ„ΈμŠ€λ₯Ό μ‰½κ²Œ 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.

iOS κΆŒν•œ μ„€μ • μ™„λ²½ 정리

iOS의 νŠΉμˆ˜ν•œ ν™˜κ²½

iOSλŠ” μ•ˆλ“œλ‘œμ΄λ“œλ³΄λ‹€ 훨씬 더 μ—„κ²©ν•œ λ°±κ·ΈλΌμš΄λ“œ μž‘μ—… 정책을 κ°€μ§€κ³  μžˆμŠ΅λ‹ˆλ‹€. iOSμ—μ„œ λ°±κ·ΈλΌμš΄λ“œ μž‘μ—…μ€ 맀우 μ œν•œμ μ΄λ©°, μ‹œμŠ€ν…œμ—μ„œ ν—ˆμš©ν•˜λŠ” νŠΉμ • μƒν™©μ—μ„œλ§Œ μ‹€ν–‰λ©λ‹ˆλ‹€.

iOSμ—μ„œλŠ” ν¬κ·ΈλΌμš΄λ“œ μ„œλΉ„μŠ€λΌλŠ” κ°œλ…μ΄ μ—†μŠ΅λ‹ˆλ‹€. λŒ€μ‹  Xcodeμ—μ„œ μ„€μ •ν•΄μ•Ό ν•  μ—¬λŸ¬ ν•­λͺ©λ“€μ΄ μžˆμŠ΅λ‹ˆλ‹€.

Info.plist μ„€μ •

iOSμ—μ„œ λ°±κ·ΈλΌμš΄λ“œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λ €λ©΄ Info.plist νŒŒμΌμ— ν•„μš”ν•œ κΆŒν•œλ“€μ„ λͺ…μ‹œν•΄μ•Ό ν•©λ‹ˆλ‹€. 특히 μœ„μΉ˜ 정보λ₯Ό μ‚¬μš©ν•˜λŠ” 경우 λ°˜λ“œμ‹œ μ„€μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.

μœ„μΉ˜ 정보 μ ‘κ·Ό κΆŒν•œμ€ 두 κ°€μ§€λ‘œ λ‚˜λ‰©λ‹ˆλ‹€:

  • NSLocationWhenInUseUsageDescription: μ•± μ‚¬μš© 쀑일 λ•Œλ§Œ μœ„μΉ˜μ— μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€
  • NSLocationAlwaysAndWhenInUseUsageDescription: 앱이 λ°±κ·ΈλΌμš΄λ“œμ— μžˆμ–΄λ„ 항상 μœ„μΉ˜μ— μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€

λŒ“κΈ€ 남기기