苹果内购如何精确获取商品列表的货币符号
最近公司在搞全球化多地区产品,又加上苹果发邮件商品金额与实际支付的不一致,需要尽快整改,所以需要获取商品实际支付的货币单位,金额等。
之前因为做过国内游戏外币代充判断,解决方案是通过以下代码来获取支付国家代号来判断是否存在代充。
SKProduct * pProduct = (SKProduct *)[pProducts objectAtIndex: i]; NSString * nstrProductIdentifier = pProduct.productIdentifier; NSLocale *storeLocale = pProduct.priceLocale; NSString *storeCountry = (NSString*)CFLocaleGetValue((CFLocaleRef)storeLocale, kCFLocaleCountryCode);//获取当前商店的国家地区代号,因为适配低版本系统,无法直接用点语法。
然后就发现各种坑。。首先是通过
NSString *storeCountry = (NSString*)CFLocaleGetValue((CFLocaleRef)storeLocale, kCFLocaleCurrencySymbol);//原本打算通过这个来获取商品的货币符号
但这行代码某些地区获取到的货币符号根本不对。。比如台湾地区应该是NT$,但实际获取到的是$,iOS10以上的都不对,iOS9是对的。
后来参考github的IAPHelper这个项目,使用的以下代码通过NSNumberFormatter转换一下来获取最终的带货币符号的金额。
- (NSString *)getLocalePrice:(SKProduct *)product {
if (product) {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[formatter setLocale:product.priceLocale];
return [formatter stringFromNumber:product.price];
}
return @"";
}
结果在测试过程中,发现在印度尼西亚这个诡异的国家,竟然又无法转换成Rp 299 这样的格式,而是直接转成IDR299了,真的是被苹果坑的五体投地。。
研究了一下午,发现是NSNumberFormatter的locale包含了languageCode属性,如果这个languageCode不是当地的,而是直接取的en,就无法正确转换成苹果支付时显示的货币格式。但是苹果返回的storeLocale里的languageCode就是en。。
最后最后的通过以下代码解决了问题,把台湾地区和印度尼西亚国家都给解决了,真的是被苹果坑到死,如果有人知道如何让苹果返回非en的storeLocale,也希望有人能分享下。
SKProduct * pProduct = (SKProduct *)[pProducts objectAtIndex: i];
NSString * nstrProductIdentifier = pProduct.productIdentifier;
NSLocale *storeLocale = pProduct.priceLocale;
NSString *currencySymbol = (NSString*)CFLocaleGetValue((CFLocaleRef)storeLocale, kCFLocaleCurrencySymbol);
NSString *currencyCode = (NSString*)CFLocaleGetValue((CFLocaleRef)storeLocale, kCFLocaleCurrencyCode);
NSLocale *finalLocal = nil;
NSArray<NSString *> *localeIds = [NSLocale availableLocaleIdentifiers];
for (NSString *localeId in localeIds) {
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:localeId];//这里的localeId中的语言部分取的是当地的语言,而非en,所以可以解决印度尼西亚的问题
NSString *country = (NSString*)CFLocaleGetValue((CFLocaleRef)locale, kCFLocaleCountryCode);
if ([country isEqualToString:(NSString*)CFLocaleGetValue((CFLocaleRef)storeLocale, kCFLocaleCountryCode)]) { finalLocal = locale;
}
}
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; [formatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[formatter setNumberStyle:kCFNumberFormatterCurrencyStyle];
[formatter setLocale:finalLocal];
方法2:你也可以这样写:
dispatch_async(dispatch_get_main_queue(), ^{
[_iconIM resetImageType:dict[@"icon"]];
NSString*num = [NSStringstringWithFormat:@"x %ld",[dict[@"num"]integerValue]];
[_numLabsetText:num];
// NSNumberFormatter*numberFormatter = [[NSNumberFormatter alloc] init];
// [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
// [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
// [numberFormatter setLocale:prod.priceLocale];
//
// NSLog(@"prod.numberFormatter:%@",numberFormatter);
// NSLog(@"prod.priceLocale:%@",prod.priceLocale);
// NSLog(@"prod.priceLocale.currencyCode:%@",prod.priceLocale.currencyCode);
NSString *currencySymbol = (NSString*)CFLocaleGetValue((CFLocaleRef)prod.priceLocale, kCFLocaleCurrencySymbol);
NSLog(@"currencySymbol:%@",currencySymbol);
// NSString *currencyCode = (NSString*)CFLocaleGetValue((CFLocaleRef)prod.priceLocale, kCFLocaleCurrencyCode);
// NSLog(@"prod.price:%@",prod.price);
[_priceLabsetText:[NSStringstringWithFormat:@"%@%@",currencySymbol,prod.price]];
});