You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI应用接收UIKit通知并前后台存入Core Data的实现方案

iOS应用设计:记录UIKit设置变更(SwiftUI+Core Data)

问题描述

我想要开发一款iOS应用,用于记录UIKit中某一项设置的所有变更。SwiftUI端的流程如下:

  1. UIKit 发送通知(static let Name_StatusDidChangeNotification: NSNotification.Name)
  2. SwiftUI应用在前台和后台模式下,将当前 DateTime 存入 Core Data

这是我首次开发iOS应用,已梳理部分思路:

  1. 创建 DataController : ObservableObject,用于控制数据的加载与设备存储
  2. 创建 AppDelegate: NSObject, UIApplicationDelegate {}
  3. 在 @main 结构体中添加代码:
@UIApplicationDelegateAdaptor(Appdelegate.self) var appDelegate 

但卡在了NotificationCenter的配置环节,不清楚应该将以下代码添加到何处:

NotificationCenter.default
                    .addObserver(self,
                      selector:#selector(mySelector),
                 name: NSNotification.Name("Name_StatusDidChangeNotification"),
                      object:nil)


@objc func mySelector(_ notification: Notification) {
//saving DateTime into Storage
}

完整实现方案

1. 把通知监听放在AppDelegate中

AppDelegate作为应用生命周期的核心入口,能确保前台/后台状态下都能稳定接收通知,是放置监听代码的最佳位置。修改后的AppDelegate代码如下:

import UIKit
import CoreData

class AppDelegate: NSObject, UIApplicationDelegate {
    // 持有DataController实例,方便在通知回调中调用存储逻辑
    var dataController: DataController!

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 初始化DataController
        dataController = DataController.shared
        
        // 注册UIKit发送的状态变更通知
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleStatusChange),
            name: NSNotification.Name("Name_StatusDidChangeNotification"),
            object: nil
        )
        return true
    }

    @objc private func handleStatusChange(_ notification: Notification) {
        // 获取当前时间并调用DataController存储
        let currentDate = Date()
        dataController.saveDateTime(currentDate)
    }
}

2. 完善DataController的Core Data存储逻辑

确保DataController实现Core Data的初始化和数据持久化方法,示例代码:

import CoreData
import Foundation

class DataController: ObservableObject {
    static let shared = DataController() // 单例模式,全局统一调用
    
    let persistentContainer: NSPersistentContainer

    init() {
        // 替换成你的Core Data模型文件名
        persistentContainer = NSPersistentContainer(name: "StatusChangeModel")
        persistentContainer.loadPersistentStores { description, error in
            if let error = error {
                fatalError("Core Data加载失败: \(error.localizedDescription)")
            }
        }
    }

    // 存储时间记录的方法
    func saveDateTime(_ date: Date) {
        let context = persistentContainer.viewContext
        // 替换成你的Core Data实体类名
        let record = StatusChangeRecord(context: context)
        record.changeDate = date
        
        do {
            try context.save()
        } catch {
            context.rollback()
            print("存储时间记录失败: \(error.localizedDescription)")
        }
    }
}

3. 在@main结构体中关联组件

让DataController在应用启动时初始化,并传递给AppDelegate:

import SwiftUI

@main
struct StatusTrackerApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    @StateObject private var dataController = DataController.shared

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, dataController.persistentContainer.viewContext)
        }
    }

    init() {
        // 将单例DataController传给AppDelegate
        appDelegate.dataController = DataController.shared
    }
}

4. 后台接收通知的配置

如果需要应用在后台也能响应通知,需在Info.plist中添加后台模式权限:

  • 打开Info.plist,添加UIBackgroundModes数组,加入remote-notification(针对远程通知)或确保应用未被完全杀死(内部NSNotification在后台活跃状态下可正常接收)。

内容的提问来源于stack exchange,提问作者magwyg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 06:31:00