gpt4 book ai didi

iOS 14 WidgetKit 在本地工作,但通过 TestFlight 失败

转载 作者:行者123 更新时间:2023-12-04 11:32:36 25 4
gpt4 key购买 nike

我有一个带有 WidgetKit 的 SwiftUI 应用程序。当我通过 Xcode 运行应用程序时(直接在我的设备上或在模拟器上), WidgetKit 完全按预期工作。
但是,当我通过 TestFlight 运行应用程序时, WidgetKit 确实出现了,但它没有显示任何数据——它只是一个空的占位符。该 WidgetKit 应该显示图像和一些文本,但它都不显示。
我在 Apple Developer 论坛上看到过一些关于类似问题的帖子。一个接受 answer说:

  • 确保在您的设备上使用 Xcode 12 beta 4 和 iOS 14 beta 4。确保您已实现占位符(in:)。确保您没有 placeholder(with:) 因为这是 Xcode 以前的 beta 建议的自动完成功能,没有它,您将无法使用占位符。我认为这整个问题是由 WidgetKit 方法重命名引起的,但这是另一回事。
  • 根据发行说明,您需要在扩展目标的build设置中将“Dead Code Stripping”设置为 NO。这仅对扩展的目标是必需的。
  • 将存档上传到 App Store Connect 时,取消选中“包括 iOS 内容的位码”。
  • 安装新测试版时从设备中删除旧版本。

  • 我已经实现了这些建议,但无济于事。
    这是我的 WidgetKit 代码。它首先通过 CloudKit 获取游戏数据,然后创建一个时间线:
    import WidgetKit
    import SwiftUI
    import CloudKit

    struct WidgetCloudKit {
    static var gameLevel: Int = 0
    static var gameScore: String = ""
    }


    struct Provider: TimelineProvider {
    private var container = CKContainer(identifier: "MyIdentifier")
    static var hasFetchedGameStatus: Bool = false


    func placeholder(in context: Context) -> SimpleEntry {
    return SimpleEntry(date: Date(), gameLevel: 0, gameScore: "0")
    }


    func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
    let entry: SimpleEntry

    if context.isPreview && !Provider.hasFetchedGameStatus {
    entry = SimpleEntry(date: Date(), gameLevel: 0, gameScore: "0")
    } else {
    entry = SimpleEntry(date: Date(), gameLevel: WidgetCloudKit.gameLevel, gameScore: WidgetCloudKit.gameScore)
    }
    completion(entry)
    }


    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
    let pred = NSPredicate(value: true)
    let sort = NSSortDescriptor(key: "creationDate", ascending: false)
    let q = CKQuery(recordType: "gameData", predicate: pred)
    q.sortDescriptors = [sort]

    let operation = CKQueryOperation(query: q)
    operation.desiredKeys = ["level", "score"]
    operation.resultsLimit = 1

    operation.recordFetchedBlock = { record in
    DispatchQueue.main.async {
    WidgetCloudKit.gameLevel = record.value(forKey: "level") as? Int ?? 0
    WidgetCloudKit.gameScore = String(record.value(forKey: "score") as? Int ?? 0)
    Provider.hasFetchedGameStatus = true

    var entries: [SimpleEntry] = []
    let date = Date()

    let entry = SimpleEntry(date: date, gameLevel: WidgetCloudKit.gameLevel, gameScore: WidgetCloudKit.gameScore)
    entries.append(entry)

    // Create a date that's 15 minutes in the future.
    let nextUpdateDate = Calendar.current.date(byAdding: .minute, value: 15, to: date)!
    let timeline = Timeline(entries: entries, policy: .after(nextUpdateDate))
    completion(timeline)
    }
    }

    operation.queryCompletionBlock = { (cursor, error) in
    DispatchQueue.main.async {
    if let error = error {
    print("queryCompletion error: \(error)")
    } else {
    if let cursor = cursor {
    print("cursor: \(cursor)")
    }
    }
    }
    }

    self.container.publicCloudDatabase.add(operation)
    }

    }

    struct SimpleEntry: TimelineEntry {
    var date: Date
    var gameLevel: Int
    var gameScore: String
    }

    struct WidgetEntryView : View {
    var entry: Provider.Entry

    var body: some View {
    GeometryReader { geo in
    VStack {
    Image("widgetImage")
    .resizable()
    .aspectRatio(contentMode: .fit)
    .frame(width: geo.size.width)
    HStack {
    VStack {
    Text("LEVEL")
    Text(entry.gameLevel == 0 ? "-" : "\(entry.gameLevel)")
    }
    VStack {
    Text("SCORE")
    Text(entry.gameScore == "0" ? "-" : entry.gameScore)
    }
    }
    }
    }
    }
    }

    @main
    struct Widget: SwiftUI.Widget {
    let kind: String = "MyWidget"

    var body: some WidgetConfiguration {
    StaticConfiguration(kind: kind, provider: Provider()) { entry in
    WidgetEntryView(entry: entry)
    }
    .configurationDisplayName("Game Status")
    .description("Shows an overview of your game status")
    .supportedFamilies([.systemSmall])
    }
    }
    问题:为什么我的 WidgetKit 在通过 TestFlight 分发时不工作?我有什么选择,在这里?
    谢谢!
    更新:
    如果我使用 unredacted() View 修饰符, WidgetKit 显示图像以及“LEVEL”和“SCORE”文本,但仍不显示任何实际数据。所以,我的 SwiftUI View 现在看起来像这样:
    struct WidgetEntryView : View {
    var entry: Provider.Entry

    var body: some View {
    GeometryReader { geo in
    VStack {
    Image("widgetImage")
    .resizable()
    .aspectRatio(contentMode: .fit)
    .frame(width: geo.size.width)
    HStack {
    VStack {
    Text("LEVEL")
    Text(entry.gameLevel == 0 ? "-" : "\(entry.gameLevel)")
    }
    VStack {
    Text("SCORE")
    Text(entry.gameScore == "0" ? "-" : entry.gameScore)
    }
    }
    }
    .unredacted() // <-- I added this
    }
    }
    }
    更新#2:
    在文章 Keeping A Widget Up To Date ,有一节讨论后台网络请求:

    When your widget extension is active, like when providing a snapshot or timeline, it can initiate background network requests. For example, a game widget that fetches your teammate’s current status, or a news widget that fetches headlines with image thumbnails. Making asynchronous background network requests let you return control to the system quickly, reducing the risk of being terminated for taking too long to respond.


    我是否需要设置这个(复杂的)后台请求范例才能使 CloudKit 为我的 WidgetKit 工作?我在正确的轨道上吗?

    最佳答案

    您是否尝试将 cloudkit 容器部署到生产环境?您可以在 CloudKit 仪表板上找到它。

    关于iOS 14 WidgetKit 在本地工作,但通过 TestFlight 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67482411/

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