Unity IAP 2.2.2版本下如何获取iOS App Store所在国家/地区
获取iOS App Store所在国家/地区(Unity IAP 2.2.2版本)
我之前在项目里也碰到过一模一样的问题——Unity IAP 2.2.2确实没有直接暴露Apple StoreKit里的priceLocale字段,而且IP定位和货币代码推导的方案又被排除了。这里有两个经过验证的可行方案,你可以根据项目情况选择:
方案一:通过原生iOS插件直接调用StoreKit API
这是最稳定、最官方的方式,完全依赖Apple的原生API,不受Unity IAP版本变动的影响(只要StoreKit接口不变)。
步骤1:编写iOS原生代码
创建一个Objective-C文件(比如IAPRegionHelper.m),放在Unity项目的Plugins/iOS目录下:
#import <StoreKit/StoreKit.h> #import <Unity/UnityInterface.h> @interface IAPRegionHelper : NSObject <SKProductsRequestDelegate> @end @implementation IAPRegionHelper + (void)fetchStoreRegionForProductID:(NSString *)productID { SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:productID]]; request.delegate = [[self alloc] init]; [request start]; } - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { if (response.products.count > 0) { SKProduct *targetProduct = response.products.firstObject; NSLocale *priceLocale = targetProduct.priceLocale; NSString *countryCode = [priceLocale objectForKey:NSLocaleCountryCode]; // 将地区代码传回Unity的指定脚本 UnitySendMessage("IAPRegionReceiver", "OnStoreRegionReceived", [countryCode UTF8String]); } [request cancel]; } @end
步骤2:编写Unity C#接收代码
创建一个C#脚本(比如IAPRegionReceiver.cs),挂载到场景中的某个GameObject上:
using UnityEngine; using System.Runtime.InteropServices; public class IAPRegionReceiver : MonoBehaviour { [DllImport("__Internal")] private static extern void fetchStoreRegionForProductID(string productID); // 调用这个方法发起地区请求,传入任意一个已上架的商品ID即可 public void RequestStoreRegion(string validProductID) { #if UNITY_IOS && !UNITY_EDITOR fetchStoreRegionForProductID(validProductID); #endif } // 原生代码会回调这个方法,传入地区代码(比如"US"、"JP") public void OnStoreRegionReceived(string regionCode) { Debug.Log($"获取到App Store地区代码: {regionCode}"); // 在这里处理地区代码的逻辑 } }
使用的时候,只需要调用RequestStoreRegion方法,传入你已配置的任意一个商品ID,就能拿到对应的地区代码了。
方案二:通过反射获取Unity IAP内部的SKProduct对象
如果不想编写原生插件,可以尝试通过反射读取Unity IAP内部隐藏的iOS原生SKProduct实例,从中提取priceLocale信息。不过要注意:这个方案依赖Unity IAP的内部实现,版本更新后可能失效,但在2.2.2版本下是可以正常工作的。
using UnityEngine.Purchasing; using System.Reflection; using System; public static class IAPRegionUtility { public static string GetStoreRegionFromProduct(Product product) { #if UNITY_IOS && !UNITY_EDITOR // 读取Product类的私有字段m_StoreSpecificData FieldInfo storeSpecificField = typeof(Product).GetField("m_StoreSpecificData", BindingFlags.NonPublic | BindingFlags.Instance); if (storeSpecificField == null) return null; object storeSpecificData = storeSpecificField.GetValue(product); if (storeSpecificData == null) return null; // 读取iOS特有的SKProduct对象 FieldInfo skProductField = storeSpecificData.GetType().GetField("product", BindingFlags.Public | BindingFlags.Instance); if (skProductField == null) return null; object skProduct = skProductField.GetValue(storeSpecificData); if (skProduct == null) return null; // 获取priceLocale属性 PropertyInfo priceLocaleProp = skProduct.GetType().GetProperty("priceLocale"); if (priceLocaleProp == null) return null; object priceLocale = priceLocaleProp.GetValue(skProduct); if (priceLocale == null) return null; // 读取国家代码 MethodInfo getCountryCodeMethod = priceLocale.GetType().GetMethod("objectForKey", new Type[] { typeof(string) }); if (getCountryCodeMethod == null) return null; object countryCode = getCountryCodeMethod.Invoke(priceLocale, new object[] { "kCFLocaleCountryCodeKey" }); return countryCode as string; #endif return null; } }
使用示例:
// 假设你已经通过Unity IAP获取到了Product对象 Product myProduct = ...; string regionCode = IAPRegionUtility.GetStoreRegionFromProduct(myProduct); if (!string.IsNullOrEmpty(regionCode)) { Debug.Log($"App Store地区代码: {regionCode}"); }
补充说明
Unity IAP没有暴露priceLocale字段的原因是它是跨平台框架,很多其他平台(比如Google Play)没有对应的概念,所以只封装了通用的商品字段。而iOS平台特有的信息,就需要我们通过原生桥接或反射的方式去获取。
内容的提问来源于stack exchange,提问作者Akhrorjon
相关产品推荐
相关产品推荐

