//
|
// BuyVipController.m
|
// BuWanVideo2.0
|
//
|
// Created by Aeline on 2021/7/18.
|
// Copyright © 2021 com.yeshi.buwansheque.ios. All rights reserved.
|
//
|
|
#import "BuyVipController.h"
|
#import "NormolNavView.h"
|
|
#import "dsbridge.h"
|
#import "JSAPI.h"
|
|
#import <StoreKit/StoreKit.h>
|
|
@interface BuyVipController () <WKNavigationDelegate, WKUIDelegate, NormolNavViewDelegate, SKPaymentTransactionObserver,SKProductsRequestDelegate>
|
|
@property (nonatomic, nullable, strong) NormolNavView *navView;
|
@property (nonatomic, nullable, strong) DWKWebView *webView;
|
|
@property (nonatomic, copy) NSString *code;
|
@property (nonatomic, copy) NSString *orderNo;
|
|
@property (nonatomic, assign) BOOL isBuying;
|
|
@property (nonatomic) JSCallback completionHandler;
|
@end
|
|
@implementation BuyVipController
|
|
- (void)viewDidLoad {
|
[super viewDidLoad];
|
[self checkBuyInfo];
|
[self addNotice];
|
[self loadViewConfig];
|
}
|
|
- (void)dealloc
|
{
|
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
|
}
|
|
- (void)addNotice {
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onBuyVip:) name:@"buyVip" object:nil];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onVipPayFinish:) name:@"vipPayFinish" object:nil];
|
|
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
|
}
|
|
- (void)checkBuyInfo {
|
NSArray* transactions = [SKPaymentQueue defaultQueue].transactions;
|
SKPaymentTransaction* transaction = [transactions firstObject];
|
if (transactions.count > 0) {
|
if (transaction.transactionState == SKPaymentTransactionStatePurchased){
|
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
|
}
|
}
|
}
|
|
- (void)viewWillAppear:(BOOL)animated {
|
[super viewWillAppear:animated];
|
[self.navigationController setNavigationBarHidden:YES animated:animated];
|
}
|
|
//- (void)viewWillDisappear:(BOOL)animated {
|
// [super viewWillDisappear:animated];
|
// [self.navigationController setNavigationBarHidden:NO animated:animated];
|
//
|
//}
|
|
- (void)loadViewConfig {
|
self.view.backgroundColor = [UIColor whiteColor];
|
[self.view addSubview:self.navView];
|
|
[self.view addSubview:self.webView];
|
|
[self.webView addJavascriptObject:[[JSAPI alloc] init] namespace:@"yestv"];
|
|
// open debug mode, Release mode should disable this.
|
[self.webView setDebugMode:true];
|
|
[self.webView customJavascriptDialogLabelTitles:@{@"alertTitle":@"Notification",@"alertBtn":@"OK"}];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:_url]];
|
// NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://vip.ysdq.yeshitv.com/index_ios_test.html"]];
|
[self.webView loadRequest:request];
|
}
|
|
- (void)onBuyVip:(NSNotification *)notice {
|
self.completionHandler = notice.userInfo[@"data"];
|
self.code = notice.userInfo[@"code"][@"code"];
|
self.orderNo = notice.userInfo[@"code"][@"orderNo"];
|
[self touchSubscribeVip];
|
}
|
|
- (void)onVipPayFinish:(NSNotification *)notice {
|
self.isBuying = YES;
|
[SVProgressHUD dismiss];
|
[UIApplication sharedApplication].keyWindow.userInteractionEnabled = YES;
|
}
|
- (void)touchSubscribeVip {
|
// 是否允许内购
|
if ([SKPaymentQueue canMakePayments]) {
|
NSArray* transactions = [SKPaymentQueue defaultQueue].transactions;
|
if (transactions.count > 0) {
|
//检测是否有未完成的交易
|
SKPaymentTransaction* transaction = [transactions firstObject];
|
if (transaction.transactionState == SKPaymentTransactionStatePurchased) {
|
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
|
}
|
}
|
NSString *productID = _code;
|
// 添加内购条目设置的产品ID
|
NSArray *product = [[NSArray alloc] initWithObjects:productID, nil];
|
NSSet *nsset = [NSSet setWithArray:product];
|
|
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];
|
request.delegate = self;
|
|
[SVProgressHUD show];
|
[UIApplication sharedApplication].keyWindow.userInteractionEnabled = NO;
|
//开始请求
|
[request start];
|
|
} else {
|
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"内购未开启" message:@"进入【设置】-【屏幕使用时间】-【内容和隐私访问限制】-【iTunes Store 与 App Store 购买项目】-【App内购买项目】- 选择“允许”,将该功能开启" preferredStyle:UIAlertControllerStyleAlert];
|
|
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
[[self fetchCurrentViewController] dismissViewControllerAnimated:YES completion:nil];
|
}];
|
[alert addAction:defaultAction];
|
[[self fetchCurrentViewController] presentViewController:alert animated:YES completion:nil];
|
}
|
}
|
|
#pragma mark - SKProductsRequestDelegate
|
// 接收到产品的返回信息,然后用返回的商品信息进行发起购买请求
|
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response NS_AVAILABLE_IOS(3_0) {
|
|
NSArray *product = response.products;
|
// 如果服务器没有产品
|
if ([product count] == 0) {
|
dispatch_async(dispatch_get_main_queue(), ^{
|
//[SVProgressHUD showErrorWithStatus:@"商品不存在"];
|
});
|
return;
|
}
|
|
SKProduct *requestProduct = nil;
|
for (SKProduct *pro in product) {
|
|
NSLog(@"%@", [pro description]);
|
NSLog(@"%@", [pro localizedTitle]);
|
NSLog(@"%@", [pro localizedDescription]);
|
NSLog(@"%@", [pro price]);
|
NSLog(@"%@", [pro productIdentifier]);
|
|
//如果后台消费条目的ID与我这里需要请求的一样(用于确保订单的正确性)
|
//NSString *productID = _dictionaryVipInfo[@"ios_code"];
|
NSString *productID = _code;
|
if([pro.productIdentifier isEqualToString:productID]){
|
requestProduct = pro;
|
}
|
}
|
//发送购买请求
|
SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:requestProduct];
|
payment.applicationUsername = _orderNo;
|
[[SKPaymentQueue defaultQueue] addPayment:payment];
|
}
|
|
#pragma mark - SKRequestDelegate
|
//请求失败
|
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
|
dispatch_async(dispatch_get_main_queue(), ^{
|
[SVProgressHUD dismiss];
|
[UIApplication sharedApplication].keyWindow.userInteractionEnabled = YES;
|
});
|
}
|
|
//请求结束
|
- (void)requestDidFinish:(SKRequest *)request {
|
dispatch_async(dispatch_get_main_queue(), ^{
|
[SVProgressHUD dismiss];
|
[UIApplication sharedApplication].keyWindow.userInteractionEnabled = YES;
|
});
|
}
|
|
#pragma mark - SKPaymentTransactionObserver
|
// 监听购买结果
|
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
|
for(SKPaymentTransaction *tran in transactions){
|
switch (tran.transactionState) {
|
case SKPaymentTransactionStatePurchased:
|
NSLog(@"交易完成");
|
[self completeTransaction:tran];
|
break;
|
|
case SKPaymentTransactionStatePurchasing:
|
NSLog(@"商品添加进列表");
|
break;
|
|
case SKPaymentTransactionStateRestored: {
|
NSLog(@"已经购买过商品");
|
[[SKPaymentQueue defaultQueue] finishTransaction:tran];
|
break;
|
}
|
|
case SKPaymentTransactionStateFailed: {
|
[[SKPaymentQueue defaultQueue] finishTransaction:tran];
|
break;
|
}
|
default:
|
break;
|
}
|
}
|
}
|
|
//交易结束,当交易结束后还要去appstore上验证支付信息是否都正确,只有所有都正确后,我们就可以给用户方法我们的虚拟物品了。
|
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
|
|
[SVProgressHUD showWithStatus:@"正在验证支付信息~请勿退出"];
|
//验证凭据,获取到苹果返回的交易凭据
|
//appStoreReceiptURL iOS7.0增加的,购买交易完成后,会将凭据存放在该地址
|
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
|
//从沙盒中获取到购买凭据
|
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
|
//解析凭证
|
NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
|
|
NSMutableDictionary *parms = [[NSMutableDictionary alloc] init];
|
parms[@"receipt"] = encodeStr;
|
parms[@"orderNo"] = self.orderNo;
|
|
NSString *json = [self jsonStringToJsonData:parms];
|
|
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
|
!self.completionHandler?:self.completionHandler(json, YES);
|
|
//临时储存凭证
|
// self.plist.dataName = @"appleBuy";
|
// NSMutableDictionary *parms = [[NSMutableDictionary alloc] init];
|
// [parms setObject:[NSString stringWithFormat:@"%ld",(long)_type] forKey:@"id"];//package_id
|
// [parms setObject:encodeStr forKey:@"code"];//购买凭据
|
// if (self.order_number) {
|
// [parms setObject:self.order_number forKey:@"order_number"];
|
// }
|
// [self.plist writeFileWithData:parms];
|
//
|
// //服务器验证
|
// [self vertifyApplePayRequestWith:encodeStr transaction:transaction];
|
}
|
|
- (NSString *)jsonStringToJsonData:(id)dic {
|
if (!dic || [dic isEqual:[NSNull null]]) {
|
return @"";
|
}
|
NSError *error;
|
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&error];
|
|
NSString *jsonString = @"";
|
|
if (!jsonData) {
|
NSLog(@"%@",error);
|
|
} else {
|
jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
|
|
}
|
NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
|
|
NSRange range = {0, jsonString.length};
|
[mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
|
|
NSRange range2 = {0, mutStr.length};
|
//去掉字符串中的换行符
|
[mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
|
|
//NSRange range3 = {0,mutStr.length};
|
//去掉字符串中的换行符
|
//[mutStr replaceOccurrencesOfString:@"\\" withString:@"" options:NSLiteralSearch range:range3];
|
return mutStr;
|
}
|
|
|
#pragma mark --------- PPTVDelegate ---------
|
- (void)backVc {
|
!_refrshData?:_refrshData();
|
[self.navigationController popViewControllerAnimated:YES];
|
}
|
|
// 页面开始加载时调用
|
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
|
[self jsAdds];
|
}
|
|
// 页面加载失败时调用
|
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
|
|
}
|
|
// 当内容开始返回时调用
|
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
|
[self jsAdds];
|
[self performSelector:@selector(afterDelay) withObject:nil afterDelay:0.5];
|
}
|
|
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler {
|
|
[self jsAdds];
|
decisionHandler(WKNavigationActionPolicyAllow);//允许跳转
|
}
|
|
- (void)afterDelay {
|
[self.webView evaluateJavaScript:@"javascript:adPlayFinish()" completionHandler:^(id _Nullable object, NSError * _Nullable error) {}];
|
}
|
|
- (void)jsAdds {
|
NSString *str = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"js"ofType:@"txt"] encoding:NSUTF8StringEncoding error:nil];
|
[self.webView evaluateJavaScript:str completionHandler:^(id _Nullable object, NSError * _Nullable error) {}];
|
}
|
|
- (NormolNavView *)navView {
|
if (!_navView) {
|
_navView = [[NormolNavView alloc] initWithFrame:CGRectMake(0, 0, KScreenW, kStatusBarH + ALNavBarH)];
|
_navView.delegate = self;
|
}
|
return _navView;
|
}
|
|
- (DWKWebView *)webView {
|
if (!_webView) {
|
// 0.网页配置对象
|
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
|
// 1.原生与JS交互管理
|
WKUserContentController *userContentController = [[WKUserContentController alloc] init];
|
|
// 添加
|
config.userContentController = userContentController;
|
|
// 3.WKWebview设置
|
WKPreferences *prefer = [[WKPreferences alloc] init];
|
//设置是否支持javaScript 默认是支持的
|
prefer.javaScriptEnabled = YES;
|
// // 在iOS上默认为NO,表示是否允许不经过用户交互由javaScript自动打开窗口
|
prefer.javaScriptCanOpenWindowsAutomatically = YES;
|
// 添加
|
config.preferences = prefer;
|
config.preferences.minimumFontSize = 0.0f;
|
// 是使用h5的视频播放器在线播放, 还是使用原生播放器全屏播放
|
config.allowsInlineMediaPlayback = YES;
|
//设置视频是否需要用户手动播放 设置为NO则会允许自动播放
|
config.mediaTypesRequiringUserActionForPlayback = YES;
|
//设置是否允许画中画技术 在特定设备上有效
|
config.allowsPictureInPictureMediaPlayback = YES;
|
//设置请求的User-Agent信息中应用程序名称 iOS9后可用
|
config.applicationNameForUserAgent = @"ChinaDailyForiPad";
|
|
config.suppressesIncrementalRendering = YES;
|
|
_webView = [[DWKWebView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.navView.frame), KScreenW, KScreenH - CGRectGetHeight(self.navView.frame)) configuration:config];
|
|
_webView.DSUIDelegate = self;
|
_webView.navigationDelegate = self;
|
|
// 是否允许手势左滑返回上一级, 类似导航控制的左滑返回
|
_webView.allowsBackForwardNavigationGestures = YES;
|
//可返回的页面列表, 存储已打开过的网页
|
//WKBackForwardList * backForwardList = [_webView backForwardList];
|
}
|
return _webView;
|
}
|
|
- (NSString *)getParamByName:(NSString *)name URLString:(NSString *)url {
|
|
NSError *error;
|
NSString *regTags=[[NSString alloc] initWithFormat:@"(^|&|\\?)+%@=+([^&]*)(&|$)", name];
|
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regTags
|
options:NSRegularExpressionCaseInsensitive
|
error:&error];
|
|
// 执行匹配的过程
|
NSArray *matches = [regex matchesInString:url
|
options:0
|
range:NSMakeRange(0, [url length])];
|
for (NSTextCheckingResult *match in matches) {
|
NSString *tagValue = [url substringWithRange:[match rangeAtIndex:2]]; // 分组2所对应的串
|
return tagValue;
|
}
|
return @"";
|
}
|
|
- (UIViewController *)fetchCurrentViewController {
|
UIViewController* currentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
|
BOOL runLoopFind = YES;
|
while (runLoopFind) {
|
if (currentViewController.presentedViewController) {
|
currentViewController = currentViewController.presentedViewController;
|
} else if ([currentViewController isKindOfClass:[UINavigationController class]]) {
|
UINavigationController* navigationController = (UINavigationController* )currentViewController;
|
currentViewController = [navigationController.childViewControllers lastObject];
|
} else if ([currentViewController isKindOfClass:[UITabBarController class]]) {
|
UITabBarController* tabBarController = (UITabBarController* )currentViewController;
|
currentViewController = tabBarController.selectedViewController;
|
} else {
|
NSUInteger childViewControllerCount = currentViewController.childViewControllers.count;
|
if (childViewControllerCount > 0) {
|
currentViewController = currentViewController.childViewControllers.lastObject;
|
return currentViewController;
|
} else {
|
return currentViewController;
|
}
|
}
|
}
|
return currentViewController;
|
}
|
@end
|