不跟系统的暗黑模式,保持light模式;增加本地日志的读取;接入firebase

This commit is contained in:
oscarz
2024-08-29 18:01:49 +08:00
parent 6d6776b9fd
commit 8500300d18
34 changed files with 25575 additions and 1523 deletions

View File

@ -8,14 +8,26 @@
import SwiftUI
import TrustDecision
import Firebase
import FirebaseAnalytics
import FirebaseCrashlytics
@main
struct AIGrammarApp: App {
let persistenceController = PersistenceController.shared
init() {
//
setupLogging()
_ = InitApp.shared
// firebase
FirebaseApp.configure()
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)
//
// Crashlytics.crashlytics().log("Test crash")
// fatalError("Test crash from Crashlytics")
}
var body: some Scene {
@ -24,6 +36,7 @@ struct AIGrammarApp: App {
.environment(\.managedObjectContext, persistenceController.container.viewContext)
.environmentObject(IAPManager()) // IAPManager
.environmentObject(globalEnvironment) // IAPManager
.preferredColorScheme(.light) // 使
}
}

View File

@ -7,6 +7,7 @@
import SwiftUI
import ToastUI
import FirebaseAnalytics
fileprivate struct BuyProView: View {
var onTryForFree: () -> Void
@ -27,6 +28,12 @@ fileprivate struct BuyProView: View {
//
// VIP
onTryForFree()
//
Analytics.logEvent(globalAnalyticsEvents.eventEnterPurchase, parameters: [
globalAnalyticsEvents.keyPurchaseEntry: globalAnalyticsEvents.valEntryBuyProBtn as NSObject,
globalAnalyticsEvents.keyDeviceID: globalEnvironment.deviceID as NSObject
])
}
.padding(.vertical, 6) // 2/3
.padding(.horizontal, 20)

View File

@ -5,6 +5,7 @@
// Created by oscar on 2024/7/9.
//
import SwiftUI
import FirebaseAnalytics
struct VIPPaymentView: View {
@Environment(\.presentationMode) var presentationMode
@ -159,6 +160,13 @@ struct VIPPaymentView: View {
private func buyProduct() {
let productId = products[selectedProductIndex].4
logger.info("selected productId: \(productId.rawValue)")
//
Analytics.logEvent(globalAnalyticsEvents.eventPurchase, parameters: [
globalAnalyticsEvents.keyPurchaseItem: productId.rawValue as NSObject,
globalAnalyticsEvents.keyDeviceID: globalEnvironment.deviceID as NSObject
])
if let product = iapManager.products.first(where: { $0.id == productId.rawValue }) {
Task {
await iapManager.buy(product: product) { result in

View File

@ -9,6 +9,8 @@ import SwiftUI
import ToastUI
import SafariServices
import FirebaseAnalytics
import SwiftyBeaver
struct FullScreenSafariView: UIViewControllerRepresentable {
let url: URL
@ -60,6 +62,8 @@ struct SettingsView: View {
@State private var useSandboxEnvironment = false
@State private var useDevelopmentEnvironment = false
@State private var showingLogShareSheet = false
@State private var logFileURL: URL?
var body: some View {
NavigationView {
@ -69,6 +73,12 @@ struct SettingsView: View {
settingItem(icon: "arrow.up.circle", text: "Upgrade to Premium", isBold: true)
.onTapGesture {
showVIPPaymentView = true
//
Analytics.logEvent(globalAnalyticsEvents.eventEnterPurchase, parameters: [
globalAnalyticsEvents.keyPurchaseEntry: globalAnalyticsEvents.valEntrySettingsBtn as NSObject,
globalAnalyticsEvents.keyDeviceID: globalEnvironment.deviceID as NSObject
])
}
// Feedback
@ -114,10 +124,31 @@ struct SettingsView: View {
VStack {
Toggle("Sandbox", isOn: $useSandboxEnvironment)
Toggle("TestEnv", isOn: $useDevelopmentEnvironment)
Button("Save") {
saveSettings()
showingAdvancedSettings = false
HStack {
Button("View Logs") {
if let logURL = getLogFileURL() {
if FileManager.default.fileExists(atPath: logURL.path) {
logger.info("Log file exists: \(logURL.path)")
self.logFileURL = logURL
self.showingLogShareSheet = true
} else {
logger.error("Log file does not exist.")
self.toastText = "Log file not found."
self.showingToast = true
}
} else {
self.toastText = "Log file not found."
self.showingToast = true
}
}
Spacer()
Button("Save") {
saveSettings()
showingAdvancedSettings = false
}
}
.padding(.horizontal,15)
.padding(.top, 15)
}
.padding(.vertical,10)
.padding(.horizontal, 20)
@ -135,6 +166,11 @@ struct SettingsView: View {
self.showingAdvancedSettings = false //
}
}
.sheet(isPresented: $showingLogShareSheet) {
if let url = logFileURL {
ShareSheetLog(activityItems: [url])
}
}
.toast(isPresented: $showingToast, dismissAfter: globalEnvironment.toastPresentMsNormal) {
HStack {
Image(systemName: "exclamationmark.bubble")
@ -152,12 +188,12 @@ struct SettingsView: View {
LoadingView()
}
}
//
private var gestureArea: some View {
Color.clear
.contentShape(Rectangle()) //
.frame(height: 150) //
.frame(height: 50) //
.gesture(
DragGesture(minimumDistance: 50, coordinateSpace: .global)
.onEnded { value in
@ -229,6 +265,20 @@ struct SettingsView: View {
}
struct ShareSheetLog: UIViewControllerRepresentable {
var activityItems: [Any]
func makeUIViewController(context: Context) -> UIActivityViewController {
let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
return controller
}
func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {
// Nothing to update here
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()

View File

@ -88,3 +88,20 @@ class GlobalEnvironment: ObservableObject {
//
let globalEnvironment = GlobalEnvironment()
class GlobalAnalyticsEvents: ObservableObject {
let eventPurchase = "purchase"
let eventEnterPurchase = "enter_purchase_page"
let keyPurchaseEntry = "purchase_entry_point"
let keyPurchaseItem = "purchase_product_id"
let keyDeviceID = "device_id"
let valEntryBuyProBtn = "buy_pro_btn"
let valEntrySettingsBtn = "settings_buy_btn"
}
let globalAnalyticsEvents = GlobalAnalyticsEvents()

View File

@ -28,6 +28,7 @@ func setupLogging() {
console.format = "$DHH:mm:ss$d $C$L$c $N.$F:$l - $M"
file.format = "$Dyyyy-MM-dd HH:mm:ss.SSS$d $C$L$c $N.$F:$l - $M"
//
console.levelColor.verbose = "⚪️ " // White
@ -41,3 +42,12 @@ func setupLogging() {
}
//
func getLogFileURL() -> URL? {
return logger.destinations
.compactMap { $0 as? FileDestination }
.first?.logFileURL // FileDestinationURL
}