diff --git a/SwiftProject/SwiftProject.xcodeproj/project.pbxproj b/SwiftProject/SwiftProject.xcodeproj/project.pbxproj index 5021872..aacf403 100644 --- a/SwiftProject/SwiftProject.xcodeproj/project.pbxproj +++ b/SwiftProject/SwiftProject.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ 006B61CD2BBA4E3D003FCB49 /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 006B61CC2BBA4E3D003FCB49 /* UserInfo.swift */; }; 006B61CF2BBA5D0A003FCB49 /* MembershipVCConfigureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 006B61CE2BBA5D0A003FCB49 /* MembershipVCConfigureView.swift */; }; 006B61D12BBA5DB4003FCB49 /* MembershipProductView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 006B61D02BBA5DB4003FCB49 /* MembershipProductView.swift */; }; + 006B61D32BBAA938003FCB49 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 006B61D22BBAA938003FCB49 /* StoreKit.framework */; }; 009661F82BAD6C7100FCA65F /* CCSpaceAlbumFilterPopView2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009661F72BAD6C7100FCA65F /* CCSpaceAlbumFilterPopView2.swift */; }; 009661FA2BAD876200FCA65F /* PhotosUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 009661F92BAD876200FCA65F /* PhotosUI.framework */; }; 009661FC2BADB20D00FCA65F /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 009661FB2BADB20D00FCA65F /* CoreMotion.framework */; }; @@ -113,6 +114,7 @@ 006B61CC2BBA4E3D003FCB49 /* UserInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInfo.swift; sourceTree = ""; }; 006B61CE2BBA5D0A003FCB49 /* MembershipVCConfigureView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MembershipVCConfigureView.swift; sourceTree = ""; }; 006B61D02BBA5DB4003FCB49 /* MembershipProductView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MembershipProductView.swift; sourceTree = ""; }; + 006B61D22BBAA938003FCB49 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; 009661F72BAD6C7100FCA65F /* CCSpaceAlbumFilterPopView2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CCSpaceAlbumFilterPopView2.swift; sourceTree = ""; }; 009661F92BAD876200FCA65F /* PhotosUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PhotosUI.framework; path = System/Library/Frameworks/PhotosUI.framework; sourceTree = SDKROOT; }; 009661FB2BADB20D00FCA65F /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; @@ -217,6 +219,7 @@ AF478B032B577D51005C35A5 /* AVFoundation.framework in Frameworks */, 00EB2D052BA2D59000924D84 /* MessageUI.framework in Frameworks */, 1E277B76988DF1691E8E5A49 /* Pods_SwiftProject.framework in Frameworks */, + 006B61D32BBAA938003FCB49 /* StoreKit.framework in Frameworks */, AF2120D42B4E99FA00400B7F /* MobileCoreServices.framework in Frameworks */, 009661FA2BAD876200FCA65F /* PhotosUI.framework in Frameworks */, AF2120D62B4E9A0100400B7F /* Photos.framework in Frameworks */, @@ -378,6 +381,7 @@ 4D8F3A411661D600CD07B39B /* Frameworks */ = { isa = PBXGroup; children = ( + 006B61D22BBAA938003FCB49 /* StoreKit.framework */, 009661FB2BADB20D00FCA65F /* CoreMotion.framework */, 009661F92BAD876200FCA65F /* PhotosUI.framework */, 00EB2D042BA2D59000924D84 /* MessageUI.framework */, @@ -961,6 +965,7 @@ CURRENT_PROJECT_VERSION = 1.0; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 8DQD6BV6H9; + ENABLE_APP_SANDBOX = NO; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", "COCOAPODS=1", @@ -1012,6 +1017,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1.0; DEVELOPMENT_TEAM = 8DQD6BV6H9; + ENABLE_APP_SANDBOX = NO; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", "COCOAPODS=1", diff --git a/SwiftProject/SwiftProject.xcworkspace/xcuserdata/aaa.xcuserdatad/UserInterfaceState.xcuserstate b/SwiftProject/SwiftProject.xcworkspace/xcuserdata/aaa.xcuserdatad/UserInterfaceState.xcuserstate index de582b4..2ede001 100644 Binary files a/SwiftProject/SwiftProject.xcworkspace/xcuserdata/aaa.xcuserdatad/UserInterfaceState.xcuserstate and b/SwiftProject/SwiftProject.xcworkspace/xcuserdata/aaa.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/SwiftProject/SwiftProject/AppDelegate.swift b/SwiftProject/SwiftProject/AppDelegate.swift index f2b2c9b..daef3f7 100644 --- a/SwiftProject/SwiftProject/AppDelegate.swift +++ b/SwiftProject/SwiftProject/AppDelegate.swift @@ -39,12 +39,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // self.window?.makeKeyAndVisible() Analytics.logEvent("user_launch", parameters: ["type":"new"]) -// Crashlytics.crashlytics().log("test") -// exceptionLogWithData() + SKUPay.sharedInstance.requestProducts(productsIdentifiers: ["VPC00001","VPC00002","VPC00003"]) -// DispatchQueue.main.asyncAfter(deadline: .now() + 10) { -// fatalError("Crash was triggered") -// } return true } diff --git a/SwiftProject/SwiftProject/CCKit/SKUPay/SKUPay.swift b/SwiftProject/SwiftProject/CCKit/SKUPay/SKUPay.swift index e43060a..324dc98 100644 --- a/SwiftProject/SwiftProject/CCKit/SKUPay/SKUPay.swift +++ b/SwiftProject/SwiftProject/CCKit/SKUPay/SKUPay.swift @@ -6,6 +6,160 @@ // import Foundation -class SKUPay { +import StoreKit + +//MARK: - 将货币信息格式化为本地信息 +extension SKProduct { + var regularPrice: String? { + let formatter = NumberFormatter() + formatter.numberStyle = .currency + formatter.locale = self.priceLocale + return formatter.string(from: self.price) + } +} + + +class SKUPay:NSObject, SKRequestDelegate,SKProductsRequestDelegate,SKPaymentTransactionObserver { + static let sharedInstance:SKUPay = SKUPay() + var productRequest:SKProductsRequest? + var productsArr:[SKProduct] = []//存放请求到的商品条目,有效的商品 + var invalidProductIdentifiers:[String] = [] //存放已经无效(过期、被删除等)的商品 + var historyPaymentTransactions:[SKPaymentTransaction]? { + get { + let data = UserDefaults.standard.value(forKey: "kHistoryTransaction") + var hpt:[SKPaymentTransaction]? = nil + guard let dt = data else { + return nil + } + do { + hpt = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [SKPaymentTransaction.self], from: dt as! Data) as? [SKPaymentTransaction] + + } + catch { + print("本地历史交易信息解析失败....") + } + return hpt + } + + set{ + guard let nv = newValue else { + UserDefaults.standard.setValue(nil, forKey: "kHistoryTransaction") + UserDefaults.standard.synchronize() + return + } + do { + let data = try NSKeyedArchiver.archivedData(withRootObject: nv, requiringSecureCoding: false) + UserDefaults.standard.setValue(data, forKey: "kHistoryTransaction") + UserDefaults.standard.synchronize() + } + catch { + print("本地存储交易信息失败....") + } + + } + } + + override init() { + super.init() + print("初始化内购管理对象....") + SKPaymentQueue.default().add(self) + } + + deinit { + SKPaymentQueue.default().remove(self) + } + + //MARK: - 拉取商品信息 + func requestProducts(productsIdentifiers:[String]) { + let pitSet = Set(productsIdentifiers) + productRequest = SKProductsRequest(productIdentifiers: pitSet) + productRequest?.delegate = self + productRequest?.start() + + } + + //MARK: - 支付 + func pay(product:SKProduct) { + let payment = SKPayment(product: product) + SKPaymentQueue.default().add(payment) + } + + //MARK: - 恢复购买 + func restoreProducts() { + SKPaymentQueue.default().restoreCompletedTransactions() + + } + + + //MARK: - 验单 + func checkPay() { + //..... + } + + ////////////////////////////////////////Delegate/////////////////////////////////////////////////// + + //MARK: - SKProductsRequestDelegate 商品信息拉取回调 + func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse){ + self.productsArr.removeAll() + if !response.products.isEmpty { + print("恭喜,获取到了有效商品信息.....iap") + self.productsArr.append(contentsOf: response.products) + } + + self.invalidProductIdentifiers.removeAll() + if !response.invalidProductIdentifiers.isEmpty { + print("很遗憾,商品信息还未生效:\n\(response.invalidProductIdentifiers)") + self.invalidProductIdentifiers.append(contentsOf: response.invalidProductIdentifiers) + } + } + + + //MARK: - SKPaymentTransactionObserver 交易信息回调 + + // Sent when the transaction array has changed (additions or state changes). Client should check state of transactions and finish as appropriate. + func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]){ + if !transactions.isEmpty { + self.historyPaymentTransactions = transactions + + transactions.forEach { spt in + + } + } + } + + + // Sent when transactions are removed from the queue (via finishTransaction:). +// func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]){ +// +// } + + + // Sent when an error is encountered while adding transactions from the user's purchase history back to the queue. + func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error){ + + } + + + // Sent when all transactions from the user's purchase history have successfully been added back to the queue. + func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue){ +// queue.transactions + } + + // Sent when a user initiates an IAP buy from the App Store + func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment, for product: SKProduct) -> Bool{ + return true + } + + + func paymentQueueDidChangeStorefront(_ queue: SKPaymentQueue){ + + } + + + // Sent when entitlements for a user have changed and access to the specified IAPs has been revoked. + + func paymentQueue(_ queue: SKPaymentQueue, didRevokeEntitlementsForProductIdentifiers productIdentifiers: [String]){ + + } }