修改IAP及隐私条款相关。

This commit is contained in:
oscarz
2024-08-17 12:23:47 +08:00
parent 00fd0adf89
commit 6d6776b9fd
21 changed files with 57 additions and 44 deletions

View File

@ -723,7 +723,7 @@
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = EasyGrammar; INFOPLIST_KEY_CFBundleDisplayName = EasyGrammar;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
INFOPLIST_KEY_NSCameraUsageDescription = "用户拍照获取文本"; INFOPLIST_KEY_NSCameraUsageDescription = "Camera access is required to capture text for grammar and spelling correction.";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES;
@ -759,7 +759,7 @@
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = EasyGrammar; INFOPLIST_KEY_CFBundleDisplayName = EasyGrammar;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
INFOPLIST_KEY_NSCameraUsageDescription = "用户拍照获取文本"; INFOPLIST_KEY_NSCameraUsageDescription = "Camera access is required to capture text for grammar and spelling correction.";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -16,9 +16,9 @@ struct VIPPaymentView: View {
let freeValues = ["2 Times / Day", "2 Times / Day", "2 Times / Day"] let freeValues = ["2 Times / Day", "2 Times / Day", "2 Times / Day"]
let premiumValues = ["Unlimited", "Unlimited", "Unlimited"] let premiumValues = ["Unlimited", "Unlimited", "Unlimited"]
let products = [ let products = [
("Premium Weekly", "$4.99", "Billed Weekly", "weekly", IAPProduct.premiumFeature1), ("Weekly", "$4.99 / week", "Billed as one payment of $4.99", "weekly", IAPProduct.premiumFeature1, "Billed Weekly"),
("Premium Monthly", "$9.99 / month", "Billed Monthly", "monthly", IAPProduct.premiumFeature2), ("Monthly", "$9.99 / month", "Billed as one payment of $9.99", "monthly", IAPProduct.premiumFeature2, "Billed Monthly"),
("Premium Yearly", "$49.99 / year", "Billed Yearly", "yearly", IAPProduct.premiumFeature3) ("Annual", "$4.16 / month", "Billed as one payment of $49.99", "yearly", IAPProduct.premiumFeature3, "Billed Yearly")
] ]
@State private var selectedProductIndex: Int = 1 // @State private var selectedProductIndex: Int = 1 //
@ -74,44 +74,46 @@ struct VIPPaymentView: View {
} }
} }
ForEach(products.indices, id: \.self) { index in VStack(alignment: .leading) { // 使 VStack ForEach
Button(action: { ForEach(products.indices, id: \.self) { index in
// do someting Button(action: {
}) { // do someting
HStack { }) {
Image(systemName: selectedProductIndex == index ? "checkmark.circle.fill" : "circle") HStack() {
.foregroundColor(selectedProductIndex == index ? .green : .secondary) Image(systemName: selectedProductIndex == index ? "checkmark.circle.fill" : "circle")
.padding(.horizontal, 4) .foregroundColor(selectedProductIndex == index ? .green : .secondary)
.padding(.horizontal, 4)
VStack(alignment: .leading) { VStack(alignment: .leading) {
if products[index].0 == "Premium Yearly" { if products[index].0 == "Annual" {
// "Premium Yearly" // "Premium Yearly"
Text(products[index].0) + Text(" ⚡️") + Text(" 58% off") Text(products[index].0) + Text(" ⚡️") + Text(" 58% off")
.bold() .bold()
.foregroundColor(.red) // 使 .foregroundColor(.red) // 使
.font(.subheadline)
} else {
Text(products[index].0)
}
Text(products[index].1)
.font(.caption)
Text(products[index].2)
.font(.subheadline) .font(.subheadline)
} else {
Text(products[index].0)
} }
Text(products[index].1) .frame(maxWidth: .infinity, alignment: .leading) // 使 HStack
.font(.subheadline) }
.padding(.vertical, 10)
.background(self.selectedProductIndex == index ? Color.yellow : Color.clear)
.cornerRadius(5)
.padding(.horizontal, 20) //
.onTapGesture {
self.selectedProductIndex = index
self.selectedPlanText = products[index].5
} }
Spacer()
Text(products[index].2)
.font(.subheadline)
.foregroundColor(.secondary)
}
.padding(.vertical, 10)
.background(self.selectedProductIndex == index ? Color.yellow : Color.clear)
.cornerRadius(5)
.padding(.horizontal, 20) //
.onTapGesture {
self.selectedProductIndex = index
self.selectedPlanText = products[index].2
} }
.frame(maxWidth: .infinity, alignment: .leading) // 使 HStack
} }
} }
Spacer() .padding(.horizontal, 5) //
Button("Purchase") { Button("Purchase") {
// Handle purchase logic here // Handle purchase logic here
@ -125,7 +127,7 @@ struct VIPPaymentView: View {
.frame(minWidth: 0, maxWidth: .infinity) .frame(minWidth: 0, maxWidth: .infinity)
.shadow(radius: 2) // .shadow(radius: 2) //
.font(.headline) // .font(.headline) //
.padding(.top, 50) .padding(.top, 20)
Text((selectedPlanText ) + ", Cancel Anytime") Text((selectedPlanText ) + ", Cancel Anytime")
.font(.footnote) .font(.footnote)
@ -135,7 +137,7 @@ struct VIPPaymentView: View {
} }
.frame(maxWidth: .infinity, maxHeight: .infinity) .frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(.systemBackground)) .background(Color(.systemBackground))
.toast(isPresented: $showingToast, dismissAfter: 5.0, onDismiss: { .toast(isPresented: $showingToast, dismissAfter: globalEnvironment.toastPresentMsNormal, onDismiss: {
// Toast // Toast
presentationMode.wrappedValue.dismiss() // presentationMode.wrappedValue.dismiss() //
}) { }) {

View File

@ -53,6 +53,7 @@ struct SettingsView: View {
@EnvironmentObject var iapManager: IAPManager // IAPManager @EnvironmentObject var iapManager: IAPManager // IAPManager
@State private var showingFullSafari = false @State private var showingFullSafari = false
@State private var currentSafariURL = globalEnvironment.userTermsURL
@State private var showingAdvancedSettings = false // @State private var showingAdvancedSettings = false //
@ -78,10 +79,19 @@ struct SettingsView: View {
} }
// About // About
settingItem(icon: "info.circle", text: "About") settingItem(icon: "info.circle", text: "Terms of Use")
.onTapGesture { .onTapGesture {
// Code to show About View // Code to show About View
self.showingFullSafari = true self.showingFullSafari = true
currentSafariURL = globalEnvironment.userTermsURL
}
// About
settingItem(icon: "info.circle", text: "Privacy Policy")
.onTapGesture {
// Code to show About View
self.showingFullSafari = true
currentSafariURL = globalEnvironment.userPrivacyURL
} }
// Restore Purchases // Restore Purchases
@ -92,7 +102,7 @@ struct SettingsView: View {
} }
.fullScreenCover(isPresented: $showingFullSafari) { .fullScreenCover(isPresented: $showingFullSafari) {
FullScreenSafariView(url: URL(string: globalEnvironment.userTermsURL)!, onDismiss: { FullScreenSafariView(url: URL(string: currentSafariURL)!, onDismiss: {
self.showingFullSafari = false self.showingFullSafari = false
}) })
} }

View File

@ -54,7 +54,8 @@ class GlobalEnvironment: ObservableObject {
var jwtSecret: String = "mCTf-JhNRnhaaGJy_x" var jwtSecret: String = "mCTf-JhNRnhaaGJy_x"
var userTermsURL: String = "https://grammar.easyprompt8.com/about/" var userTermsURL: String = "https://grammar.easyprompt8.com/about/terms.html"
var userPrivacyURL: String = "https://grammar.easyprompt8.com/about/privacy.html"
// //
// var baseHost: String = "http://192.168.2.2:1080" // var baseHost: String = "http://192.168.2.2:1080"

View File

@ -111,8 +111,8 @@ class IAPManager: ObservableObject {
logger.error("User cancelled the purchase.") logger.error("User cancelled the purchase.")
DispatchQueue.main.async { DispatchQueue.main.async {
// //
completion(.failure(NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Purchase Cancelled"]))) // completion(.failure(NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Purchase Cancelled"])))
} }
case .pending: case .pending:
// //