You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI Framework(.xcframework)中Xcode Strings Catalog不生效问题

iOS Framework项目Strings Catalog本地化失效问题

我在iOS Framework项目(将构建为.xcframework,未使用SPM或Podfile)中配置了Strings Catalog,采用应用级本地化方案(而非系统本地化),通过UserDefaults持久化用户上次使用的区域标识符。目前遇到的问题是:本地化完全不生效,始终返回键字符串而非翻译内容,且无任何错误反馈。

已实现以下代码逻辑:

1. 语言管理类与Locale扩展

用于切换和持久化区域设置,同时扩展Locale简化本地化字符串调用:

class LanguageSettings: ObservableObject {
    
    init() {
        var localeId = UserDefaults.standard.value(forKey: "locale") as? String
        if localeId == nil {
            localeId = Locale.current.identifier
        }
        switch localeId?.lowercased() {
        case "en","en-us":
            break
        case "ar":
            locale = LanguageSettings.arabic
            break
        default:
            break
        }
    }
    
    init(localeTest: Locale) {
        locale = localeTest
    }
    
    @Published var locale: Locale = Locale(identifier: "EN-US") {
        didSet {
            switch locale.identifier.lowercased() {
            case "en", "en-us":
                break
            case "ar":
                break
            default:
                locale = oldValue
                break
            }
            updateUserDefaults()
        }
    }
    
    private func updateUserDefaults() {
        UserDefaults.standard.setValue(locale.identifier, forKey: "locale")
    }
    
    static let english = Locale(identifier: "EN-US")
    static let arabic = Locale(identifier: "AR")
    
    static let availableLocales = [
        english, arabic
    ]
}

extension Locale {
    
    func string(localized: String.LocalizationValue, comment: StaticString? = nil) -> String {
        
        let localizedString = String(localized: localized, bundle: Bundle.main, locale: self, comment: comment)
        print("Value for \(localized) for \(identifier) is \(localizedString)")
        return localizedString
    }
}

2. 测试视图ErrorDisplay

使用上述语言管理类的SwiftUI视图,包含语言切换功能:

import Foundation
import SwiftUI

struct ErrorDisplay: View {
    
    @EnvironmentObject private var languageSettings: LanguageSettings
    @Environment(\.locale) private var locale: Locale
    
    var body: some View {
        
        let localeIdToName: [String: String] = [
            "en": "English",
            "en-us": "English",
            "ar": "Arabic"
        ]
        
//        let locale = languageSettings.locale
        
        GeometryReader { _ in
            VStack {
                Image(.exclamationTriangleSolid).foregroundColor(.white)
                    .padding(.top, 10)
                Text(locale.identifier)
                Divider().background(.white)
                HStack {
                    Text(localeIdToName[locale.identifier.lowercased()] ?? "-")
                        .padding(.all, 5)
                        .foregroundColor(.black)
                    Image(systemName: "chevron.down").foregroundColor(.black)
                        .padding(.trailing, 5)
                }
                    .background(.white)
                    .padding(.all, 8)
                    .containerShape(Rectangle())
                    .onTapGesture {
                        withAnimation {
                            showLocalePicker = true
                        }
                    }
                Text(message ?? "An error has occurred")
                    .multilineTextAlignment(.center)
                    .font(.system(size: 16))
                    .foregroundColor(.white)
                Button(
                    action: onReload
                ) {
                    Text(locale.string(localized: "Reload Video"))
                }
                    .padding(.vertical, 10)
            }
        }
            .sheet(isPresented: $showLocalePicker) {
                Text(
                    locale.string(localized: "Select Locale")
                ).padding()
                Text("Select Locale")
                ForEach(0..<availableLocales.count) { i in
                    let locale = availableLocales[i]
                    let name = localeIdToName[locale.identifier.lowercased()]
                    
                    Button(
                        action: {
                            withAnimation {
                                showLocalePicker = false
                            }
                            if name != nil {
                                languageSettings.locale = locale
                            }
                        }
                    ) {
                        Text(name ?? "-")
                    }.padding()
                }
                
                Button(
                    role: .destructive,
                    action: {
                        withAnimation {
                            showLocalePicker = false
                        }
                    }
                ) {
                    Text(locale.string(localized: "Cancel"))
                }.padding()
            }
    }
    
    var message: String? = nil
    
    var availableLocales: [Locale] = LanguageSettings.availableLocales
    
    var onReload: () -> Void
    
    @State private var showLocalePicker = false
}

3. 预览代码

用于测试阿拉伯语本地化的预览:

#Preview {
    ErrorDisplay(
        onReload: {}
    )
        .environment(\.locale, LanguageSettings.arabic)
        .environmentObject(
            LanguageSettings(localeTest: LanguageSettings.arabic)
        )
}

关键现象

  • Strings Catalog已完成英语、阿拉伯语的100%翻译
  • 注入的Environment级Locale正确,切换语言时视图会触发重建,日志打印正常
  • 日志始终输出本地化键(如Reload Video),而非对应的翻译内容

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 15:14:54