diff --git a/ios/PushDeer-iOS/PushDeer/AppDelegate.swift b/ios/PushDeer-iOS/PushDeer/AppDelegate.swift index 1ac0cd1..1ee62d6 100644 --- a/ios/PushDeer-iOS/PushDeer/AppDelegate.swift +++ b/ios/PushDeer-iOS/PushDeer/AppDelegate.swift @@ -20,8 +20,12 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele application.registerForRemoteNotifications() Task { - // APP启动后要先调一个无用接口, 用于触发国行手机的网络授权弹框, 未授权前调的接口会直接失败. (提前触发网络授权弹窗) - _ = try await HttpRequest.fake() + let notFirstStart = UserDefaults.standard.bool(forKey: "PushDeer_notFirstStart") + if !notFirstStart { + // APP首次启动后要先调一个无用接口, 用于触发国行手机的网络授权弹框, 未授权前调的接口会直接失败. (提前触发网络授权弹窗) + _ = try await HttpRequest.fake() + UserDefaults.standard.set(true, forKey: "PushDeer_notFirstStart") + } } return true @@ -33,6 +37,10 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele AppState.shared.deviceToken = deviceTokenString } + func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { + print("didFailToRegisterForRemoteNotificationsWithError: ", error) + } + func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification) async -> UNNotificationPresentationOptions { print("willPresent:", notification.request.content.userInfo) Task { diff --git a/ios/PushDeer-iOS/PushDeer/Model/Result.swift b/ios/PushDeer-iOS/PushDeer/Model/Result.swift index 39c38ef..5ba7525 100644 --- a/ios/PushDeer-iOS/PushDeer/Model/Result.swift +++ b/ios/PushDeer-iOS/PushDeer/Model/Result.swift @@ -23,7 +23,7 @@ struct TokenContent: Codable{ struct UserInfoContent: Codable{ let id: Int let name: String - let email: String + let email: String? let apple_id: String let wechat_id: String? let level: Int diff --git a/ios/PushDeer-iOS/PushDeer/Service/AppState.swift b/ios/PushDeer-iOS/PushDeer/Service/AppState.swift index 3f6f01b..47e2089 100644 --- a/ios/PushDeer-iOS/PushDeer/Service/AppState.swift +++ b/ios/PushDeer-iOS/PushDeer/Service/AppState.swift @@ -20,7 +20,7 @@ class AppState: ObservableObject { /// key 列表 @Published var keys: [KeyItem] = [] /// 消息列表 -// @Published var messages: [MessageItem] = [] + // @Published var messages: [MessageItem] = [] /// 选中的 tab 下标 @Published var tabSelectedIndex: Int { didSet { @@ -79,13 +79,18 @@ class AppState: ObservableObject { } catch { print(error) + // 后端登录失败 + throw NSError(domain: NSLocalizedString("登录失败", comment: "AppleId登录失败时提示") + "\n\(error.localizedDescription)", code: -4, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("登录失败", comment: "AppleId登录失败时提示") + "(-4)\n\(error.localizedDescription)"]) } + } else { + // 非 Apple 登录凭证 + throw NSError(domain: NSLocalizedString("登录失败", comment: "AppleId登录失败时提示"), code: -3, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("登录失败", comment: "AppleId登录失败时提示") + "(-3)"]) } case let .failure(error): print(error) + // Apple 登录失败 + throw NSError(domain: NSLocalizedString("登录失败", comment: "AppleId登录失败时提示") + "\n\(error.localizedDescription)", code: -2, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("登录失败", comment: "AppleId登录失败时提示") + "(-2)\n\(error.localizedDescription)"]) } - // 登录失败 - throw NSError(domain: NSLocalizedString("登录失败", comment: "AppleId登录失败时提示"), code: -1, userInfo: nil) } } diff --git a/ios/PushDeer-iOS/PushDeer/Service/HttpRequest.swift b/ios/PushDeer-iOS/PushDeer/Service/HttpRequest.swift index 722495f..9563f3b 100644 --- a/ios/PushDeer-iOS/PushDeer/Service/HttpRequest.swift +++ b/ios/PushDeer-iOS/PushDeer/Service/HttpRequest.swift @@ -26,9 +26,9 @@ struct HttpRequest { continuation.resume(returning: content) } else if result.code == 80403 { AppState.shared.token = "" - continuation.resume(throwing: NSError(domain: result.error ?? NSLocalizedString("登录过期", comment: "token失效时提示"), code: result.code, userInfo: nil)) + continuation.resume(throwing: NSError(domain: result.error ?? NSLocalizedString("登录过期", comment: "token失效时提示"), code: result.code, userInfo: [NSLocalizedDescriptionKey: result.error ?? NSLocalizedString("登录过期", comment: "token失效时提示")])) } else { - continuation.resume(throwing: NSError(domain: result.error ?? NSLocalizedString("接口报错", comment: "接口报错时提示"), code: result.code, userInfo: nil)) + continuation.resume(throwing: NSError(domain: result.error ?? NSLocalizedString("接口报错", comment: "接口报错时提示"), code: result.code, userInfo: [NSLocalizedDescriptionKey: result.error ?? NSLocalizedString("接口报错", comment: "接口报错时提示")])) } } catch { print(error) diff --git a/ios/PushDeer-iOS/PushDeer/Service/Persistence.swift b/ios/PushDeer-iOS/PushDeer/Service/Persistence.swift index d91224d..2025e25 100644 --- a/ios/PushDeer-iOS/PushDeer/Service/Persistence.swift +++ b/ios/PushDeer-iOS/PushDeer/Service/Persistence.swift @@ -31,7 +31,9 @@ struct PersistenceController { * The store could not be migrated to the current model version. Check the error message to determine what the actual problem was. */ - fatalError("Unresolved error \(error), \(error.userInfo)") + // fatalError("Unresolved error \(error), \(error.userInfo)") + print("Unresolved error \(error), \(error.userInfo)") + HToast.showError("数据库初始化失败!\n\(error.localizedDescription)") } }) container.viewContext.automaticallyMergesChangesFromParent = true diff --git a/ios/PushDeer-iOS/PushDeer/View/Common/DeletableView.swift b/ios/PushDeer-iOS/PushDeer/View/Common/DeletableView.swift index 65a2ab9..e67e09d 100644 --- a/ios/PushDeer-iOS/PushDeer/View/Common/DeletableView.swift +++ b/ios/PushDeer-iOS/PushDeer/View/Common/DeletableView.swift @@ -42,7 +42,7 @@ struct DeletableView : View { DragGesture() .onChanged({ value in let width = value.translation.width - print("onChanged", width) +// print("onChanged", width) let endX = isShowDelete ? offsetMaxX : 0.0 if width < endX { offsetX = width - endX diff --git a/ios/PushDeer-iOS/PushDeer/View/Common/EditableText.swift b/ios/PushDeer-iOS/PushDeer/View/Common/EditableText.swift index ae9b91b..20720c7 100644 --- a/ios/PushDeer-iOS/PushDeer/View/Common/EditableText.swift +++ b/ios/PushDeer-iOS/PushDeer/View/Common/EditableText.swift @@ -25,8 +25,14 @@ struct EditableText: View { var body: some View { if #available(iOS 15.0, *) { - textField() - .submitLabel(.done) + Group { + // https://stackoverflow.com/questions/70506330/swiftui-app-crashes-with-different-searchbar-viewmodifier-on-ios-14-15/70603710#70603710 + // !!!: 用 Group 包起来, 并且再次检查, 是因为在 Xcode 13.2 上面有 bug, 造成老版本也会寻找 if 里面的新方法, 造成老版本奔溃. + if #available(iOS 15.0, *) { + textField() + .submitLabel(.done) + } + } } else { textField() } diff --git a/ios/PushDeer-iOS/PushDeer/View/DeviceItemView.swift b/ios/PushDeer-iOS/PushDeer/View/DeviceItemView.swift index c5d8e2c..8906b44 100644 --- a/ios/PushDeer-iOS/PushDeer/View/DeviceItemView.swift +++ b/ios/PushDeer-iOS/PushDeer/View/DeviceItemView.swift @@ -89,7 +89,10 @@ struct DeviceItemView: View { if deviceName.contains("mac") { return "macwindow" } - return "ipad.and.iphone" + if #available(iOS 15.0, *) { + return "ipad.and.iphone" + } + return "laptopcomputer.and.iphone" } } diff --git a/ios/PushDeer-iOS/PushDeer/View/LoginView.swift b/ios/PushDeer-iOS/PushDeer/View/LoginView.swift index 207993c..63c3b06 100644 --- a/ios/PushDeer-iOS/PushDeer/View/LoginView.swift +++ b/ios/PushDeer-iOS/PushDeer/View/LoginView.swift @@ -37,6 +37,7 @@ struct LoginView: View { // 获取成功去主页 } catch { showLoading = false + HToast.showError(error.localizedDescription) } } ) diff --git a/ios/PushDeer-iOS/PushDeer/View/MainView.swift b/ios/PushDeer-iOS/PushDeer/View/MainView.swift index b78e45e..39f5f5b 100644 --- a/ios/PushDeer-iOS/PushDeer/View/MainView.swift +++ b/ios/PushDeer-iOS/PushDeer/View/MainView.swift @@ -15,7 +15,11 @@ struct MainView: View { TabView.init(selection: $store.tabSelectedIndex) { DeviceListView() .tabItem { - Label("设备",systemImage: "ipad.and.iphone") + if #available(iOS 15.0, *) { + Label("设备",systemImage: "ipad.and.iphone") + } else { + Label("设备",systemImage: "laptopcomputer.and.iphone") + } } .tag(0) diff --git a/ios/PushDeer-iOS/PushDeer/View/MessageListView.swift b/ios/PushDeer-iOS/PushDeer/View/MessageListView.swift index 46f1111..282a110 100644 --- a/ios/PushDeer-iOS/PushDeer/View/MessageListView.swift +++ b/ios/PushDeer-iOS/PushDeer/View/MessageListView.swift @@ -14,7 +14,7 @@ struct MessageListView: View { @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \MessageModel.created_at, ascending: false)], animation: .default) private var messages: FetchedResults - + var body: some View { BaseNavigationView(title: "消息") { ScrollView { @@ -78,12 +78,16 @@ struct TestPushView: View { store.keys = try await HttpRequest.getKeys().keys } if let keyItem = store.keys.first { - _ = try await HttpRequest.push(pushkey: keyItem.key, text: testText, desp: "", type: "") - testText = "" - HToast.showSuccess(NSLocalizedString("推送成功", comment: "")) - let messageItems = try await HttpRequest.getMessages().messages - withAnimation(.easeOut) { - try? MessageModel.saveAndUpdate(messageItems: messageItems) + do { + _ = try await HttpRequest.push(pushkey: keyItem.key, text: testText, desp: "", type: "") + testText = "" + HToast.showSuccess(NSLocalizedString("推送成功", comment: "")) + let messageItems = try await HttpRequest.getMessages().messages + withAnimation(.easeOut) { + try? MessageModel.saveAndUpdate(messageItems: messageItems) + } + } catch { + HToast.showError(error.localizedDescription) } } else { HToast.showError(NSLocalizedString("推送失败, 请先添加一个Key", comment: "")) diff --git a/ios/PushDeer-iOS/PushDeer/View/SettingsView.swift b/ios/PushDeer-iOS/PushDeer/View/SettingsView.swift index 81e31dd..54787c1 100644 --- a/ios/PushDeer-iOS/PushDeer/View/SettingsView.swift +++ b/ios/PushDeer-iOS/PushDeer/View/SettingsView.swift @@ -15,7 +15,7 @@ struct SettingsView: View { var body: some View { BaseNavigationView(title: "设置") { VStack { - SettingsItemView(title: NSLocalizedString("登录为", comment: "") + " \(store.userInfo?.name ?? "--")", button: NSLocalizedString("退出", comment: "退出登录按钮上的文字")) { + SettingsItemView(title: NSLocalizedString("登录为", comment: "") + " " + userName(), button: NSLocalizedString("退出", comment: "退出登录按钮上的文字")) { store.token = "" } .padding(EdgeInsets(top: 18, leading: 20, bottom: 0, trailing: 20)) @@ -45,6 +45,18 @@ struct SettingsView: View { } } } + + func userName() -> String { + if let name = store.userInfo?.name { + if name.isEmpty { + return NSLocalizedString("苹果用户", comment: "") + } else { + return name + } + } else { + return "--" + } + } } struct SettingsView_Previews: PreviewProvider { diff --git a/ios/PushDeer-iOS/PushDeer/en.lproj/Localizable.strings b/ios/PushDeer-iOS/PushDeer/en.lproj/Localizable.strings index fe70404..66985d1 100644 --- a/ios/PushDeer-iOS/PushDeer/en.lproj/Localizable.strings +++ b/ios/PushDeer-iOS/PushDeer/en.lproj/Localizable.strings @@ -109,3 +109,4 @@ /* No comment provided by engineer. */ "自定义服务器" = "Custom server"; +"苹果用户" = "Apple User";