微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我应该如何在 SwiftUI 中使用 UserDefaults 构建我的应用程序?

如何解决我应该如何在 SwiftUI 中使用 UserDefaults 构建我的应用程序?

免责声明:我是 IOS 开发的新手,正在慢慢学习基础知识。

我需要有关项目逻辑/结构的帮助,特别是围绕用户认值的使用。我正在开发一个从公共 API 获取文本的 IOS 项目。

应用的当前状态:

  • 用户打开应用,并在 HeaderView 上登陆。
  • HeaderView 从 API 获取新的文本。让我们称这个新文本为“当前文本”。用户可以点击标题,并在 DetailView 中阅读获取的“当前文本”的完整详细信息。
  • 然后,如果用户愿意,他可以从该 API 生成新的随机当前文本。这是通过 DetailView 按钮完成的。
  • 刷新管理器会检查 .onAppear 是否自上次加载后时间已经过了第二天早上 7 点。如果是这样,它会获取一个新的文本。
  • 用户可以通过点击“保存”按钮从 DetailView 保存当前文本。此当前文本存储在 CoreData 中,并显示在主页上的列表中。
  • 如果用户出于任何原因终止应用程序,例如向上滑动,当前文本不会保存到用户认值。 IE:如果用户在早上 9 点打开应用程序,读取文本但不保存,然后终止应用程序,在当天的第二次应用程序加载时,晚上 7 点,当前文本将不同.

这是我的问题:

  • 我想确保体验是一致的。如果用户终止应用程序,则更改当前文本是一个问题。
  • 如何在 fetch.getText() 上将当前文本保存到 UserDefaults,并删除之前存储的文本?

注意事项:

  • 我最终想开发一个显示“当前文本”的小部件。我了解小部件与 IOS 应用的通信是通过 @AppStorage 和 UserDefaults 完成的。

我的代码

数据模型:

import Foundation

struct Text: Codable,Hashable {
    let title,author: String
}

class FetchText: ObservableObject {
  // 1.
  @Published var Texts = [Text]()
     
    init() {
        getText()
    }
    
    func getText() {
        let url = URL(string: "API URL")!
        // 2.
        URLSession.shared.dataTask(with: url) {(data,response,error) in
            do {
                if let TextData = data {
                    // 3.
                    let decodedData = try JSONDecoder().decode([Text].self,from: TextData)
                    dispatchQueue.main.async {
                        self.Texts = decodedData
                    }
                } else {
                    print("No data")
                }
            } catch {
                print("Error")
            }
        }.resume()
    }
}

细节视图:

import SwiftUI

struct DetailViewNew: View {
    
    @Observedobject var fetch = FetchText()
    
    var currentDate = Text(Date().addingTimeInterval(600),style: .date)
    
    var body: some View {
        
        vstack {
            ScrollView {
                vstack (alignment: .leading) {
                    Text("Today's Text,\(currentDate)")
                    
                    if let Text = fetch.Texts.first {
                        Text("\(Text.title)")
                        Text("By \(Text.author)")
                    }else {
                        Spacer()
                    }
                }
            }
            Button(action: {fetch.getText()}) {Text("Get Next Text")}
            
            Button(action: {
                if let Text = fetch.Texts.first {
                    let add = SavedText(context: self.moc)
                    add.id = UUID()
                    add.title = "\(Text.title)"
                    add.author = "\(Text.author)"
                    add.date = Date().addingTimeInterval(600)
                    add.saved = self.saved
                    try? self.moc.save()
                }}) {Text("Store Text in Core Data")}
        }
    }
}

struct DetailViewNew_Previews: PreviewProvider {
    static var previews: some View {
        
        DetailViewNew()
        
    }
}

标题视图

import SwiftUI

struct HeaderView: View {
    
    @Observedobject var fetch = FetchText()

    var body: some View {
        
            vstack (alignment: .center,spacing: 0){
                
                if let Text = fetch.Texts.first {
                    Text("\(Text.title)")
                    Text("By \(Text.author)")
                }
                NavigationLink (destination: DetailViewNew(fetch: fetch)) {Text("Read")}
            }
.onAppear(perform: {
            refreshManager.loadDataifNeeded() { success in
                print(success)
            }
        })
    }
}

struct HeaderView_Previews: PreviewProvider {
    static var previews: some View {
        HeaderView()
            .preferredColorScheme(.light)
            
    }
}

刷新管理器

import Foundation

class RefreshManager: NSObject,ObservableObject {
    
    var fetch = FetchText()

    static let shared = RefreshManager()
    private let defaults = UserDefaults.standard
    private let defaultsKey = "lastRefresh"
    private let calender = Calendar.current

    func loadDataifNeeded(completion: (Bool) -> Void) {

        if isRefreshrequired() {
            fetch.getText()
            defaults.set(Date(),forKey: defaultsKey)
            completion(true)
        } else {
            completion(false)
        }
    }

    private func isRefreshrequired(userPickedHour: Int = 5) -> Bool {

        guard let lastRefreshDate = defaults.object(forKey: defaultsKey) as? Date else {
            return true
        }

        if let diff = calender.dateComponents([.hour],from: lastRefreshDate,to: Date()).hour,let currentHour =  calender.dateComponents([.hour],from: Date()).hour,diff >= 24,userPickedHour <= currentHour {
            return true
        } else {
            return false
        }
    }
}

有什么建议吗?我很感激任何帮助。谢谢。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。