サブスクリプションでのアプリ内購入に取り組んでいます。 Swiftでは、次のようにSKProductから価格と価格ロケールを取得できます。
weeklyProduct.price.doubleValue
weeklyProduct.priceLocale.currencySymbol
ここで、weeklyProductはSKProductです。
無料試用期間を取得することは可能ですか?たとえば、製品の2週間の無料試用を指定しました。これをSKProductから取得できますか?
入手できますが、前述のとおり、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 ""
}
}
初めて回答を投稿しました。穏やかな...
インスピレーションとして 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年など)。
素敵な@scott Wood。関数ではなく、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
}
}
そして、description
プロパティに基づいて、複数形を返す関数。
そして、はい、他の誰かが指摘したように、アプリが他の言語で利用できる場合は複数形をローカライズする必要があります。
試用期間はSKProduct情報に含まれていません。アプリにハードコードするか、サーバーに保存する必要があります。このタイプの情報を(現在のところ)導出するために利用できる唯一のオプションは、レシート自体からです。
IOS 11.2から、introductoryPrice
の- SKProduct
プロパティを使用して、トライアルに関する情報を取得できます。
SKProductDiscount
クラスのインスタンスが含まれ、無料トライアルを含むすべての割引期間が記述されています。
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
}
}
そして、次のようにSubscriptionPeriodから呼び出すことができます。
import StoreKit
@available(iOS 11.2, *)
extension SKProductSubscriptionPeriod {
func localizedPeriod() -> String? {
return PeriodFormatter.format(unit: unit.toCalendarUnit(), numberOfUnits: numberOfUnits)
}
}
SKProductDiscountから同様に呼び出すことができます。現時点では、他のPaymentModeは実装していません。
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
}
}
}