У меня есть проект SwiftUI-Firebase, и я использую делегат приложения для обработки push-уведомлений. На стороне клиента создается токен регистрации облачного обмена сообщениями, который я хотел бы сохранить в firestore вместе с идентификатором пользователя и другими метаданными.
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
tokenData = [
"token": fcmToken ?? ""
]
// Store token in firestore for sending notifications from server in future...
print("dataDict: \(tokenData)")
}
}
Итак, мне нужно получить tokenData, пользовательские метаданные, упаковать их в пользовательский объект и, наконец, сохранить в firestore. Я делаю это, сначала создавая tokenModel:
struct FCMToken: Codable, Identifiable {
@DocumentID var id: String? = UUID().uuidString
var userID: String?
var token: String
var createdAt: Date
enum CodingKeys: String, CodingKey {
case userID
case token
case createdAt
}
}
И затем я хотел бы передать tokenData из делегата в мой HomeView(), чтобы я мог проверить, вошел ли пользователь в систему:
@main
struct erisApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
WindowGroup {
HomeView(fcmTokenData: delegate.tokenData)
}
}
}
Если это так, я могу вызвать метод firestore внутри HomeView() для хранения моих данных tokenData. Проблема в том, что я не могу извлечь этот tokenData из делегата. Мне довольно удобно работать со SwiftUI, но я совершенно не знаком с UIKit, шаблоном Protocol-Delegate и так далее. Может ли кто-нибудь подсказать мне, как достичь желаемого результата?
Спасибо.
Чтобы получить свойства AppDelegate в SwiftUI, используйте @UIApplicationDelegateAdaptor с протоколом ObservableObject и оболочками @Published и @EnvironmentObject, как описано в Apple Docs здесь.
Добавьте протокол ObservableObject в свой класс AppDelegate. Затем объявите tokenData как @Published. Это предполагает, что tokenData обновляется вашим расширением AppDelegate выше.
class AppDelegate: NSObject, UIApplicationDelegate, ObservableObject {
@Published var tokenData: [TokenData] = []
// application functions...
}
Добавьте @UIApplicationDelegateAdaptor в объявление приложения, как вы уже сделали, но измените HomeView следующим образом:
@main
struct erisApp: App {
@UIApplicationDelegateAdaptor var delegate: AppDelegate
var body: some Scene {
WindowGroup {
HomeView()
}
}
}
Настройте HomeView() с помощью @EnvironmentObject, а затем используйте delegate.tokenData по мере необходимости:
struct HomeView: View {
@EnvironmentObject var delegate: AppDelegate
var body: some View {
Text("Token Data: \(delegate.tokenData)")
}
}