await AppTrackingTransparency.requestTrackingAuthorization();
String _authStatus = 'Unknown';
@override
void initState() {
super.initState();
// It is safer to call native code using addPostFrameCallback after the widget has been fully built and initialized.
// Directly calling native code from initState may result in errors due to the widget tree not being fully built at that point.
WidgetsFlutterBinding.ensureInitialized().addPostFrameCallback((_) => initPlugin());
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlugin() async {
final TrackingStatus status =
await AppTrackingTransparency.trackingAuthorizationStatus;
setState(() => _authStatus = '$status');
// If the system can show an authorization request dialog
if (status == TrackingStatus.notDetermined) {
// Show a custom explainer dialog before the system dialog
await showCustomTrackingDialog(context);
// Wait for dialog popping animation
await Future.delayed(const Duration(milliseconds: 200));
// Request system's tracking authorization dialog
final TrackingStatus status =
await AppTrackingTransparency.requestTrackingAuthorization();
setState(() => _authStatus = '$status');
}
final uuid = await AppTrackingTransparency.getAdvertisingIdentifier();
print("UUID: $uuid");
}
final uuid = await AppTrackingTransparency.getAdvertisingIdentifier();
<key>NSUserTrackingUsageDescription</key>
<string>This identifier will be used to deliver personalized ads to you.</string>
위치 정보 동의에 not allow를 눌러도 app fully funtional 하도록 하라고 나와있는데 물론 없이도 사용가능하지만 나는 뭔가 navigation 처럼 동작시키고자 설정으로 바로 보내주고 설정에서 ok를 누르면 앱을 다시 실행시키는 코드를 작성하고 싶었다.
처음에는 state를 이용하려 했으나 저거 하나 하자고 라이브러리를 설치하는 것이 아까워 조금 찾아보니 옵저버 패턴과
flutter life cycle을 이용하여 해결 할 수 있었다.
Future checkPermission() async {
final isLocationEnabled = await Geolocator.isLocationServiceEnabled();
if (!isLocationEnabled) {
return '위치 서비스를 활성화 해주세요.';
}
LocationPermission checkPermission = await Geolocator.checkPermission();
if (checkPermission == LocationPermission.denied) {
checkPermission = await Geolocator.requestPermission();
if (checkPermission == LocationPermission.denied) {
return '위치 권한을 허가해주세요.';
}
}
if (checkPermission == LocationPermission.deniedForever) {
return '앱의 위치 권한을 세팅에서 허가해주세요.';
}
return '위치 권한이 허가되었습니다.';
}
우선 옵저버 패턴에 대해서 알아봐야하는데 옵저버 패턴(Observer Pattern)이란?
옵저버 패턴은 객체의 상태가 변하면 이를 관찰하는 다른 객체에게 이를 알리는 설계 패턴이다.
이를 통해 한 객체의 상태가 변하면 이를 의존하는 다른 객체들이 이 변화를 자동으로 감지하여 반응할 수 있다.
예를 들어, Flutter에서 WidgetsBindingObserver
는 앱의 생명주기 상태 변화를 감지하는 역할을 한다. WidgetsBindingObserver
를 클래스에 추가하면 didChangeAppLifecycleState
와 같은 메소드를 오버라이드하여 앱의 생명주기 상태 변화를 감지하고 이에 따른 동작을 정의할 수 있다.
class _HomeScreenState extends State<HomeScreen> with WidgetsBindingObserver {
late WebViewController webViewController;
String? _token;
// initState 메소드에 WidgetsBinding.instance.addObserver 추가
@override
void initState() {
super.initState();
_token = widget.token;
WidgetsBinding.instance!.addObserver(this);
...
}
// dispose 메소드에 WidgetsBinding.instance.removeObserver 추가
@override
void dispose() {
WidgetsBinding.instance!.removeObserver(this);
super.dispose();
}
// 앱 생명주기 상태 변화 감지
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
setState(() {});
}
}
WidgetsBindingObserver
를 사용하여 앱의 생명주기 상태 변화를 감지하고, 앱이 활성 상태로 전환될 때마다 위치 권한 체크를 수행하도록 하였다.생명주기(Lifecycle)란?
생명주기는 앱이나 앱의 각 화면이 생성되고 소멸될 때까지의 과정을 의미한다. 대부분의 UI 프레임워크나 라이브러리는 컴포넌트의 생성, 업데이트, 소멸 등의 단계를 가지고 있으며, 이런 단계를 생명주기 메소드라고 부른다.
이 메소드들은 프레임워크나 라이브러리에서 자동으로 호출되며, 우리는 이 메소드를 오버라이드하여 각 단계에서 수행할 작업을 정의할 수 있다.
Flutter에서는 StatefulWidget
의 생명주기 메소드로 createState
, initState
, didChangeDependencies
, build
, didUpdateWidget
, deactivate
, dispose
등이 있다.
이 중에서 initState
는 위젯이 생성될 때 한 번만 호출되며, dispose
는 위젯이 소멸될 때 한 번만 호출된다. didChangeAppLifecycleState
는 앱의 상태가 변화했을 때 호출되는 메소드로, WidgetsBindingObserver
를 통해 사용할 수 있습니다.
따라서 위 코드는 WidgetsBindingObserver
를 통해 앱의 생명주기 상태를 감지하고, 앱이 활성 상태로 전환될 때마다 화면을 갱신하도록 하였다.
이를 통해 사용자가 앱 설정을 변경한 후 앱으로 돌아왔을 때 변경된 설정에 따라 화면이 갱신될 수 있다.