You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flutter:iOS平台下locale.countryCode返回null问题求助

解决Flutter在iOS上获取系统区域国家码为null的问题

我之前也遇到过一模一样的问题——用WidgetsBinding获取系统区域信息在Android上正常,但iOS的countryCode始终返回null。经过一番排查,总结出几个可行的解决方案:

原因分析

iOS的区域设置机制和Android存在差异,Flutter的WidgetsBinding.instance!.window.locale在iOS上有时无法正确映射系统的区域信息,尤其是当应用未配置支持的本地化列表时,更容易出现这个问题。


解决方案1:改用dart:ui的Locale API

dart:ui中的window.localeWidgetsBinding的实现更贴近原生平台,在iOS上的兼容性更好。试试这段代码:

import 'dart:ui' as ui;

void fetchSystemLocaleInfo() {
  // 获取主系统区域
  Locale mainLocale = ui.window.locale;
  String? countryCode = mainLocale.countryCode;

  // 如果主区域获取失败,遍历所有系统区域列表
  if (countryCode == null && ui.window.locales.isNotEmpty) {
    countryCode = ui.window.locales.first.countryCode;
  }

  print("获取到的国家码:$countryCode");
}

解决方案2:配置iOS的Info.plist

如果你的应用没有声明支持的本地化语言,iOS可能不会正确返回区域信息。在Info.plist中添加CFBundleLocalizations数组,包含你需要支持的语言代码:

<key>CFBundleLocalizations</key>
<array>
  <string>en</string> <!-- 英文 -->
  <string>zh-Hans</string> <!-- 简体中文 -->
  <string>ja</string> <!-- 日语 -->
  <!-- 按需添加其他语言 -->
</array>

添加后重新编译iOS应用,再尝试获取国家码,大概率能解决问题。


解决方案3:通过原生通道调用iOS原生API

如果上面两种方法都不生效,直接调用iOS原生的Locale.current.regionCode是最可靠的方式,因为原生API能直接获取系统的区域信息:

步骤1:iOS端编写原生代码

在Swift文件中创建MethodChannel处理器:

import Flutter
import UIKit

class LocaleHandler: NSObject, FlutterPlugin {
    static func register(with registrar: FlutterPluginRegistrar) {
        let channel = FlutterMethodChannel(name: "your.app.locale.channel", binaryMessenger: registrar.messenger())
        let instance = LocaleHandler()
        registrar.addMethodCallDelegate(instance, channel: channel)
    }

    func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        switch call.method {
        case "getCountryCode":
            let countryCode = Locale.current.regionCode
            result(countryCode)
        default:
            result(FlutterMethodNotImplemented)
        }
    }
}

然后在AppDelegate.swift中注册这个通道:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    LocaleHandler.register(with: self.registrar(forPlugin: "your.app.locale.channel")!)
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

步骤2:Flutter端调用原生方法

import 'package:flutter/services.dart';

Future<String?> fetchNativeCountryCode() async {
    const MethodChannel channel = MethodChannel("your.app.locale.channel");
    try {
        return await channel.invokeMethod<String>("getCountryCode");
    } on PlatformException catch (e) {
        print("获取国家码失败:${e.message}");
        return null;
    }
}

调用这个方法就能获取到iOS系统准确的国家码了。


内容的提问来源于stack exchange,提问作者Dani

火山引擎 最新活动