Commit e79bbfb5 authored by CZ1004's avatar CZ1004

Merge branch 'develop_0409' into charge

* develop_0409:
  内购
  4-8-2
parents eed9a6af 2584358c
......@@ -14,19 +14,19 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
0496DEFD2D9E3F59005B2834 /* PBXContainerItemProxy */ = {
0493223D2DA5314500E037A5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = EB388E532D8A61A800629B0D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 0496DEF12D9E3F57005B2834;
remoteInfo = widgetExtension;
remoteGlobalIDString = 041E01052DA3E865000F6C81;
remoteInfo = ChargeShow;
};
04D1E8032DA52AD10035D838 /* PBXContainerItemProxy */ = {
0496DEFD2D9E3F59005B2834 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = EB388E532D8A61A800629B0D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 041E01052DA3E865000F6C81;
remoteInfo = ChargeShow;
remoteGlobalIDString = 0496DEF12D9E3F57005B2834;
remoteInfo = widgetExtension;
};
/* End PBXContainerItemProxy section */
......@@ -70,19 +70,19 @@
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
0496DF032D9E3F59005B2834 /* Exceptions for "widget" folder in "widgetExtension" target */ = {
0493223E2DA531CC00E037A5 /* Exceptions for "ChargeShow" folder in "ChargeShow" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Info.plist,
);
target = 0496DEF12D9E3F57005B2834 /* widgetExtension */;
target = 041E01052DA3E865000F6C81 /* ChargeShow */;
};
04D1E8062DA52C000035D838 /* Exceptions for "ChargeShow" folder in "ChargeShow" target */ = {
0496DF032D9E3F59005B2834 /* Exceptions for "widget" folder in "widgetExtension" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Info.plist,
);
target = 041E01052DA3E865000F6C81 /* ChargeShow */;
target = 0496DEF12D9E3F57005B2834 /* widgetExtension */;
};
EB388E6D2D8A61AA00629B0D /* Exceptions for "PhoneManager" folder in "PhoneManager" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
......@@ -97,7 +97,7 @@
041E01082DA3E865000F6C81 /* ChargeShow */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
04D1E8062DA52C000035D838 /* Exceptions for "ChargeShow" folder in "ChargeShow" target */,
0493223E2DA531CC00E037A5 /* Exceptions for "ChargeShow" folder in "ChargeShow" target */,
);
path = ChargeShow;
sourceTree = "<group>";
......@@ -399,7 +399,7 @@
041E010D2DA3E865000F6C81 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 041E01052DA3E865000F6C81 /* ChargeShow */;
targetProxy = 04D1E8032DA52AD10035D838 /* PBXContainerItemProxy */;
targetProxy = 0493223D2DA5314500E037A5 /* PBXContainerItemProxy */;
};
0496DEFE2D9E3F59005B2834 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
......@@ -447,7 +447,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = 6K23946NQ5;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = ChargeShow/Info.plist;
......@@ -511,11 +511,9 @@
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_ENTITLEMENTS = widgetExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 6K23946NQ5;
DEVELOPMENT_TEAM = 6K23946NQ5;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = widget/Info.plist;
......@@ -531,7 +529,6 @@
PRODUCT_BUNDLE_IDENTIFIER = com.app.phonemanager.bswidget;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = phonemanager_widget_dev;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
......@@ -588,11 +585,9 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = PhoneManager/PhoneManager.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 6K23946NQ5;
DEVELOPMENT_TEAM = 6K23946NQ5;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = PhoneManager/Info.plist;
INFOPLIST_KEY_NSCameraUsageDescription = "We need camera access to access image storage information";
......@@ -613,7 +608,6 @@
PRODUCT_BUNDLE_IDENTIFIER = com.app.phonemanager;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = phonemanager_dev1;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "PhoneManager/Class/Tool/Class/OC/PhoneManager-Bridging-Header.h";
SWIFT_VERSION = 5.0;
......
......@@ -19,7 +19,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
window = UIWindow(frame: UIScreen.main.bounds)
window?.backgroundColor = UIColor.colorWithHex(hexStr: launchColor)
window?.overrideUserInterfaceStyle = .light
let Ssoryboard = UIStoryboard(name: "LauchVC", bundle: nil)
if let current = Ssoryboard.instantiateViewController(identifier: "LauchVCID") as? LauchVC {
......@@ -36,7 +36,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
private func setupDefault() {
HomePayModel.share.checkTrialStatus()
HomePayModel.share.loadLocalData()
NetStatusManager.manager.startNet { status in
switch status {
......
{
"images" : [
{
"filename" : "ic_idsp_unlock.png",
"filename" : "ic_unsel_com.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_idsp_unlock@2x.png",
"filename" : "ic_unsel_com@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_idsp_unlock@3x.png",
"filename" : "ic_unsel_com@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
......
{
"images" : [
{
"filename" : "icon_close__pingfen_pop.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "icon_close__pingfen_pop@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "icon_close__pingfen_pop@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_bj_quanxian.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_bj_quanxian@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_bj_quanxian@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_pro_quanxian.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_pro_quanxian@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_pro_quanxian@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_naal_unlock.png",
"filename" : "star_01.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_naal_unlock@2x.png",
"filename" : "star_01@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_naal_unlock@3x.png",
"filename" : "star_01@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
......
{
"images" : [
{
"filename" : "ic_sbst_unlock.png",
"filename" : "star_02.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_sbst_unlock@2x.png",
"filename" : "star_02@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_sbst_unlock@3x.png",
"filename" : "star_02@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
......
......@@ -287,6 +287,8 @@ class CompressQualityController : BaseViewController{
HomeNoAdsViewController.show {
actionBlock()
}
}else{
actionBlock()
}
}
......
......@@ -35,6 +35,7 @@ class LandingVC:UIViewController {
configureGradientView()
setupUI()
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
}
override func viewDidAppear(_ animated: Bool) {
......
......@@ -13,6 +13,15 @@ class HomePayModel: NSObject ,SKProductsRequestDelegate ,SKPaymentTransactionObs
static let share:HomePayModel = HomePayModel()
enum PayState {
case Subscribe // 订阅
case NonConsum // 非消耗型
}
var state:PayState = .Subscribe
private let productIdentifiers:[String] = ["com.app.phonemanager.year.member" , "com.app.phonemanager.lifetime.member"]
var isNoAd:Bool {
get {
guard let noabd = UserDefaults.standard.object(forKey: "noabd") as? Bool else { return false }
......@@ -25,11 +34,10 @@ class HomePayModel: NSObject ,SKProductsRequestDelegate ,SKPaymentTransactionObs
}
}
var storeCall:((_ product:SKProduct) -> Void) = { prod in }
var storeCall:((_ product:[SKProduct?]) -> Void) = { prod in }
func checkTrialStatus() -> Void {
public func loadLocalData() -> Void {
verifyReceiptWithApple { receipt in
self.alert.dismiss()
guard let json = receipt else {
self.refreshReceipt()
return
......@@ -43,45 +51,83 @@ class HomePayModel: NSObject ,SKProductsRequestDelegate ,SKPaymentTransactionObs
s.dateFormat = "yyyyMMdd HHmmss"
Print("ext : %@", s.string(from: extDate ?? Date()))
#endif
}else{
self.isNoAd = false
}
}
}
private func checkTrialStatus() -> Void {
if state == .Subscribe { // 订阅型
verifyReceiptWithApple { receipt in
self.alert.dismiss()
guard let json = receipt else {
self.refreshReceipt()
return
}
let sub = self.checkSubscriptionStatus(receiptInfo: json)
if sub.0 == true {
let extDate = sub.2
self.isNoAd = true
#if DEBUG
let s = DateFormatter()
s.dateFormat = "yyyyMMdd HHmmss"
Print("ext : %@", s.string(from: extDate ?? Date()))
#endif
}else{
self.isNoAd = false
}
}
}else{
self.alert.dismiss()
self.isNoAd = true
}
}
func fetchProducts() {
let request = SKProductsRequest(productIdentifiers: ["com.app.phonemanager.year.member"])
let request = SKProductsRequest(productIdentifiers: Set(productIdentifiers))
request.delegate = self
request.start()
Print("获取商品信息")
}
var product:SKProduct?
private var product:[SKProduct?]?
/** 获取商品列表 */
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
let products = response.products
guard let product = products.first else {
return
}
DispatchQueue.main.async {
self.product = product
self.storeCall(product)
var ps:[SKProduct?] = [nil,nil]
if products.count >= 2 {
if products.first?.productIdentifier == productIdentifiers.first {
ps[0] = products.first
ps[1] = products.last
}else{
ps[1] = products.first
ps[0] = products.last
}
}else{
ps = products
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: {
self.product = ps
Print("获取商品信息成功")
self.storeCall(ps)
})
}
/** 购买 */
func purchase() -> Void {
guard let prod = product,
func purchase(_ states:PayState = .Subscribe) -> Void {
guard let p1 = product?.first,
let p2 = product?.last,
SKPaymentQueue.canMakePayments()
else { return }
let payment = SKPayment(product: prod)
self.state = states
let payment = SKPayment(product: states == .Subscribe ? p1! : p2!)
SKPaymentQueue.default().add(payment)
alert.show()
}
/** 恢复 */
func restore() -> Void {
func restore(_ states:PayState = .Subscribe) -> Void {
self.state = states
SKPaymentQueue.default().restoreCompletedTransactions()
alert.show()
}
......@@ -245,6 +291,11 @@ extension HomePayModel {
checkTrialStatus()
}
/** 恢复失败 */
func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: any Error) {
alert.dismiss()
}
/** 刷新收据 */
func refreshReceipt() {
let request = SKReceiptRefreshRequest()
......
......@@ -16,7 +16,7 @@ class HomePayViewController:UIViewController {
private var doneBlock:(()->Void) = {}
var currentProduct:SKProduct? {
var currentProduct:[SKProduct?]? {
didSet {
setPrice()
}
......@@ -26,12 +26,12 @@ class HomePayViewController:UIViewController {
super.viewDidLoad()
view.backgroundColor = .green
addViews()
HomePayModel.share.fetchProducts()
storeKeD()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
storeKeD()
HomePayModel.share.fetchProducts()
}
override func viewDidAppear(_ animated: Bool) {
......@@ -47,7 +47,6 @@ class HomePayViewController:UIViewController {
guard let self else {return}
if let operstatus = status as? OperStatus {
switch operstatus {
case .close:
self.dismiss(animated: true)
......@@ -58,7 +57,6 @@ class HomePayViewController:UIViewController {
}
if let commonPush = status as? CommonPush {
switch commonPush {
case .pp:
self.ppClick()
......@@ -68,7 +66,7 @@ class HomePayViewController:UIViewController {
self.payTouch()
break
case .swit:
self.disjunctorTouch()
break
case .restore:
self.restoreClick()
......@@ -77,31 +75,29 @@ class HomePayViewController:UIViewController {
}
}
}
}
extension HomePayViewController {
private func setPrice() -> Void {
guard currentProduct != nil else { return }
homePayView?.product = currentProduct
guard currentProduct != nil ,
let p1 = currentProduct?.first,
let p2 = currentProduct?.last
else { return }
homePayView?.product = p1
homePayView?.product1 = p2
}
private func storeKeD() -> Void {
HomePayModel.share.storeCall = {[weak self] product in
HomePayModel.share.storeCall = {[weak self] products in
guard let self = self else { return }
self.currentProduct = product
self.currentProduct = products
}
}
private func disjunctorTouch() -> Void {
self.disjunctor = !self.disjunctor
setPrice()
}
private func payTouch() -> Void {
HomePayModel.share.purchase()
HomePayModel.share.purchase( (homePayView?.type == 0) ? .Subscribe : .NonConsum )
}
private func ppClick() {
......
......@@ -144,7 +144,7 @@ class SecretViewController: BaseViewController {
}
secretDesc.snp.makeConstraints { make in
make.left.equalTo(secretTL.snp.left)
make.top.equalTo(secretTL.snp.bottom).offset(2)
make.top.equalTo(secretTL.snp.bottom).offset(12)
}
secretLock.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-28)
......
......@@ -852,6 +852,7 @@ class SecretPhotoManager: NSObject, PhotoPickerControllerDelegate , CameraContro
if type == 0 {
let config = CameraConfiguration()
let vc = CameraController(config: config, type: .all, delegate: self)
vc.modalPresentationStyle = .overFullScreen
guard let root = cWindow?.rootViewController else { return }
root.present(vc, animated: true)
}else{
......@@ -859,6 +860,7 @@ class SecretPhotoManager: NSObject, PhotoPickerControllerDelegate , CameraContro
config.selectMode = .multiple
config.maximumSelectedCount = 4
let vc = PhotoPickerController(picker: config, delegate: self)
vc.modalPresentationStyle = .overFullScreen
guard let root = cWindow?.rootViewController else { return }
root.present(vc, animated: true)
}
......
......@@ -40,7 +40,12 @@ class PMAlertView: UIViewController {
func show() -> Void {
DispatchQueue.main.async {
guard let rt = UIViewController.topMostViewController() else { return }
Print("显示弹窗")
guard let rt = UIViewController.topMostViewController()
else { return }
if let vc = rt as? PMAlertView {
return
}
self.modalPresentationStyle = .overFullScreen
self.modalTransitionStyle = .crossDissolve
rt.present(self, animated: true)
......@@ -49,6 +54,7 @@ class PMAlertView: UIViewController {
func dismiss() -> Void {
DispatchQueue.main.async {
Print("关闭弹窗")
self.dismiss(animated: true)
}
}
......
//
// PMButton.swift
// PhoneManager
//
// Created by edy on 2025/4/8.
//
import UIKit
class PMButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
self.layer.cornerRadius = 12
self.clipsToBounds = true
}
var isSelect:Bool = false {
didSet {
if isSelect {
self.layer.borderColor = UIColor.colorWithHex(hexStr: "#266BFF").cgColor
self.layer.borderWidth = 1
self.gradient(colors: [UIColor.colorWithHex(hexStr: "#FFFFFF"),UIColor.colorWithHex(hexStr: "#E3E9FC")])
}else{
self.layer.borderColor = UIColor.clear.cgColor
self.layer.borderWidth = 0
self.gradient(colors: [.clear])
}
}
}
var labels : [UILabel] = []
func setTitles(_ titles: [String] ) {
if labels.count == titles.count {
for i in 0..<titles.count {
let lb:UILabel = labels[i]
lb.text = titles[i]
}
return
}
if titles.count > 1 {
let t = UILabel()
t.text = titles[0]
t.textColor = .colorWithHex(hexStr: "#333333")
t.font = UIFont.boldSystemFont(ofSize: 16)
self.addSubview(t)
t.snp.makeConstraints { make in
make.left.equalToSuperview().offset(10)
make.bottom.equalTo(self.snp.centerY).offset(-2)
}
let b = UILabel()
b.text = titles[1]
b.textColor = .colorWithHex(hexStr: "#666666")
b.font = UIFont.boldSystemFont(ofSize: 12)
addSubview(b)
b.snp.makeConstraints { make in
make.left.equalToSuperview().offset(10)
make.top.equalTo(self.snp.centerY)
}
labels.append(t)
labels.append(b)
}else if titles.count == 1 {
let t = UILabel()
t.text = titles[0]
t.textColor = .colorWithHex(hexStr: "#333333")
t.font = UIFont.boldSystemFont(ofSize: 16)
self.addSubview(t)
t.snp.makeConstraints { make in
make.left.equalToSuperview().offset(10)
make.centerY.equalToSuperview()
}
labels.append(t)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
......@@ -8,6 +8,7 @@
import UIKit
class PMPageControl: UIPageControl {
private let activeWidth: CGFloat = 16.0
private let inactiveWidth: CGFloat = 8.0
private let dotSpacing: CGFloat = 8.0
......@@ -15,6 +16,7 @@ class PMPageControl: UIPageControl {
override func layoutSubviews() {
super.layoutSubviews()
// for (index, dot) in subviews.enumerated() {
// Print("Page : %d",index)
// let isCurrentPage = index == currentPage
// let targetWidth = isCurrentPage ? activeWidth : inactiveWidth
// let previousDotsWidth = CGFloat(index) * (inactiveWidth + dotSpacing)
......
//
// yQzSnStarView.swift
// PhoneManager
//
// Created by edy on 2025/4/9.
//
import UIKit
class yQzSnStarView: UIView {
var maxStar = 5 {
didSet {
reloadView()
}
}
var spacing:CGFloat = 5 {
didSet {
starStack.spacing = self.spacing
}
}
var axis:NSLayoutConstraint.Axis = .vertical {
didSet {
starStack.axis = axis
}
}
var currentStar = 5 {
didSet {
reloadView()
}
}
private func reloadView() -> Void {
for v in starStack.arrangedSubviews {
starStack.removeArrangedSubview(v)
}
for i in 0..<maxStar {
let iconName = i < currentStar ? "star_01" : "star_02"
let icon = UIImageView(image: UIImage(named: iconName))
icon.contentMode = .scaleToFill
starStack.addArrangedSubview(icon)
icon.snp.makeConstraints { make in
make.width.equalTo(icon.snp.height)
}
}
}
private func setupUI() -> Void {
starStack.snp.makeConstraints { make in
make.left.top.bottom.right.equalToSuperview()
}
}
private lazy var starStack: UIStackView = {
let star = UIStackView()
star.axis = .horizontal
star.spacing = 5
star.alignment = .center
star.distribution = .fillEqually
addSubview(star)
return star
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
......@@ -6,6 +6,8 @@
//
import UIKit
import StoreKit
extension UIView {
......@@ -244,3 +246,16 @@ extension Date {
}
}
extension SKProduct {
var localizedPrice: String {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = priceLocale
formatter.maximumFractionDigits = 2
guard let priceNumber:NSNumber = price as? NSNumber else {
return ""
}
return formatter.string(from: priceNumber) ?? ""
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment