gpt4 book ai didi

firebase - iOS 14 WidgetKit + SwiftUI + Firebase?

转载 作者:行者123 更新时间:2023-12-03 13:31:23 27 4
gpt4 key购买 nike

我对 SwiftUI 和 Firebase 还是很陌生。最近,作为一个爱好,我一直在为我的学校开发一个应用程序。在 Xcode 12 发布后,我决定尝试一些新功能,例如 Widgets。但是,由于我的应用程序从 Firebase 获取数据,我遇到了一些问题。我最近的问题是这个“线程 1:”无法获取 FirebaseApp 实例。请在使用 Firestore 之前调用 FirebaseApp.configure()。我不完全确定将“FirebaseApp.configure()”放在哪里,因为 WidgetKit 没有 AppDelegate.swift。我的代码如下。
编辑:
我重新安排了我的代码,以便我现在从原始 iOS 应用程序数据模型中获取数据。因此,我没有在 WidgetKit Swift 文件中导入 Firebase。但是,我仍然收到相同的错误(“SendProcessControlEvent:toPid: 遇到错误:错误域=com.apple.dt.deviceprocesscontrolservice Code=8”和“-> 0x7fff5bb6933a <+10>: jae 0x7fff5bb69344 ; <+20> -线程 1:“无法获取 FirebaseApp 实例。请在使用 Firestore 之前调用 FirebaseApp.configure()”)。我还包含了@Wendy Liga 的代码,但我仍然遇到同样的错误。我的新代码如下:
iOS 应用数据模型

import Foundation
import SwiftUI
import Firebase
import FirebaseFirestore

struct Assessment: Identifiable {
var id:String = UUID().uuidString
var Subject:String
var Class:Array<String>
var Day:Int
var Month:String
var Title:String
var Description:String
var Link:String
var Crit:Array<String>
}

class AssessmentsViewModel:ObservableObject {
@Published var books = [Assessment]()

private var db = Firestore.firestore()

// Add assessment variables
@Published var AssessmentSubject:String = ""
//@Published var AssessmentClass:Array<String> = [""]
@Published var AssessmentDay:Int = 1
@Published var AssessmentMonth:String = "Jan"
@Published var AssessmentTitle:String = ""
@Published var AssessmentDescription:String = ""
@Published var AssessmentLink:String = ""
@Published var AssessmentCrit:Array<String> = [""]
@Published var AssessmentDate:Date = Date()

func fetchData() {
db.collection("AssessmentsTest").order(by: "date").addSnapshotListener { (QuerySnapshot, error) in
guard let documents = QuerySnapshot?.documents else {
print("No documents")
return
}

self.books = documents.map { (QueryDocumentSnapshot) -> Assessment in
let data = QueryDocumentSnapshot.data()

let Subject = data["subject"] as? String ?? ""
let Class = data["class"] as? Array<String> ?? [""]
let Day = data["day"] as? Int ?? 0
let Month = data["month"] as? String ?? ""
let Title = data["title"] as? String ?? ""
let Description = data["description"] as? String ?? ""
let Link = data["link"] as? String ?? ""
let Crit = data["crit"] as? Array<String> ?? [""]

return Assessment(Subject: Subject, Class: Class, Day: Day, Month: Month, Title: Title, Description: Description, Link: Link, Crit: Crit)
}
}
}

func writeData() {
let DateConversion = DateFormatter()
DateConversion.dateFormat = "DD MMMM YYYY"
let Timestamp = DateConversion.date(from: "20 June 2020")

db.collection("AssessmentsTest").document(UUID().uuidString).setData([
"subject": AssessmentSubject,
"month": AssessmentMonth,
"day": AssessmentDay,
"title": AssessmentTitle,
"description": AssessmentDescription,
"link": AssessmentLink,
"crit": AssessmentCrit,
"date": AssessmentDate
]) { err in
if let err = err {
print("Error writing document: \(err)")
} else {
print("Document successfully written!")
}
}
}
}

WidgetKit View
struct WidgetsMainView: View {

@ObservedObject private var viewModel = AssessmentsViewModel()

var body: some View {
HStack {
Spacer().frame(width: 10)
VStack(alignment: .leading) {
Spacer().frame(height: 10)

ForEach(self.viewModel.books) { Data in
HStack {
VStack {
Text(String(Data.Day))
.bold()
.font(.system(size: 25))
Text(Data.Month)
}
.padding(EdgeInsets(top: 16, leading: 17, bottom: 16, trailing: 17))
.background(Color(red: 114/255, green: 112/255, blue: 110/255))
.foregroundColor(Color.white)
.cornerRadius(10)

VStack(alignment: .leading, spacing: 0) {
Text("\(Data.Subject) Crit \(Data.Crit.joined(separator: " + "))")
.bold()
if Data.Title != "" {
Text(Data.Title)
} else {
Text(Data.Class.joined(separator: ", "))
}
}
.padding(.leading, 10)
}
}
.onAppear {
viewModel.books.prefix(2)
}

Spacer()
}
Spacer()
}
}
}
WidgetKit @main
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
return true
}
}

@main
struct AssessmentsWidget: Widget {

@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

private let kind: String = "Assessments Widget"

public var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider(), placeholder: PlaceholderView()) { entry in
AssessmentsWidgetEntryView(entry: entry)
}
.configurationDisplayName("Assessments Widget")
.description("Keep track of your upcoming assessments.")
.supportedFamilies([.systemMedium])
}
}

最佳答案

您的主应用程序需要将数据传递给您的扩展程序,这可以通过允许您的应用程序使用“应用程序组”功能来实现。 App Groups 所做的是,它创建了一个容器,您的应用可以在其中保存数据,以便您与应用扩展共享。因此,请按照以下步骤启用“应用程序组”。
1. 选择您的主要应用目标>签名和功能,然后点击+功能并选择“应用组”
enter image description here
2. 点击“+”添加新容器,并在分组后为其添加名称。示例:“group.com.widgetTest.widgetContainer”
enter image description here
在主应用程序上创建“应用程序组”后,您应该在“WidgetKit 扩展”目标上采取相同的步骤。这一次,您应该能够从主应用程序中选择您已经拥有的容器,而不是创建容器。你可以在 YouTube 上找到一个很好的视频,在这里 How to Share UserDefaults with app extensions 上很好地解释了这个过程。
我建议的下一步是创建一个 Swift 包或框架,并添加一个新的模型对象,这个模型对象是您将从主应用程序传递到 WidgetKit 扩展的模型对象。我选择了一个 Swift 包。
为此,请按照下列步骤操作:
1.文件>新建>Swift包
enter image description here
可以看到来自 WWDC19 的一个很好的视频 here
2. 在您的 Swift 包中,在“Sources”文件夹中,创建一个自定义模型,您将在主应用程序和 WidgetKit 扩展中使用它
enter image description here
使您的对象符合“可编码”并且它是公共(public)的。
重要 确保导入“Foundation”,以便在对对象进行解码/编码时,它会正确执行。
3. 将您的包添加到您的主应用程序和 WidgetKit 扩展

  • 选择您的应用程序的目标>常规>滚动到“框架、库和嵌入式内容”
  • 点击“+”并搜索您的包裹

  • enter image description here
  • 在您的 WidgetKit 扩展上执行相同的步骤

  • enter image description here
    现在,您需要做的就是在您将在主应用程序和 WidgetExtension 中创建自定义对象的文件中“导入”您的模块,然后在主应用程序上初始化您的共享对象并将其保存到 UserDefaults首先将对象编码为 JSON,然后将其保存到 UserDefaults(套件名称:group.com.widgetTest.widgetContainer)
    let mySharedObject = MySharedObject(name: "My Name", lastName: "My Last Name")

    do {
    let data = try JSONEncoder().encode(mySharedObject)

    /// Make sure to use your "App Group" container suite name when saving and retrieving the object from UserDefaults
    let container = UserDefaults(suiteName:"group.com.widgetTest.widgetContainer")
    container?.setValue(data, forKey: "sharedObject")

    /// Used to let the widget extension to reload the timeline
    WidgetCenter.shared.reloadAllTimelines()

    } catch {
    print("Unable to encode WidgetDay: \(error.localizedDescription)")
    }

    然后在您的 WidgetKit 扩展中,您想从 UserDefaults 中检索您的对象,对其进行解码,您应该一切顺利。
    简短回答
    下载您的 Firebase 数据,从该数据创建一个新对象,将其编码为 JSON,使用 UserDefaults 将其保存在您的容器中,从容器中检索扩展程序中的对象,对其进行解码并将其用于您的 WidgetKit 条目。当然,所有这些都是假设您遵循上述步骤。

    关于firebase - iOS 14 WidgetKit + SwiftUI + Firebase?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62618123/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com