内购开发

This commit is contained in:
zeng 2025-05-06 15:09:27 +08:00
parent b5b55119f6
commit 65a0753c20
14 changed files with 197 additions and 38 deletions

View File

@ -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" */;

View File

@ -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",

View File

@ -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
}

View File

@ -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()
///

View File

@ -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)
}
}
}

View File

@ -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")"
}

View File

@ -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?()
}
}
}
}

View File

@ -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
}
}

View 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)
}
}

View File

@ -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";

View 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?
}

View 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?
}

View File

@ -31,4 +31,7 @@ target 'MoviaBox' do
pod 'WMZPageController' #分页控制器
pod 'SVProgressHUD' #HUD
pod 'TZImagePickerController' #相册
# pod 'FBSDKCoreKit' # Facebook 基础
# pod 'FBSDKLoginKit' # Facebook 登录
end

View File

@ -88,6 +88,6 @@ SPEC CHECKSUMS:
YYKit: 7cda43304a8dc3696c449041e2cb3107b4e236e7
ZFPlayer: 5cf39e8d9f0c2394a014b0db4767b5b5a6bffe13
PODFILE CHECKSUM: a4a45c34f6f8f83641e2b23364c97c871ca84221
PODFILE CHECKSUM: 38415be06361089ed99017f8e3cdad9bd57ec94a
COCOAPODS: 1.16.2