ios - 如何测试应用商店购买收据获取原始应用版本

标签 ios

我想在应用启动时加载应用购买收据。如何模拟应用程序购买(不是应用程序内购买,而是实际的应用程序购买)以便我有收据? (我正在尝试从付费模式转变为免费模式)。

我正在使用此代码加载收据

(BOOL)isAppPreviouslyPurchased {
    BOOL wasPreviouslyPurchased = false;

    // Load the receipt from the app bundle.
    NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
    if (receiptData) {

        //read purchase version from receipt
        NSDictionary *receipt = [NSJSONSerialization JSONObjectWithData:receiptData options:0 error:nil];
        NSString *oldVersion = receipt[@"original_application_version"];
        float vFloat = [oldVersion floatValue];

        if (vFloat < 1.6) {
            wasPreviouslyPurchased = true;
        }
    }

    return wasPreviouslyPurchased;
}

最佳答案

首先:刷新您的收据

SKReceiptRefreshRequest *request = [[SKReceiptRefreshRequest alloc] init];
request.delegate = self;
[request start];

添加SKPaymentTransactionObserver协议(protocol)和这个方法

- (void)paymentQueue:(SKPaymentQueue *)queue
 updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction *transaction in transactions) {
        switch (transaction.transactionState) {
            // Call the appropriate custom method for the transaction state.
            case SKPaymentTransactionStatePurchasing:
                [self showTransactionAsInProgress:transaction deferred:NO];
                break;
            case SKPaymentTransactionStateDeferred:
                [self showTransactionAsInProgress:transaction deferred:YES];
                break;
            case SKPaymentTransactionStateFailed:
                [self failedTransaction:transaction];
                break;
            case SKPaymentTransactionStatePurchased:
                [self completeTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
                [self restoreTransaction:transaction];
                break;
            default:
                // For debugging
                NSLog(@"Unexpected transaction state %@", @(transaction.transactionState));
                break;
        }
    }
}

然后,当调用此方法时,您的收据将被刷新;)

其次:您必须解密收据

NSData *receipt; // Sent to the server by the device

// Create the JSON object that describes the request
NSError *error;
NSDictionary *requestContents = @{
    @"receipt-data": [receipt base64EncodedStringWithOptions:0]
};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
                                                      options:0
                                                        error:&error];

if (!requestData) { /* ... Handle error ... */ }

// Create a POST request with the receipt data.
NSURL *storeURL = [NSURL URLWithString:@"https://buy.itunes.apple.com/verifyReceipt"];
NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
[storeRequest setHTTPMethod:@"POST"];
[storeRequest setHTTPBody:requestData];

// Make a connection to the iTunes Store on a background queue.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:storeRequest queue:queue
        completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    if (connectionError) {
        /* ... Handle error ... */
    } else {
        NSError *error;
        NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
        if (!jsonResponse) { /* ... Handle error ...*/ }
        /* ... Send a response back to the device ... */
    }
}];

您可以使用此代码对其进行解密,但 Apple 并不真正推荐它。您应该从您的服务器调用 iTunes。

然后,您可以使用 Apple 服务器返回的响应来调用您的方法。

像这样(使用本地验证,如 Apple 所说的那样不好)

NSData *receipt; // Sent to the server by the device

// Create the JSON object that describes the request
NSError *error;
NSDictionary *requestContents = @{
    @"receipt-data": [receipt base64EncodedStringWithOptions:0]
};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
                                                      options:0
                                                        error:&error];

if (!requestData) { /* ... Handle error ... */ }

// Create a POST request with the receipt data.
NSURL *storeURL = [NSURL URLWithString:@"https://buy.itunes.apple.com/verifyReceipt"];
NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
[storeRequest setHTTPMethod:@"POST"];
[storeRequest setHTTPBody:requestData];

// Make a connection to the iTunes Store on a background queue.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:storeRequest queue:queue
        completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    if (connectionError) {
        /* ... Handle error ... */
    } else {
        NSError *error;
        NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
        if (!jsonResponse) { /* ... Handle error ...*/ }
          [self isAppPreviouslyPurchased:jsonResponse];
    }
}];

-(BOOL)isAppPreviouslyPurchased:(NSDictionary *)receipt {
    BOOL wasPreviouslyPurchased = false;

        NSString *oldVersion = receipt[@"original_application_version"];
        float vFloat = [oldVersion floatValue];

        if (vFloat < 1.6) {
            wasPreviouslyPurchased = true;
        }

    return wasPreviouslyPurchased;
}

关于ios - 如何测试应用商店购买收据获取原始应用版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27569244/

相关文章:

ios - 切换 UILabel 的隐藏状态

ios - 无法将通知推送到 iOS9 设备

ios - 归档 ios 构建 ionic 的问题

ios - 如何给 UIButton 标签赋负值?

ios - 获取 UIColor 的深色样式

ios - 找不到 NSAlert 类型

ios - 在编辑模式下重新排序数据后如何保存更改

ios - 如何在 iOS 应用程序中连接到 EC2 实例

ios - findObjectsInBackgroundWithBlock 显示没有结果

ios - Urban Airship 在 2.0 中坠毁