feat(ios): 首次启动询问无线数据权限
iOS 在首个接口请求前等待系统无线数据选择,避免未授权时请求被静默拒绝。
This commit is contained in:
1 parent
47df002d8e
commit
b5e9deb4bd
6 files changed
+199
-1
No files matched your search
@@ -0,0 +1,62 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
/// iOS 首次启动等待系统无线数据选择,再发首个接口请求。
|
||||
abstract final class WirelessDataPrompt {
|
||||
const WirelessDataPrompt._();
|
||||
|
||||
/// 系统选择超过此时长仍未回调时继续启动。
|
||||
static const Duration decisionTimeout = Duration(seconds: 15);
|
||||
|
||||
/// 与 iOS `WirelessDataPrompt.channelName` 保持一致。
|
||||
static const String channelName = 'com.stormg.lumadrama/wireless-data';
|
||||
|
||||
static const String _awaitDecisionMethod = 'awaitDecision';
|
||||
|
||||
static const MethodChannel _channel = MethodChannel(channelName);
|
||||
|
||||
static Future<void>? _pending;
|
||||
|
||||
/// 非 iOS 立即返回。iOS 只等待一次,失败或超时后放行。
|
||||
static Future<void> awaitDecision({
|
||||
required bool enabled,
|
||||
Future<void> Function()? ask,
|
||||
Duration? timeout,
|
||||
}) {
|
||||
if (!enabled) return Future<void>.value();
|
||||
return _pending ??= _askOnce(ask, timeout ?? decisionTimeout);
|
||||
}
|
||||
|
||||
/// 测试隔离用,清掉已完成的等待。
|
||||
@visibleForTesting
|
||||
static void resetForTest() {
|
||||
_pending = null;
|
||||
}
|
||||
|
||||
static Future<void> _askOnce(
|
||||
Future<void> Function()? ask,
|
||||
Duration timeout,
|
||||
) async {
|
||||
try {
|
||||
await (ask ?? _invokeChannel).call().timeout(timeout);
|
||||
} on TimeoutException {
|
||||
_log('decision timed out');
|
||||
} catch (error) {
|
||||
_log('decision skipped: $error');
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> _invokeChannel() {
|
||||
return _channel.invokeMethod<void>(_awaitDecisionMethod);
|
||||
}
|
||||
|
||||
static void _log(String message) {
|
||||
if (kDebugMode) {
|
||||
debugPrint('[wireless-data] $message');
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -2,17 +2,21 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'app.dart';
|
||||
import 'core/config/app_config.dart';
|
||||
import 'core/config/server_endpoint.dart';
|
||||
import 'core/platform/wireless_data_prompt.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await ServerEndpoint.load();
|
||||
AppConfig.ready = AppConfig.probeAndApplyBaseUrl();
|
||||
AppConfig.ready = WirelessDataPrompt.awaitDecision(
|
||||
enabled: !kIsWeb && defaultTargetPlatform == TargetPlatform.iOS,
|
||||
).then((_) => AppConfig.probeAndApplyBaseUrl());
|
||||
runApp(const LumaDramaApp());
|
||||
unawaited(
|
||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]),
|
||||
|
||||
Reference in new issue
Block a user