0 评论

0 收藏

分享

[object-c开发相关技术] 01】针对客户详细信息开发苹果客户端object-c语言完整详细包含产品查询,购买,交易验

【01】针对客户详细信息开发苹果客户端object-c语言完整详细包含产品查询,购买,交易验证和恢复购买功能的完整实例-优雅草卓伊凡引言
此前由于卓伊凡我发布过关于苹果ios上架中 in -purchase 苹果内购问题 得到客户咨询来处理,苹果内购相关问题,现在讲demo写出如下,客户是采用object-c 开发的苹果客户端。
实战
目前已经配置好的后台
目前已经配置的积分,对应的商品金额
以下是一个详细的 Objective-C 内购实现示例,包含产品查询、购买、交易验证和恢复购买功能:
// InAppPurchaseManager.h#import <Foundation/Foundation.h>#import <StoreKit/StoreKit.h>NS_ASSUME_NONNULL_BEGINextern NSString *const IAPManagerProductPurchasedNotification;extern NSString *const IAPManagerProductPurchaseFailedNotification;extern NSString *const IAPManagerProductsLoadedNotification;@interface InAppPurchaseManager : NSObject <SKProductsRequestDelegate, SKPaymentTransactionObserver>+ (instancetype)sharedManager;// 查询产品信息- (void)requestProductsWithIdentifiers:(NSSet *)productIdentifiers;// 购买产品- (void)purchaseProduct:(SKProduct *)product;// 恢复购买- (void)restorePurchases;// 验证交易凭证- (void)verifyReceipt:(NSData *)receiptData;@property (nonatomic, strong) NSArray *products;@property (nonatomic, strong) NSSet *productIdentifiers;@property (nonatomic, strong) NSMutableSet *purchasedProductIdentifiers;@endNS_ASSUME_NONNULL_END// InAppPurchaseManager.m#import "InAppPurchaseManager.h"NSString *const IAPManagerProductPurchasedNotification = @"IAPManagerProductPurchasedNotification";NSString *const IAPManagerProductPurchaseFailedNotification = @"IAPManagerProductPurchaseFailedNotification";NSString *const IAPManagerProductsLoadedNotification = @"IAPManagerProductsLoadedNotification";@interface InAppPurchaseManager ()@property (nonatomic, strong) SKProductsRequest *productsRequest;@end@implementation InAppPurchaseManager+ (instancetype)sharedManager {    static InAppPurchaseManager *sharedInstance = nil;    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        sharedInstance = [[self alloc] init];    });    return sharedInstance;}- (instancetype)init {    if (self = [super init]) {        // 初始化产品标识符        _productIdentifiers = [NSSet setWithArray:@[@"001Liu", @"002Liu", @"003Liu"]];        _purchasedProductIdentifiers = [NSMutableSet set];        // 检查之前的购买记录        for (NSString *productIdentifier in _productIdentifiers) {            BOOL productPurchased = [[NSUserDefaults standardUserDefaults] boolForKey:productIdentifier];            if (productPurchased) {                [_purchasedProductIdentifiers addObject:productIdentifier];            }        }        // 添加支付观察者        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];    }    return self;}#pragma mark - 产品请求- (void)requestProductsWithIdentifiers:(NSSet *)productIdentifiers {    self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];    self.productsRequest.delegate = self;    [self.productsRequest start];}#pragma mark - SKProductsRequestDelegate- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {    self.products = response.products;    // 输出无效产品ID(用于调试)    for (NSString *invalidIdentifier in response.invalidProductIdentifiers) {        NSLog(@"无效产品ID: %@", invalidIdentifier);    }    // 通知产品已加载    [[NSNotificationCenter defaultCenter] postNotificationName:IAPManagerProductsLoadedNotification object:nil];    self.productsRequest = nil;}- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {    NSLog(@"产品请求失败: %@", error.localizedDescription);    self.productsRequest = nil;}#pragma mark - 购买功能- (void)purchaseProduct:(SKProduct *)product {    if (![SKPaymentQueue canMakePayments]) {        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"无法购买"                                                                       message:@"您的设备禁止应用内购买"                                                                preferredStyle:UIAlertControllerStyleAlert];        [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]];        [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alert animated:YES completion:nil];        return;    }    SKPayment *payment = [SKPayment paymentWithProduct:product];    [[SKPaymentQueue defaultQueue] addPayment:payment];}#pragma mark - SKPaymentTransactionObserver- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions {    for (SKPaymentTransaction *transaction in transactions) {        switch (transaction.transactionState) {            case SKPaymentTransactionStatePurchased:                [self completeTransaction:transaction];                break;            case SKPaymentTransactionStateFailed:                [self failedTransaction:transaction];                break;            case SKPaymentTransactionStateRestored:                [self restoreTransaction:transaction];                break;            default:                break;        }    }}- (void)completeTransaction:(SKPaymentTransaction *)transaction {    [self provideContentForProductIdentifier:transaction.payment.productIdentifier];    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];    // 验证交易凭证(可选但推荐)    [self verifyReceipt:transaction.transactionReceipt];}- (void)restoreTransaction:(SKPaymentTransaction *)transaction {    [self provideContentForProductIdentifier:transaction.originalTransaction.payment.productIdentifier];    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];}- (void)failedTransaction:(SKPaymentTransaction *)transaction {    if (transaction.error.code != SKErrorPaymentCancelled) {        NSLog(@"交易失败: %@", transaction.error.localizedDescription);        // 发送失败通知        [[NSNotificationCenter defaultCenter] postNotificationName:IAPManagerProductPurchaseFailedNotification                                                            object:transaction.error];    }    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];}- (void)provideContentForProductIdentifier:(NSString *)productIdentifier {    [_purchasedProductIdentifiers addObject:productIdentifier];    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:productIdentifier];    [[NSUserDefaults standardUserDefaults] synchronize];    // 发送购买成功通知    [[NSNotificationCenter defaultCenter] postNotificationName:IAPManagerProductPurchasedNotification                                                        object:productIdentifier];}#pragma mark - 恢复购买- (void)restorePurchases {    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];}- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {    NSLog(@"恢复购买完成");}- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {    NSLog(@"恢复购买失败: %@", error.localizedDescription);}#pragma mark - 凭证验证(示例)- (void)verifyReceipt:(NSData *)receiptData {    // 这里应该将凭证发送到你的服务器进行验证    // 以下是示例代码    NSURL *url = [NSURL URLWithString:@"https://your-server.com/verify_receipt"];    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];    request.HTTPMethod = @"POST";    // 构建请求体    NSDictionary *requestBody = @{@"receipt-data": [receiptData base64EncodedStringWithOptions:0],                                 @"password": @"your_shared_secret"}; // 如果有的话    NSError *error;    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:requestBody options:0 error:&error];    if (!error) {        request.HTTPBody = jsonData;        NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {            if (error) {                NSLog(@"验证失败: %@", error.localizedDescription);                return;            }            // 解析服务器响应            NSError *jsonError;            NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];            if (!jsonError) {                NSLog(@"验证结果: %@", responseJSON);                // 根据验证结果处理业务逻辑            }        }];        [task resume];    }}- (void)dealloc {    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];}@end// 使用示例 - 在ViewController中#import "ViewController.h"#import "InAppPurchaseManager.h"@interface ViewController () <SKProductsRequestDelegate>@property (weak, nonatomic) IBOutlet UIButton *purchaseButton1;@property (weak, nonatomic) IBOutlet UIButton *purchaseButton2;@property (weak, nonatomic) IBOutlet UIButton *purchaseButton3;@property (weak, nonatomic) IBOutlet UIButton *restoreButton;@property (nonatomic, strong) SKProduct *product1;@property (nonatomic, strong) SKProduct *product2;@property (nonatomic, strong) SKProduct *product3;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    // 注册通知    [[NSNotificationCenter defaultCenter] addObserver:self                                             selector:@selector(productsLoaded:)                                                 name:IAPManagerProductsLoadedNotification                                               object:nil];    [[NSNotificationCenter defaultCenter] addObserver:self                                             selector:@selector(productPurchased:)                                                 name:IAPManagerProductPurchasedNotification                                               object:nil];    // 请求产品信息    NSSet *productIdentifiers = [NSSet setWithArray:@[@"001Liu", @"002Liu", @"003Liu"]];    [[InAppPurchaseManager sharedManager] requestProductsWithIdentifiers:productIdentifiers];}- (void)productsLoaded:(NSNotification *)notification {    // 更新UI显示产品信息    for (SKProduct *product in [InAppPurchaseManager sharedManager].products) {        if ([product.productIdentifier isEqualToString:@"001Liu"]) {            self.product1 = product;            [self.purchaseButton1 setTitle:[NSString stringWithFormat:@"购买 - %@", product.price] forState:UIControlStateNormal];        } else if ([product.productIdentifier isEqualToString:@"002Liu"]) {            self.product2 = product;            [self.purchaseButton2 setTitle:[NSString stringWithFormat:@"购买 - %@", product.price] forState:UIControlStateNormal];        } else if ([product.productIdentifier isEqualToString:@"003Liu"]) {            self.product3 = product;            [self.purchaseButton3 setTitle:[NSString stringWithFormat:@"购买 - %@", product.price] forState:UIControlStateNormal];        }    }}- (void)productPurchased:(NSNotification *)notification {    NSString *productIdentifier = notification.object;    NSLog(@"购买成功: %@", productIdentifier);    // 更新UI,例如禁用已购买产品的按钮    if ([productIdentifier isEqualToString:@"001Liu"]) {        self.purchaseButton1.enabled = NO;        [self.purchaseButton1 setTitle:@"已购买" forState:UIControlStateNormal];    }    // 类似处理其他产品...}- (IBAction)purchaseProduct1:(id)sender {    if (self.product1) {        [[InAppPurchaseManager sharedManager] purchaseProduct:self.product1];    }}- (IBAction)purchaseProduct2:(id)sender {    if (self.product2) {        [[InAppPurchaseManager sharedManager] purchaseProduct:self.product2];    }}- (IBAction)purchaseProduct3:(id)sender {    if (self.product3) {        [[InAppPurchaseManager sharedManager] purchaseProduct:self.product3];    }}- (IBAction)restorePurchases:(id)sender {    [[InAppPurchaseManager sharedManager] restorePurchases];}- (void)dealloc {    [[NSNotificationCenter defaultCenter] removeObserver:self];}@end

优雅草论坛2022年8月11日大改,优雅草论坛变回只服务于客户的提问交流论坛,详情查看优雅草8月11日大改,原因详情查优雅草外卖乐关闭

回复

举报 使用道具

全部回复
暂无回帖,快来参与回复吧
yac2025
优雅草的临时工
主题 328
回复 0
粉丝 0