chore: Initial clean commit

- Removed YuMi/Library/ (138 MB, not tracked)
- Removed YuMi/Resources/ (23 MB, not tracked)
- Removed old version assets (566 files, not tracked)
- Excluded Pods/, xcuserdata/ and other build artifacts
- Clean repository optimized for company server deployment
This commit is contained in:
edwinQQQ
2025-10-09 16:19:14 +08:00
commit a35a711be6
5582 changed files with 408913 additions and 0 deletions

View File

@@ -0,0 +1,227 @@
import UIKit
import StoreKit
@available(iOS 15.0, *)
typealias Transaction = StoreKit.Transaction
@available(iOS 15.0, *)
typealias RenewalInfo = StoreKit.Product.SubscriptionInfo.RenewalInfo
@available(iOS 15.0, *)
typealias RenewalState = StoreKit.Product.SubscriptionInfo.RenewalState
enum PIStoreError: Error {
//
case failedVerification
case noProduct
}
@objc public enum StoreConditionResult: Int64 { //
case start //
case pay //
case verifiedServer //
case userCancelled //
case pending //
case unowned
case noProduct //
case failedVerification //
}
@available(iOS 15.0, *)
public class PIIAPRegulate: NSObject {
public typealias KConditionBlock = (_ state :StoreConditionResult,_ param:Dictionary<String,Any>?) ->()
@objc public var ConditionBlock: KConditionBlock! //
var updateListenerTask: Task<Void, Error>? = nil //
var transactionMap :[String:Transaction] = [:]// Idmap
@objc public static let shared = PIIAPRegulate()
private override init() { // private
super.init()
self.updateListenerTask = listenForTransactions()
}
func triggerConditionBlock(_ state: StoreConditionResult, _ param: [String: Any]? = nil) {
if let ConditionBlock = ConditionBlock {
ConditionBlock(state, param)
}
}
// 退
@objc public func refunRequest(view: UIView,transactionId:UInt64) async {
do {
if let scene = await view.window?.windowScene{
_ = try await Transaction.beginRefundRequest(for:transactionId , in: scene)
}
}catch{
print("iap error")
}
}
//
@objc public func demandCommodityThing(productId:String, uuid: String) async throws {
triggerConditionBlock(.start)
do {
let list = [productId]
let storeProducts = try await Product.products(for: Set(list))
guard let product = storeProducts.first else {
// triggerConditionBlock(.noProduct)
throw PIStoreError.noProduct
}
_ = try await purchase(product, uuid)
} catch {
triggerConditionBlock(.noProduct)
throw PIStoreError.noProduct
}
}
//
private func purchase(_ product: Product, _ uuid: String) async throws -> Transaction? {
triggerConditionBlock(.pay)
guard let curUUID = UUID.init(uuidString: uuid) else{
triggerConditionBlock(.failedVerification)
return nil
}
let result = try await product.purchase(options: [.appAccountToken(curUUID)])
switch result {
case .success(let verification): //
return try await verifiedAndAccomplish(verification)
case .userCancelled: //
triggerConditionBlock(.userCancelled)
case .pending: //
triggerConditionBlock(.pending)
default:
triggerConditionBlock(.unowned)
}
return nil
}
//
func checkVerified<T>(_ result: VerificationResult<T>) throws -> T {
//Check whether the JWS passes StoreKit verification.
switch result {
case .unverified:
//StoreKit parses the JWS, but it fails verification.
triggerConditionBlock(.failedVerification)
throw PIStoreError.failedVerification
case .verified(let safe):
//The result is verified. Return the unwrapped value.
print("iap: verified success")
return safe
}
}
// &
func verifiedAndAccomplish(_ verification:VerificationResult<Transaction>) async throws -> Transaction?{
//Check whether the transaction is verified. If it isn't,
//this function rethrows the verification error.
let transaction = try checkVerified(verification)
// ~~~
let transactionId = try verification.payloadValue.id
// map
let key = String(transactionId)
transactionMap[key] = transaction
await uploadServer(for: key)
//
await transaction.finish()
print("iap: finish")
return transaction
}
/*All transactions
Latest transactions
Current entitlements
*/
func getAllBusiness(transactionId:String) async {
let transactionIntId = UInt64(transactionId)
for await result in Transaction.all {
do {
let tran = try checkVerified(result)
let resultId = try result.payloadValue.id
if transactionIntId == resultId {
await tran.finish()
break
}
} catch let error {
print("error:----\(error)")
}
}
}
//
// @objc public func verifyBusinessAccomplish(transaction:String) async {
// if(transactionMap[transaction] != nil){
// await transactionMap[transaction]!.finish()
// transactionMap.removeValue(forKey: transaction)
// print("verifyBusinessFinish end")
// }else {
// await getAllBusiness(transactionId: transaction)
// }
// }
@objc public func verifyBusinessAccomplish(transactionID: String, completionHandler: @escaping (Bool, Error?) -> Void) {
if let transaction = transactionMap[transactionID] {
Task {
await transaction.finish()
transactionMap.removeValue(forKey: transactionID)
completionHandler(true, nil) //
}
} else {
Task {
await getAllBusiness(transactionId: transactionID)
completionHandler(false, nil) //
}
}
}
@MainActor
func uploadServer(for transactionId:String) async {
let dic :Dictionary<String,String> = ["transactionId":transactionId]
triggerConditionBlock(.verifiedServer, dic)
}
//
func listenForTransactions() -> Task<Void, Error> {
return Task.detached {
for await result in Transaction.updates {
do {
let resultId = try result.payloadValue.id
if !self.transactionMap.keys.contains(String(resultId)) {
_ = try await self.verifiedAndAccomplish(result)
}
} catch {
//
print("Error: \(error)")
}
}
}
}
//广
func Promotion() async -> [SKProduct]?{
let promotion = SKProductStorePromotionController()
let prodicts = try? await promotion.promotionOrder()
return prodicts
}
//
deinit {
updateListenerTask?.cancel()
}
}