我正在使用订阅进行应用内购买。 在swift中,您可以从SKProduct获得价格和价格区域设置,如下所示:
weeklyProduct.price.doubleValue
weeklyProduct.priceLocale.currencySymbol
其中weeklyProduct是SKProduct。
是否有可能获得免费试用期?例如,我为该产品指定了为期两周的免费试用版。我可以从SKProduct获得这个吗?
答案 0 :(得分:4)
你可以得到它,但如上所述它只能从iOS 11.2开始,对于其他版本,你必须通过API从服务器获取它。
以下是我使用的示例代码:
if #available(iOS 11.2, *) {
if let period = prod.introductoryPrice?.subscriptionPeriod {
print("Start your \(period.numberOfUnits) \(unitName(unitRawValue: period.unit.rawValue)) free trial")
}
} else {
// Fallback on earlier versions
// Get it from your server via API
}
func unitName(unitRawValue:UInt) -> String {
switch unitRawValue {
case 0: return "days"
case 1: return "weeks"
case 2: return "months"
case 3: return "years"
default: return ""
}
}
答案 1 :(得分:4)
我第一次发布答案。保持温柔...
以Eslam's answer为灵感,我创建了SKProduct.PeriodUnit的扩展
extension SKProduct.PeriodUnit {
func description(capitalizeFirstLetter: Bool = false, numberOfUnits: Int? = nil) -> String {
let period:String = {
switch self {
case .day: return "day"
case .week: return "week"
case .month: return "month"
case .year: return "year"
}
}()
var numUnits = ""
var plural = ""
if let numberOfUnits = numberOfUnits {
numUnits = "\(numberOfUnits) " // Add space for formatting
plural = numberOfUnits > 1 ? "s" : ""
}
return "\(numUnits)\(capitalizeFirstLetter ? period.capitalized : period)\(plural)"
}
}
要使用:
if #available(iOS 11.2, *),
let period = prod?.introductoryPrice?.subscriptionPeriod
{
let desc = period.unit.description(capitalizeFirstLetter: true, numberOfUnits: period.numberOfUnits)
} else {
// Fallback
}
这将创建格式正确的字符串(例如1天,1周,2个月,2年)
答案 2 :(得分:0)
试用长度不包含在SKProduct信息中,必须硬编码到应用程序中或存储在您的服务器上。导出此类信息(当前)的唯一可用选项来自收据本身。
答案 3 :(得分:0)
从iOS 11.2开始,您可以使用write
的{{3}}属性获取有关试用的信息。
它包含introductoryPrice
类的实例,它描述了所有折扣期,包括免费试用。
答案 4 :(得分:0)
一个不错的@scott Wood。我将其设为 FBSDKShareDialog *dialog = [[FBSDKShareDialog alloc] init];
FBSDKSharePhoto *photo = [[FBSDKSharePhoto alloc] init];
FBSDKSharePhotoContent *content = [[FBSDKSharePhotoContent alloc] init];
for( int i = 0; i < (int)pActiveSession.aShotImages.count; i++ )
{
UIImage *image = [UIImage imageWithData:pActiveSession.aShotImages[i]];
[pActiveSession.allShotImages addObject:[self resizeImage:image]];
}
content.photos = pActiveSession.allShotImages;
photo.userGenerated = YES;
dialog.mode = FBSDKShareDialogModeNative;
dialog.fromViewController = self;
[FBSDKShareDialog showFromViewController:self
withContent:content
delegate:nil];
的属性而不是函数。这样可以使行为与枚举更加一致:
SKProduct.PeriodUnit
然后是一个基于@available(iOS 11.2, *)
extension SKProduct.PeriodUnit {
var description: String {
switch self {
case .day: return "day"
case .week: return "week"
case .month: return "month"
case .year: return "year"
// support for future values
default:
return "N/A"
}
}
func pluralisedDescription(length: Int) -> String {
let lengthAndDescription = length.description + " " + self.description
let plural = length > 1 ? lengthAndDescription + "s" : lengthAndDescription
return plural
}
}
属性返回复数的函数。
是的,正如其他人指出的那样,如果您的应用程序支持其他语言,则应本地化复数形式。
答案 5 :(得分:0)
我已经使用DateComponentsFormatter解决了它,这为您节省了很多时间来本地化不同的语言并处理复数形式。 这似乎是很多代码,但我希望以后可以节省我的时间。
import Foundation
class PeriodFormatter {
static var componentFormatter: DateComponentsFormatter {
let formatter = DateComponentsFormatter()
formatter.maximumUnitCount = 1
formatter.unitsStyle = .full
formatter.zeroFormattingBehavior = .dropAll
return formatter
}
static func format(unit: NSCalendar.Unit, numberOfUnits: Int) -> String? {
var dateComponents = DateComponents()
dateComponents.calendar = Calendar.current
componentFormatter.allowedUnits = [unit]
switch unit {
case .day:
dateComponents.setValue(numberOfUnits, for: .day)
case .weekOfMonth:
dateComponents.setValue(numberOfUnits, for: .weekOfMonth)
case .month:
dateComponents.setValue(numberOfUnits, for: .month)
case .year:
dateComponents.setValue(numberOfUnits, for: .year)
default:
return nil
}
return componentFormatter.string(from: dateComponents)
}
}
它需要将SKProduct周期单位转换为NSCalendarUnit
import StoreKit
@available(iOS 11.2, *)
extension SKProduct.PeriodUnit {
func toCalendarUnit() -> NSCalendar.Unit {
switch self {
case .day:
return .day
case .month:
return .month
case .week:
return .weekOfMonth
case .year:
return .year
@unknown default:
debugPrint("Unknown period unit")
}
return .day
}
}
您可以像这样从Subscription时段调用它:
import StoreKit
@available(iOS 11.2, *)
extension SKProductSubscriptionPeriod {
func localizedPeriod() -> String? {
return PeriodFormatter.format(unit: unit.toCalendarUnit(), numberOfUnits: numberOfUnits)
}
}
您可以依次从SKProductDiscount调用。请注意,我目前尚未实现其他PaymentModes。
import StoreKit
@available(iOS 11.2, *)
extension SKProductDiscount {
func localizedDiscount() -> String? {
switch paymentMode {
case PaymentMode.freeTrial:
return "Free trial for \(subscriptionPeriod.localizedPeriod() ?? "a period")"
default:
return nil
}
}
}
答案 6 :(得分:0)
快捷键5
import StoreKit
extension SKProduct {
func priceString() -> String {
let period:String = {
switch self.subscriptionPeriod?.unit {
case .day: return "day"
case .week: return "week"
case .month: return "month"
case .year: return "year"
case .none: return ""
case .some(_): return ""
}
}()
let price = self.localizedPrice!
let numUnits = self.subscriptionPeriod?.numberOfUnits ?? 0
let plural = numUnits > 1 ? "s" : ""
return String(format: "%@ for %d %@%@", arguments: [price, numUnits, period, plural])
}
}
要使用:
let price = product.priceString()
print(price)
结果:
THB 89.00 for 7 days
THB 149.00 for 1 month
答案 7 :(得分:0)
+ (NSString*)localizedTitleForSKPeriod:(SKProductSubscriptionPeriod*)period{
NSDateComponents *comps = [NSDateComponents new];
NSDateComponentsFormatter *fmt = [NSDateComponentsFormatter new];
switch (period.unit) {
case SKProductPeriodUnitDay:{
fmt.allowedUnits = NSCalendarUnitDay;
comps.day = period.numberOfUnits;
}break;
case SKProductPeriodUnitWeek:{
fmt.allowedUnits = NSCalendarUnitWeekOfMonth;
comps.weekOfMonth = period.numberOfUnits;
}break;
case SKProductPeriodUnitMonth:{
fmt.allowedUnits = NSCalendarUnitMonth;
comps.month = period.numberOfUnits;
}break;
case SKProductPeriodUnitYear: {
fmt.allowedUnits = NSCalendarUnitYear;
comps.year = period.numberOfUnits;
}break;
}
// 1 Day, 1 Week, 2 Weeks, 1 Month, 2 Months, 3 Months, 6 Months, 1 Year
fmt.unitsStyle = NSDateComponentsFormatterUnitsStyleFull;
// One Day, One Week, Two Weeks, etc
//fmt.unitsStyle = NSDateComponentsFormatterUnitsStyleSpellOut;
NSString *s = [[fmt stringFromDateComponents:comps] capitalizedString];
return s;
}
答案 8 :(得分:0)
这是更紧凑,使用更短的版本,用于Swift 5,扩展了SKProductSubscriptionPeriod
用法:
print("\(period.localizedDescription) free trial")
//Printed example "1 week free trial"
实施:
extension SKProductSubscriptionPeriod {
public var localizedDescription: String {
let period:String = {
switch self.unit {
case .day: return "day"
case .week: return "week"
case .month: return "month"
case .year: return "year"
@unknown default:
return "unknown period"
}
}()
let plural = numberOfUnits > 1 ? "s" : ""
return "\(numberOfUnits) \(period)\(plural)"
}
}
答案 9 :(得分:0)
目标C
#import "SKProduct+SKProduct.h"
-(NSString*_Nullable)localizedTrialDuraion{
if (@available(iOS 11.2, *)) {
NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
[formatter setUnitsStyle:NSDateComponentsFormatterUnitsStyleFull]; //e.g 1 month
formatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorDropAll;
NSDateComponents * dateComponents = [[NSDateComponents alloc]init];
[dateComponents setCalendar:[NSCalendar currentCalendar]];
switch (self.introductoryPrice.subscriptionPeriod.unit) {
case SKProductPeriodUnitDay:{
formatter.allowedUnits = NSCalendarUnitDay;
[dateComponents setDay:self.introductoryPrice.subscriptionPeriod.numberOfUnits];
break;
}
case SKProductPeriodUnitWeek:{
formatter.allowedUnits = NSCalendarUnitWeekOfMonth;
[dateComponents setWeekOfMonth:self.introductoryPrice.subscriptionPeriod.numberOfUnits];
break;
}
case SKProductPeriodUnitMonth:{
formatter.allowedUnits = NSCalendarUnitMonth;
[dateComponents setMonth:self.introductoryPrice.subscriptionPeriod.numberOfUnits];
break;
}
case SKProductPeriodUnitYear:{
formatter.allowedUnits = NSCalendarUnitYear;
[dateComponents setYear:self.introductoryPrice.subscriptionPeriod.numberOfUnits];
break;
}
default:{
return nil;
break;
}
break;
}
[dateComponents setValue:self.introductoryPrice.subscriptionPeriod.numberOfUnits forComponent:formatter.allowedUnits];
return [formatter stringFromDateComponents:dateComponents];
} else {
// Fallback on earlier versions
}
return nil;
}
答案 10 :(得分:0)
如果您使用 SwiftyStoreKit,localizedSubscriptionPeriod
是最简单的方法
import SwiftyStoreKit
product.introductoryPrice?.localizedSubscriptionPeriod // "1 week"