ios - 在 SwiftUI 2.0 中更改应用程序图标时发生 fatal error

标签 ios swift swiftui

我正在尝试允许用户在我的应用程序中自定义应用程序图标。我找到了在 SwiftUI 1.0(旧生命周期)中执行此操作的教程,并尝试使其在新生命周期中工作。我特别使用了 this tutorial 。我收到 fatal error fatal error :找不到 IconNames 类型的 ObservableObject。 IconNames 的 View.environmentObject(_:) 作为此 View 的祖先可能会丢失。

首先,我使用以下内容更新了我的 info.plist 文件

<key>CFBundleIcons</key>
<dict>
    <key>CFBundlePrimaryIcon</key>
    <dict>
        <key>CFBundleIconName</key>
        <string></string>
        <key>CFBundleIconFiles</key>
        <array>
            <string></string>
        </array>
        <key>UIPrerenderedIcon</key>
        <false/>
    </dict>
    <key>CFBundleAlternateIcons</key>
    <dict>
        <key>Dark</key>
        <dict>
            <key>CFBundleIconFiles</key>
            <array/>
            <key>Item 0</key>
            <string>Dark</string>
        </dict>
    </dict>
</dict>

然后,我将以下代码添加到我的设置页面(我在内容 View 中通过导航链接导航到的页面。

import SwiftUI

struct Settings: View {
    @EnvironmentObject var iconSettings : IconNames
    
    var body: some View {
        Form{
            Section{
                Picker(selection: $iconSettings.currentIndex, label: Text("App icon")){
                    ForEach(0 ..< iconSettings.iconNames.count){ i in
                        HStack{
                            Text(self.iconSettings.iconNames[i] ?? "AppIcon")
                            Image(uiImage: UIImage(named: self.iconSettings.iconNames[i] ?? "AppIcon") ?? UIImage())
                                .resizable()
                                .renderingMode(.original)
                                .frame(width: 50, height: 50, alignment: .leading)
                        }
                    }
                }.onReceive([self.iconSettings.currentIndex].publisher.first()) { (value) in
                    
                    let index = self.iconSettings.iconNames.firstIndex(of: UIApplication.shared.alternateIconName) ?? 0

                    if index != value{

                        UIApplication.shared.setAlternateIconName(self.iconSettings.iconNames[value]){ error in
                            if let error = error {
                                print(error.localizedDescription)
                            } else {
                                print("Success!")
                            }
                        }
                    }
                }
            }
        }
        .navigationTitle("Settings")
    }
}


class IconNames: ObservableObject {
    var iconNames: [String?] = [nil]
    @Published var currentIndex = 0
    init() {
        getAlternateIcons()
        
        if let currentIcon = UIApplication.shared.alternateIconName{
            self.currentIndex = iconNames.firstIndex(of: currentIcon) ?? 0
        }
    }
    func getAlternateIcons() {
        if let icons = Bundle.main.object(forInfoDictionaryKey: "CFBundleIcons") as? [String : Any], let alternateIcons = icons["CFBundleAlternateIcons"] as? [String: Any] {
            
            for (_, value) in alternateIcons{

                guard let iconList = value as? Dictionary<String,Any> else{return}
                guard let iconFiles = iconList["CFBundleIconFiles"] as? [String]
                    else{return}
                    
                guard let icon = iconFiles.first else{return}
                iconNames.append(icon)
   
            }
        }
    }
}

最佳答案

您必须提供 environmentObject 来代替 Settings View 创建,例如

Settings().environmentObject(IconNames())

关于ios - 在 SwiftUI 2.0 中更改应用程序图标时发生 fatal error ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65093726/

相关文章:

ios - SwiftUI - 在 iPadOS 和 Catalyst 上使用 onTapGesture 和鼠标/触控板出现意外行为

ios - iOS 旋转后 subview Controller 高度为零

ios - 苹果推送通知希伯来语

iOS:如何从 Swift 文件中的 Constant.h ObjC 获取#define?

ios - 写入文件 : How to write multiple data in a csv (or any) file?

ios - 如何从子viewController中的UITableView更新父 Controller 中UIScrollView的contentSize

ios - SwiftUI - 为什么当我在 macOS 上更改选项卡时 TabView 及其内容有时不刷新?

swift - 使用 Swift 登录 FB

ios - 使用 AudioEngine 的音效

ios - SwiftUI - 数据源为空时动态列表过滤动画飞到右侧