diff --git a/MoviaBox.xcodeproj/project.pbxproj b/MoviaBox.xcodeproj/project.pbxproj index 90c0521..8246bd4 100644 --- a/MoviaBox.xcodeproj/project.pbxproj +++ b/MoviaBox.xcodeproj/project.pbxproj @@ -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" */; diff --git a/MoviaBox.xcworkspace/xcshareddata/swiftpm/Package.resolved b/MoviaBox.xcworkspace/xcshareddata/swiftpm/Package.resolved index c0978d8..a525953 100644 --- a/MoviaBox.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/MoviaBox.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -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", diff --git a/MoviaBox/AppDelegate/AppDelegate+OpenApp.swift b/MoviaBox/AppDelegate/AppDelegate+OpenApp.swift index 2d52257..09f2b84 100644 --- a/MoviaBox/AppDelegate/AppDelegate+OpenApp.swift +++ b/MoviaBox/AppDelegate/AppDelegate+OpenApp.swift @@ -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 } diff --git a/MoviaBox/AppDelegate/AppDelegate.swift b/MoviaBox/AppDelegate/AppDelegate.swift index 1c32765..1cb99b4 100644 --- a/MoviaBox/AppDelegate/AppDelegate.swift +++ b/MoviaBox/AppDelegate/AppDelegate.swift @@ -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() ///注册消息通知 diff --git a/MoviaBox/Base/Networking/API/SPWalletAPI.swift b/MoviaBox/Base/Networking/API/SPWalletAPI.swift index 5163ac8..093e80a 100644 --- a/MoviaBox/Base/Networking/API/SPWalletAPI.swift +++ b/MoviaBox/Base/Networking/API/SPWalletAPI.swift @@ -17,7 +17,37 @@ class SPWalletAPI: NSObject { SPNetwork.request(parameters: param) { (response: SPNetworkResponse) 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) 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) in + completer?(response.data) + } } } diff --git a/MoviaBox/Class/Wallet/View/SPCoinRechargeCell.swift b/MoviaBox/Class/Wallet/View/SPCoinRechargeCell.swift index bd8aafe..ddb6903 100644 --- a/MoviaBox/Class/Wallet/View/SPCoinRechargeCell.swift +++ b/MoviaBox/Class/Wallet/View/SPCoinRechargeCell.swift @@ -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")" } diff --git a/MoviaBox/Class/Wallet/View/SPCoinRechargeView.swift b/MoviaBox/Class/Wallet/View/SPCoinRechargeView.swift index 2bad673..7f6f2e9 100644 --- a/MoviaBox/Class/Wallet/View/SPCoinRechargeView.swift +++ b/MoviaBox/Class/Wallet/View/SPCoinRechargeView.swift @@ -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?() + } + } } } diff --git a/MoviaBox/Libs/Login/SPLoginManager+Facebook.swift b/MoviaBox/Libs/Login/SPLoginManager+Facebook.swift index 03799ee..7c10cb8 100644 --- a/MoviaBox/Libs/Login/SPLoginManager+Facebook.swift +++ b/MoviaBox/Libs/Login/SPLoginManager+Facebook.swift @@ -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 } } diff --git a/MoviaBox/Libs/SPIAPManager/SPIAPManager.swift b/MoviaBox/Libs/SPIAPManager/SPIAPManager.swift new file mode 100644 index 0000000..c45fa57 --- /dev/null +++ b/MoviaBox/Libs/SPIAPManager/SPIAPManager.swift @@ -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) + } + +} diff --git a/MoviaBox/Source/en.lproj/Localizable.strings b/MoviaBox/Source/en.lproj/Localizable.strings index b3f5258..15b4970 100644 --- a/MoviaBox/Source/en.lproj/Localizable.strings +++ b/MoviaBox/Source/en.lproj/Localizable.strings @@ -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"; diff --git a/MoviaBox/Thirdparty/JXIAPManager/SPIAPOrderModel.swift b/MoviaBox/Thirdparty/JXIAPManager/SPIAPOrderModel.swift new file mode 100644 index 0000000..d89756b --- /dev/null +++ b/MoviaBox/Thirdparty/JXIAPManager/SPIAPOrderModel.swift @@ -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? +} diff --git a/MoviaBox/Thirdparty/JXIAPManager/SPIAPVerifyModel.swift b/MoviaBox/Thirdparty/JXIAPManager/SPIAPVerifyModel.swift new file mode 100644 index 0000000..e0b8a08 --- /dev/null +++ b/MoviaBox/Thirdparty/JXIAPManager/SPIAPVerifyModel.swift @@ -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? + +} diff --git a/Podfile b/Podfile index 98e19d1..6dbd20d 100644 --- a/Podfile +++ b/Podfile @@ -31,4 +31,7 @@ target 'MoviaBox' do pod 'WMZPageController' #分页控制器 pod 'SVProgressHUD' #HUD pod 'TZImagePickerController' #相册 +# pod 'FBSDKCoreKit' # Facebook 基础 +# pod 'FBSDKLoginKit' # Facebook 登录 + end diff --git a/Podfile.lock b/Podfile.lock index e1e43f4..417712e 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -88,6 +88,6 @@ SPEC CHECKSUMS: YYKit: 7cda43304a8dc3696c449041e2cb3107b4e236e7 ZFPlayer: 5cf39e8d9f0c2394a014b0db4767b5b5a6bffe13 -PODFILE CHECKSUM: a4a45c34f6f8f83641e2b23364c97c871ca84221 +PODFILE CHECKSUM: 38415be06361089ed99017f8e3cdad9bd57ec94a COCOAPODS: 1.16.2