内购开发
This commit is contained in:
parent
b5b55119f6
commit
65a0753c20
@ -7,8 +7,6 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1B384A992DC1CFE800F5B1A2 /* FacebookCore in Frameworks */ = {isa = PBXBuildFile; productRef = 1B384A982DC1CFE800F5B1A2 /* FacebookCore */; };
|
||||
1B384A9B2DC1CFE800F5B1A2 /* FacebookLogin in Frameworks */ = {isa = PBXBuildFile; productRef = 1B384A9A2DC1CFE800F5B1A2 /* FacebookLogin */; };
|
||||
1BF22FD12DC2169B0082429A /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 1BF22FD02DC2169B0082429A /* FirebaseAnalytics */; };
|
||||
1BF22FD32DC2169B0082429A /* FirebaseCore in Frameworks */ = {isa = PBXBuildFile; productRef = 1BF22FD22DC2169B0082429A /* FirebaseCore */; };
|
||||
1BF22FD52DC2169B0082429A /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 1BF22FD42DC2169B0082429A /* FirebaseMessaging */; };
|
||||
@ -53,9 +51,7 @@
|
||||
1BF22FD52DC2169B0082429A /* FirebaseMessaging in Frameworks */,
|
||||
91D08C5AEAE459A3B8EA48C6 /* Pods_MoviaBox.framework in Frameworks */,
|
||||
1BF22FD32DC2169B0082429A /* FirebaseCore in Frameworks */,
|
||||
1B384A992DC1CFE800F5B1A2 /* FacebookCore in Frameworks */,
|
||||
1BF22FD12DC2169B0082429A /* FirebaseAnalytics in Frameworks */,
|
||||
1B384A9B2DC1CFE800F5B1A2 /* FacebookLogin in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -149,7 +145,6 @@
|
||||
mainGroup = 1DBC40502DA4EDFC0093FCB0;
|
||||
minimizedProjectReferenceProxies = 1;
|
||||
packageReferences = (
|
||||
1B384A972DC1CFE800F5B1A2 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */,
|
||||
1BF22FCF2DC2169B0082429A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
|
||||
);
|
||||
preferredProjectObjectVersion = 77;
|
||||
@ -460,14 +455,6 @@
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
1B384A972DC1CFE800F5B1A2 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/facebook/facebook-ios-sdk";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 14.1.0;
|
||||
};
|
||||
};
|
||||
1BF22FCF2DC2169B0082429A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/firebase/firebase-ios-sdk";
|
||||
@ -479,16 +466,6 @@
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
1B384A982DC1CFE800F5B1A2 /* FacebookCore */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 1B384A972DC1CFE800F5B1A2 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */;
|
||||
productName = FacebookCore;
|
||||
};
|
||||
1B384A9A2DC1CFE800F5B1A2 /* FacebookLogin */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 1B384A972DC1CFE800F5B1A2 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */;
|
||||
productName = FacebookLogin;
|
||||
};
|
||||
1BF22FD02DC2169B0082429A /* FirebaseAnalytics */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 1BF22FCF2DC2169B0082429A /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"originHash" : "356668427da72005d8cb60963e877385296f1863605fc5a20d1f75f2cec3b22c",
|
||||
"originHash" : "c63c63846d9c539229e96de38d6af51417e28c0ee9a0bc48bd0f0f19d923c329",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "abseil-cpp-binary",
|
||||
@ -19,15 +19,6 @@
|
||||
"version" : "11.2.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "facebook-ios-sdk",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/facebook/facebook-ios-sdk",
|
||||
"state" : {
|
||||
"revision" : "c19607d535864533523d1f437c84035e5fb101cf",
|
||||
"version" : "14.1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "firebase-ios-sdk",
|
||||
"kind" : "remoteSourceControl",
|
||||
|
@ -6,7 +6,9 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
#if canImport(FacebookCore)
|
||||
import FacebookCore
|
||||
#endif
|
||||
|
||||
|
||||
extension SceneDelegate {
|
||||
@ -17,7 +19,9 @@ extension SceneDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
#if canImport(FacebookCore)
|
||||
ApplicationDelegate.shared.application(UIApplication.shared, open: url, sourceApplication: nil, annotation: [UIApplication.OpenURLOptionsKey.annotation])
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,9 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
#if canImport(FacebookCore)
|
||||
import FacebookCore
|
||||
#endif
|
||||
|
||||
@main
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
@ -15,7 +17,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
///Facebook
|
||||
#if canImport(FacebookCore)
|
||||
ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
#endif
|
||||
|
||||
self.appConfig()
|
||||
///注册消息通知
|
||||
|
@ -17,7 +17,37 @@ class SPWalletAPI: NSObject {
|
||||
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<SPPayTemplateModel>) in
|
||||
completer?(response.data)
|
||||
}
|
||||
}
|
||||
|
||||
///创建内购订单
|
||||
static func requestCreateOrder(payId: String, shortPlayId: String = "0", videoId: String = "0", completer: ((_ orderModel: SPIAPOrderModel?) -> Void)?) {
|
||||
var param = SPNetworkParameters(path: "/createOrder")
|
||||
param.parameters = [
|
||||
"payment_channel" : "apple",
|
||||
"short_play_id" : shortPlayId,
|
||||
"video_id" : videoId,
|
||||
"pay_setting_id" : payId
|
||||
]
|
||||
|
||||
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<SPIAPOrderModel>) in
|
||||
completer?(response.data)
|
||||
}
|
||||
}
|
||||
|
||||
///校验内购
|
||||
static func requestVerifyOrder(orderCode: String, payId: String, productId: String, purchaseToken: String, completer: ((_ model: SPIAPVerifyModel?) -> Void)?) {
|
||||
var param = SPNetworkParameters(path: "/applePaid")
|
||||
param.parameters = [
|
||||
"order_code" : orderCode,
|
||||
"pay_setting_id" : payId,
|
||||
"pkg_name" : kSPAPPBundleIdentifier,
|
||||
"transaction_id" : productId,
|
||||
"purchases_token" : purchaseToken
|
||||
]
|
||||
|
||||
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<SPIAPVerifyModel>) in
|
||||
completer?(response.data)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,7 +26,12 @@ class SPCoinRechargeCell: SPCollectionViewCell {
|
||||
didSet {
|
||||
coinLabel.text = "\(model?.coins ?? 0)"
|
||||
|
||||
bonusLabel.text = String(format: "%@ Bonus".localized, "+\(model?.send_coins ?? 0)")
|
||||
if let sendCoins = model?.send_coins, sendCoins > 0 {
|
||||
bonusLabel.isHidden = false
|
||||
bonusLabel.text = String(format: "%@ Bonus".localized, "+\(sendCoins)")
|
||||
} else {
|
||||
bonusLabel.isHidden = true
|
||||
}
|
||||
|
||||
moneyLabel.text = "\(model?.currency ?? "")\(model?.price ?? "0")"
|
||||
}
|
||||
|
@ -15,6 +15,9 @@ class SPCoinRechargeView: UIView {
|
||||
|
||||
private lazy var currentIndexPath: IndexPath = .init(row: 0, section: 0)
|
||||
|
||||
///充值成功回调
|
||||
var rechargeFinishHandle: (() -> Void)?
|
||||
|
||||
var dataArr: [SPPayTemplateItem]? {
|
||||
didSet {
|
||||
self.collectionView.reloadData()
|
||||
@ -64,7 +67,7 @@ class SPCoinRechargeView: UIView {
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
coinLabel.text = "0"
|
||||
coinLabel.text = "\(SPLoginManager.manager.userInfo?.coin_left_total ?? 0)"
|
||||
|
||||
_setupUI()
|
||||
}
|
||||
@ -123,8 +126,19 @@ extension SPCoinRechargeView: UICollectionViewDelegate, UICollectionViewDataSour
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||
currentIndexPath = indexPath
|
||||
|
||||
collectionView.reloadData()
|
||||
|
||||
guard let model = self.dataArr?[indexPath.row] else { return }
|
||||
|
||||
SPIAPManager.manager.startRecharge(model: model) { [weak self] finish in
|
||||
|
||||
SPLoginManager.manager.updateUserInfo {
|
||||
self?.coinLabel.text = "\(SPLoginManager.manager.userInfo?.coin_left_total ?? 0)"
|
||||
}
|
||||
if finish {
|
||||
self?.rechargeFinishHandle?()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,14 +6,16 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
#if canImport(FacebookLogin)
|
||||
import FacebookLogin
|
||||
#endif
|
||||
|
||||
//https://developers.facebook.com/docs/facebook-login/ios?checkpoint_src=any
|
||||
extension SPLoginManager {
|
||||
|
||||
///facebook登录
|
||||
func facebookSignLogin(presentingViewController: UIViewController, completer: ((_ model: SPThirdSignModel?) -> Void)?) {
|
||||
|
||||
#if canImport(FacebookLogin)
|
||||
let loginManager = LoginManager()
|
||||
loginManager.logOut()
|
||||
loginManager.defaultAudience = .everyone
|
||||
@ -56,5 +58,6 @@ extension SPLoginManager {
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
93
MoviaBox/Libs/SPIAPManager/SPIAPManager.swift
Normal file
93
MoviaBox/Libs/SPIAPManager/SPIAPManager.swift
Normal file
@ -0,0 +1,93 @@
|
||||
//
|
||||
// SPIAPManager.swift
|
||||
// MoviaBox
|
||||
//
|
||||
// Created by 佳尔 on 2025/5/6.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SPIAPManager: NSObject {
|
||||
typealias CompletionHandler = ((_ finish: Bool) -> Void)
|
||||
///内购模版前缀
|
||||
static let IAPPrefix = "moviabox."
|
||||
|
||||
|
||||
static let manager = SPIAPManager()
|
||||
|
||||
///成功回调
|
||||
private var completionHandler: CompletionHandler?
|
||||
|
||||
private lazy var iapManager: JXIAPManager = {
|
||||
let manager = JXIAPManager()
|
||||
manager.delegate = self
|
||||
return manager
|
||||
}()
|
||||
|
||||
private var orderCode: String?
|
||||
private var payId: String?
|
||||
|
||||
///开始内购
|
||||
func startRecharge(model: SPPayTemplateItem, handler: CompletionHandler? = nil) {
|
||||
guard let payId = model.id else {
|
||||
handler?(false)
|
||||
return
|
||||
}
|
||||
self.completionHandler = handler
|
||||
|
||||
let productId = SPIAPManager.IAPPrefix + (model.ios_template_id ?? "")
|
||||
|
||||
SPHUD.show()
|
||||
|
||||
SPWalletAPI.requestCreateOrder(payId: payId) { orderModel in
|
||||
guard let orderModel = orderModel else {
|
||||
SPHUD.dismiss()
|
||||
self.completionHandler?(false)
|
||||
return
|
||||
}
|
||||
self.orderCode = orderModel.order_code
|
||||
self.payId = payId
|
||||
|
||||
self.iapManager.start(productId: productId, orderId: self.orderCode ?? "")
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//MARK: -------------- JXIAPManagerDelegate --------------
|
||||
extension SPIAPManager: JXIAPManagerDelegate {
|
||||
|
||||
func jx_iapPaySuccess(productId: String, receipt: String, transactionIdentifier: String?) {
|
||||
guard let orderCode = self.orderCode, let payId = self.payId else { return }
|
||||
|
||||
SPWalletAPI.requestVerifyOrder(orderCode: orderCode, payId: payId, productId: productId, purchaseToken: receipt) { model in
|
||||
SPHUD.dismiss()
|
||||
|
||||
if let model = model {
|
||||
self.orderCode = nil
|
||||
self.payId = nil
|
||||
|
||||
self.completionHandler?(true)
|
||||
} else {
|
||||
self.completionHandler?(false)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func jx_iapPayFailed(productId: String, code: JXIAPManagerCode) {
|
||||
self.orderCode = nil
|
||||
self.payId = nil
|
||||
SPHUD.dismiss()
|
||||
|
||||
if code == .noProduct {
|
||||
SPToast.show(text: "Invalid in-app purchase".localized)
|
||||
}
|
||||
|
||||
self.completionHandler?(false)
|
||||
}
|
||||
|
||||
}
|
@ -78,6 +78,7 @@
|
||||
"VIP Record" = "VIP Record";
|
||||
"Signout" = "Signout";
|
||||
"Confirm logout?" = "Confirm logout?";
|
||||
"Invalid in-app purchase" = "Invalid in-app purchase";
|
||||
|
||||
|
||||
"kLoginAgreementText" = "By continuing, you agree to the User Agreement and Privacy Policy";
|
||||
|
17
MoviaBox/Thirdparty/JXIAPManager/SPIAPOrderModel.swift
vendored
Normal file
17
MoviaBox/Thirdparty/JXIAPManager/SPIAPOrderModel.swift
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// SPIAPOrderModel.swift
|
||||
// MoviaBox
|
||||
//
|
||||
// Created by 佳尔 on 2025/5/6.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SmartCodable
|
||||
|
||||
class SPIAPOrderModel: SPModel, SmartCodable {
|
||||
|
||||
|
||||
var order_code: String?
|
||||
var money: String?
|
||||
var is_backhaul: String?
|
||||
}
|
17
MoviaBox/Thirdparty/JXIAPManager/SPIAPVerifyModel.swift
vendored
Normal file
17
MoviaBox/Thirdparty/JXIAPManager/SPIAPVerifyModel.swift
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// SPIAPVerifyModel.swift
|
||||
// MoviaBox
|
||||
//
|
||||
// Created by 佳尔 on 2025/5/6.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SmartCodable
|
||||
|
||||
class SPIAPVerifyModel: SPModel, SmartCodable {
|
||||
|
||||
var status: String?
|
||||
var money: String?
|
||||
var is_backhaul: String?
|
||||
|
||||
}
|
3
Podfile
3
Podfile
@ -31,4 +31,7 @@ target 'MoviaBox' do
|
||||
pod 'WMZPageController' #分页控制器
|
||||
pod 'SVProgressHUD' #HUD
|
||||
pod 'TZImagePickerController' #相册
|
||||
# pod 'FBSDKCoreKit' # Facebook 基础
|
||||
# pod 'FBSDKLoginKit' # Facebook 登录
|
||||
|
||||
end
|
||||
|
@ -88,6 +88,6 @@ SPEC CHECKSUMS:
|
||||
YYKit: 7cda43304a8dc3696c449041e2cb3107b4e236e7
|
||||
ZFPlayer: 5cf39e8d9f0c2394a014b0db4767b5b5a6bffe13
|
||||
|
||||
PODFILE CHECKSUM: a4a45c34f6f8f83641e2b23364c97c871ca84221
|
||||
PODFILE CHECKSUM: 38415be06361089ed99017f8e3cdad9bd57ec94a
|
||||
|
||||
COCOAPODS: 1.16.2
|
||||
|
Loading…
x
Reference in New Issue
Block a user