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

iOS技术问询:如何通过代码获取用户所在的App Store地区(非Locale方式)

获取合规的App Store用户地区方案

我之前刚好处理过类似的需求,给你分享两个Apple官方认可的实现方式,完全符合合规要求,比单纯用Locale更精准可靠:

方案一:iOS 13+ 直接用SKPaymentQueue的storefront属性(推荐)

从iOS 13开始,Apple在StoreKit里提供了SKPaymentQueue.default().storefront属性,它直接返回用户当前关联的App Store地区信息——如果用户登录了App Store账户,返回的是账户绑定的地区;未登录则返回设备IP对应的地区,这正是我们需要的精准结果。

代码示例:

import StoreKit

func fetchAppStoreCountryCode(completion: @escaping (String?) -> Void) {
    if #available(iOS 13.0, *) {
        let countryCode = SKPaymentQueue.default().storefront?.countryCode
        completion(countryCode)
    } else {
        // 调用iOS 13以下的兼容方案
        fetchLegacyAppStoreCountryCode(completion: completion)
    }
}

方案二:iOS 13以下兼容方案 - SKStoreProductRequest

对于iOS 13及更早版本,我们可以通过请求当前App的产品信息来获取storeFrontId,这个ID里包含了地区代码(格式类似143441-GB,拆分后GB就是国家代码)。

代码示例:

import StoreKit

func fetchLegacyAppStoreCountryCode(completion: @escaping (String?) -> Void) {
    guard let appBundleId = Bundle.main.bundleIdentifier else {
        completion(nil)
        return
    }
    
    let productRequest = SKStoreProductRequest(productIdentifier: appBundleId)
    productRequest.delegate = LegacyStoreFrontDelegate(completion: completion)
    productRequest.start()
}

// 单独的Delegate类,避免污染ViewController
class LegacyStoreFrontDelegate: NSObject, SKStoreProductRequestDelegate {
    private let completion: (String?) -> Void
    
    init(completion: @escaping (String?) -> Void) {
        self.completion = completion
        super.init()
    }
    
    func productRequest(_ request: SKStoreProductRequest, didReceive response: SKProductsResponse) {
        defer { request.finish() }
        guard let storeFrontId = response.storeFrontId else {
            completion(nil)
            return
        }
        
        let components = storeFrontId.components(separatedBy: "-")
        guard components.count == 2 else {
            completion(nil)
            return
        }
        
        completion(components[1])
    }
    
    func request(_ request: SKRequest, didFailWithError error: Error) {
        defer { request.finish() }
        print("获取App Store地区失败:\(error.localizedDescription)")
        completion(nil)
    }
}

后续处理

拿到国家代码后,你可以把它映射成对应的地区分组:

  • 美国:US
  • 欧洲地区:GB(英国)、FR(法国)、ES(西班牙)等

比如:

func isEuropeanUser(countryCode: String?) -> Bool {
    let europeanCountryCodes = ["GB", "FR", "ES", "DE", "IT"] // 按需扩展欧洲国家代码
    return countryCode.flatMap { europeanCountryCodes.contains($0) } ?? false
}

func isUSUser(countryCode: String?) -> Bool {
    return countryCode == "US"
}

注意事项

  • 这两种方法都不需要额外的权限,只需导入StoreKit框架即可。
  • 相比Locale.countryCode,这些方法直接从App Store服务获取数据,不受用户手动修改系统语言/区域设置的影响,更符合合规和业务需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:22:58