我正在 XCode 模拟器中测试应用程序购买。我使用一个测试帐户登录。现在我想用另一个帐户测试它,它要求我输入第一个帐户的密码。我怎样才能完全退出它。我尝试通过清理(Shift + Command + k,Shift + Command + Option + k)并删除 ~Library/Application Support/iPhone Simultor/6.1/ 中的所有文件夹仍然没有用。
我在处理应用内购买时遇到了两个错误。
第一个是private let productIdentifiers: Set它出现错误“对泛型类型'Set'的引用需要<...>中的参数”
我的代码中的第二个错误是private var purchasedProductIdentifiers = Set() 它出现了错误“无法推断通用参数‘元素’”
这是我靠近两个错误的大部分代码:
public class IAPHelper : NSObject {
private let productIdentifiers: Set
private var purchasedProductIdentifiers = Set()
private var productsRequest: SKProductsRequest?
private var productsRequestCompletionHandler: ProductsRequestCompletionHandler?
static let IAPHelperPurchaseNotification = "IAPHelperPurchaseNotification"
public init(productIds: Set<ProductIdentifier>) {
self.productIdentifiers = productIds
super.init()
}
}
Run Code Online (Sandbox Code Playgroud)
帮助会很好!
编辑:当我将第二个错误更改为时,我现在收到错误 '>' is not a postfix unary operator private var purchasedProductIdentifiers = Set<ProductIdentifier> = Set()
我想在我的应用程序中实现年度订阅,我使用StoreKit. 问题是,当我点击subscriptionButton. 抛出错误的应用程序:'NSInvalidArgumentException', reason: 'Cannot finish a purchasing transaction'。我被困在这个地方,无法解决我的问题。所以,我的paymentQueue代码看起来像这样:
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
print(transactions)
for transaction in transactions {
print(transaction.error ?? "")
switch transaction.transactionState {
case .deferred:
print("deffered")
case let .failed(err):
print("failed: \(err)")
case .purchased:
let productID = p.productIdentifier
selectProduct(productID: productID)
case .purchasing:
print("purhasing")
print("produkt name: \(p.localizedTitle)") // after executing this line of code app crashes
case .restored:
let productID = p.productIdentifier
selectProduct(productID: productID)
}
queue.finishTransaction(transaction)
}
} …Run Code Online (Sandbox Code Playgroud) 文档说,一个应用程序可以每年通过 SKSToreReviewController 要求用户三次进行评分。
大多数建议在 UserDefaults 中保存一个变量,并在使用几次后调用该函数。如果您每年调用该函数超过 3 次,会发生什么情况?App Store 会忽略这些电话并在一年后再次要求评级还是会出现某种错误?
如果应用程序已更新(即从 1.0 版跳转到 2.0 版)会发生什么?这 3 个请求会被重置吗?
我不完全明白这一点。例如,如果我尝试恢复用户 6 个月前购买的一年订阅:
如果此订阅在一年后自动续订,并且我们在 6 个月后再次恢复它: - 原始购买日期是哪一天?- 购买日期是哪一天?
到目前为止我的理解是: 购买日期:始终是恢复的时间 原始购买日期:很可能是订阅期的开始。但如果是自动续订的话,是第一次订阅的开始吗?还是每个续订期的开始?
我目前正在尝试设置本地环境来测试 macOS 应用程序中的应用内购买。
位于https://developer.apple.com/documentation/xcode/setting_up_storekit_testing_in_xcode 的Apple 文档指出:
要创建 StoreKit 配置文件,请启动 Xcode,然后选择 File > New > File。在出现的工作表中,在过滤器搜索字段中输入“storekit”,然后选择 StoreKit 配置文件...
当我筛选“storekit”时,没有“StoreKit 配置文件”。
我究竟做错了什么?我是否需要在 Xcode 中安装某种 SDK 或类似软件?
我正在服务器端验证我的消费品应用内购买。
也就是说,我通过以下方式从客户端获取收据:
.onChange(of: self.storeObserver.paymentStatus) { status in
switch status {
case .purchasing:
print("Payment status: purchasing")
case .failed:
self.creatingGame = false
print("Payment status: failed")
case .deferred:
print("Payment status: deferred")
case .restored:
print("Payment status: restored")
case .purchased:
// Get the receipt if it's available
if Bundle.main.appStoreReceiptURL == nil {
print("appStoreReceiptURL is nil")
}
if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
do {
let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
let receiptString = receiptData.base64EncodedString(options: [])
print("receiptString: \(receiptString)")
// Read receiptData
createGame(receiptString: …Run Code Online (Sandbox Code Playgroud) 我正在使用Swift构建应用程序,我刚刚添加了StoreKit支持.我的应用程序中只有消耗品.
AppDelegate遵循SKPaymentTransactionObserver协议,这是我的paymentQueue:updatedTransactions方法:
func paymentQueue(queue: SKPaymentQueue!, updatedTransactions transactions: [AnyObject]!) {
for transaction in transactions as [SKPaymentTransaction] {
switch transaction.transactionState {
case SKPaymentTransactionState.Purchasing:
println("purchasing")
case SKPaymentTransactionState.Purchased:
println("payment done")
SKPaymentQueue.defaultQueue().finishTransaction(transaction)
case SKPaymentTransactionState.Failed:
println("payment failed")
SKPaymentQueue.defaultQueue().finishTransaction(transaction)
default:
println("nop \(transaction.transactionState)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
我已经在iTunes连接中创建了一个测试用户等等,一切正常,但所有事务都失败了.
交易进入购买状态然后失败,即使我在模拟器中确认交易.
知道为什么会这样吗?
谢谢.
我已经实现了应用程序内购买,它过去一直工作到现在.我添加了一些新的应用内购买和测试.它总是切换到SKPaymentTransactionStateFailed并且应用程序在该阶段崩溃并且没有给出错误消息.以下是应用内购买的代码:
-(void)fetchAvailableProducts{
NSSet *productIdentifiers = [NSSet
setWithObjects:@"xxx.template8",nil];
productsRequest = [[SKProductsRequest alloc]
initWithProductIdentifiers:productIdentifiers];
productsRequest.delegate = self;
[productsRequest start];
}
- (BOOL)canMakePurchases
{
return [SKPaymentQueue canMakePayments];
}
- (void)purchaseMyProduct:(SKProduct*)product{
if ([self canMakePurchases]) {
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
else{
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:
@"Purchases are disabled in your device" message:nil delegate:
self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
[alertView show];
}
}
-(IBAction)purchase:(id)sender{
[self purchaseMyProduct:[validProducts objectAtIndex:0]];
purchaseButton.enabled = NO;
}
#pragma mark StoreKit Delegate
-(void)paymentQueue:(SKPaymentQueue *)queue
updatedTransactions:(NSArray …Run Code Online (Sandbox Code Playgroud) 我正在尝试在应用程序中购买Swift应用程序,使用产品ID进行消费类应用内购买productID
研究
使用这个答案,我了解了应用内购买的基本模式,并尝试对其进行调整,就像这样.我不需要使用NSUserDefaults方法让应用程序记住是否进行了购买,因为我正在使用不同的解决方案处理它.
码
class ViewController: UICollectionViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver {
viewDidLoad() {
//Unimportant stuff left out
product_id = "productID"
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
}
@IBAction func thisISTheButtonToTriggerTheInAppPurchases(sender: AnyObject) {
if (SKPaymentQueue.canMakePayments()) {
var productID:NSSet = NSSet(object: self.product_id!);
var productsRequest:SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>);
productsRequest.delegate = self;
productsRequest.start();
print("Fetching Products");
}else{
print("can't make purchases");
}
}
func buyProduct(product: SKProduct){
print("Sending the Payment Request to Apple");
var payment = SKPayment(product: product)
SKPaymentQueue.defaultQueue().addPayment(payment);
}
func productsRequest (request: SKProductsRequest, didReceiveResponse response: …Run Code Online (Sandbox Code Playgroud)