SwiftUI之存储方案选择

研究应用场景

根据不同应用场景选择
1、如果不需要持久化存储,那么单例模式就是最优选择
可以参考下面例子
SwiftUI数据如何在App中的不同视图和类直接调用


2、需要持久化,但不会SQL
建议使用xcode自带的CoreData,优势是原生,不用写SQL语句就可以实现数据的增删改查。可以参考下面例子:


3、需要高性能的查询
SwiftUI 数据之List显示Sqlite数据库内容(2020年教程)


数据存储方案 CoreData vs Sqlite

1、用CoreData理想的模式

class Member {
    var name = ""
    var type = ""
    
    init(){
      
    }
    init(user: User) {
        self.name = user.name!
        self.type = user.type!
    }
    
}

理想的调用方式

Text("欢迎用户:\(self.uMgr.currentUser.name)")
 Text("\(self.uMgr.currentUser.type)")

2、用Sqlite的理想模式

class SQLandmark: SQLTable {
    var id = -1
    var name = ""
    var imageName = ""
    
    override var description:String {
        return "id: \(id), name: \(name)"
    }
   
    static func customTables() ->String {
        return "landmark"
    }
   
}

更优雅简单的调用方式

let sqLandmarkData: [SQLandmark] = SQLandmark.rows(order:"id ASC")

CoreData 和 Sqlite工具区别

1、CoreData 使用Xcode即可


41085-eefcf757a5ead9c6.png
image.png

2、Sqlite建议使用Navicat


41085-7b562b3c6583fd13.png
image.png

CoreData增删改查模式

1、获取数据

  let appDelegate = UIApplication.shared.delegate as? AppDelegate
    managedContext = appDelegate?.persistentContainer.viewContext

    insertSampleData()

    let request: NSFetchRequest<BowTie> = BowTie.fetchRequest()
    let firstTitle = segmentedControl.titleForSegment(at: 0)!
    request.predicate = NSPredicate(format: "%K = %@", argumentArray: [#keyPath(BowTie.searchKey), firstTitle])

    do {
      let results = try managedContext.fetch(request)
      currentBowTie = results.first

      populate(bowtie: results.first!)
    } catch let error as NSError {
      print("Could not fetch \(error), \(error.userInfo)")
    }

2、插入数据

func insertSampleData() {

    let fetch: NSFetchRequest<BowTie> = BowTie.fetchRequest()
    fetch.predicate = NSPredicate(format: "searchKey != nil")

    let count = try! managedContext.count(for: fetch)

    if count > 0 {
      // SampleData.plist data already in Core Data
      return
    }
    let path = Bundle.main.path(forResource: "SampleData", ofType: "plist")
    let dataArray = NSArray(contentsOfFile: path!)!

    for dict in dataArray {
      let entity = NSEntityDescription.entity(forEntityName: "BowTie", in: managedContext)!
      let bowtie = BowTie(entity: entity, insertInto: managedContext)
      let btDict = dict as! [String: Any]

      bowtie.id = UUID(uuidString: btDict["id"] as! String)
      bowtie.name = btDict["name"] as? String
      bowtie.searchKey = btDict["searchKey"] as? String
      bowtie.rating = btDict["rating"] as! Double
      let colorDict = btDict["tintColor"] as! [String: Any]
      bowtie.tintColor = UIColor.color(dict: colorDict)

      let imageName = btDict["imageName"] as? String
      let image = UIImage(named: imageName!)
      bowtie.photoData = image?.pngData()
      bowtie.lastWorn = btDict["lastWorn"] as? Date

      let timesNumber = btDict["timesWorn"] as! NSNumber
      bowtie.timesWorn = timesNumber.int32Value
      bowtie.isFavorite = btDict["isFavorite"] as! Bool
      bowtie.url = URL(string: btDict["url"] as! String)
    }
    try! managedContext.save()
  }

3、更新数据

 func update(rating: String?) {

    guard let ratingString = rating,
      let rating = Double(ratingString) else {
        return
    }

    do {

      currentBowTie.rating = rating
      try managedContext.save()
      populate(bowtie: currentBowTie)

    } catch let error as NSError {

      if error.domain == NSCocoaErrorDomain &&
        (error.code == NSValidationNumberTooLargeError || error.code == NSValidationNumberTooSmallError) {
        rate(rateButton)
      } else {
        print("Could not save \(error), \(error.userInfo)")
      }
    }
  }

QQ:3365059189
SwiftUI技术交流QQ群:518696470

https://www.jianshu.com/c/7b3e3b671970

SwiftUI中,为了在启动屏幕显示加载状态,并在配置完成后再切换到引导页面,你可以按照以下步骤操作: 1. **启动屏设置**: - 创建一个`LoadingView`,它将展示加载指示器。你可以使用`ProgressView`或者自定义视图来实现。 ```swift struct LoadingView: View { var body: some View { ProgressView(activityIndeterminate: true) // 或者使用CircularProgressIndicator等自定义进度视图 .padding() .background(Color.gray.opacity(0.7)) .foregroundColor(.white) .animation(.default) .onAppear(perform: loadConfig) } func loadConfig() { DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { self.preloadPreferences() self.isPreloaded = true // 设置一个布尔值标记加载完成 } } // 假设有个变量isPreloaded用于跟踪是否配置已完成 @State private var isPreloaded: Bool = false } ``` 2. **偏好配置**: - 通过UserDefaults或其他持久化存储方案,预先加载用户的偏好设置。 ```swift func preloadPreferences() { if let config = UserDefaults.standard.string(forKey: "preferenceKey") { handleConfiguration(config) } else { print("No preference data found, loading default settings.") } } // handleConfiguration方法负责解析配置并做相应调整 func handleConfiguration(config: String) { // 解析config字符串并应用到应用程序的初始状态或导航栈 } ``` 3. **引导页切换**: - 利用`isPreloaded`的状态,在配置完成后跳转到引导页或主界面。 ```swift struct ContentView: View { @StateObject private var viewModel = ViewModel(isPreloaded: $isPreloaded) var body: some View { if !viewModel.isPreloaded { LoadingView() } else { // 引导页或者其他主界面视图 NavigationView { // ... } } } } // ViewModel类 class ViewModel: ObservableObject { @Published var isPreloaded: Bool init(isPreloaded: Binding<Bool>) { _isPreloaded = isPreloaded } // 当isPreloaded变为true时,触发导航或界面变更 func onConfigLoaded() { withAnimation { isPreloaded = true navigateToMainPage() // 调用导航函数 } } func navigateToMainPage() { // 替换为实际的引导页或者主界面的导航逻辑 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知识大胖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值