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

如何在iOS应用中以编程方式集成Realm数据库?

集成Realm解决iOS应用数据持久化问题

问题背景

我开发了一款iOS应用,需要在Realm数据库中存储标题(Title)和图片(或图片路径)两个字段。目前数据存储在Video结构体中,但重启应用后所有修改都会丢失。需要将现有代码改造为集成Realm的版本,实现数据持久化。

现有代码如下:

struct Video  {
    var image: UIImage
    var title : String 
}

class VideoCell: UITableViewCell {
    var videoImageView=UIImageView()
    var videoTitleLabel=UILabel()
   
    required init?(coder:NSCoder){
        fatalError("init(coder:) has not been implemented")
    }

    func set(video : Video) {
        videoTitleLabel.text = video.title
        videoImageView.image = video.image
    } 
}

class VideoListVC:  UIViewController, UISearchResultsUpdating {
    var tableView=UITableView()
    var videos : [Video] = []

    var videoImageView=UIImageView()
    var videoTitleLabel=UILabel()

    struct Cells {
        static let videoCell = "VideoCell"
    }

    override func viewDidLoad(){
        super.viewDidLoad()   
        title = ""
        videos = fetchData()
        configureTableView()    
    }

    func configureTableView(){
        view.addSubview(tableView)
        setTableViewDelegates()
        tableView.rowHeight = 290
        tableView.register(VideoCell.self, forCellReuseIdentifier: Cells.videoCell)
        tableView.pin(to:view)
    } 

    func setTableViewDelegates(){
        tableView.delegate=self
        tableView.dataSource=self
    }    
}

extension VideoListVC: UITableViewDelegate,UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return videos.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: Cells.videoCell) as! VideoCell
        let video = videos[indexPath.row]
        cell.set(video: video)
        return cell
    }

    func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
        return .delete
    }
    
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            tableView.beginUpdates()
            videos.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .fade)
            tableView.endUpdates()
        }
    } 
}

集成Realm的步骤

1. 安装Realm

通过CocoaPods安装,在项目的Podfile中添加:

pod 'RealmSwift'

执行pod install命令后,使用.xcworkspace文件打开项目。

2. 将Video结构体改为Realm模型

Realm要求数据模型必须继承自Object,且无法直接存储UIImage类型,推荐两种存储方案:

方案一:存储图片本地路径(推荐,避免数据库体积过大)

import RealmSwift

class Video: Object {
    @Persisted var title: String = ""
    @Persisted var imagePath: String = "" // 存储图片在沙盒中的路径

    // 从路径加载UIImage的计算属性
    var image: UIImage? {
        guard !imagePath.isEmpty else { return nil }
        let url = URL(fileURLWithPath: imagePath)
        guard let data = try? Data(contentsOf: url) else { return nil }
        return UIImage(data: data)
    }
}

方案二:存储图片Data(适合小体积图片)

import RealmSwift

class Video: Object {
    @Persisted var title: String = ""
    @Persisted var imageData: Data? // 存储图片的二进制数据

    // 从Data转UIImage的计算属性
    var image: UIImage? {
        guard let data = imageData else { return nil }
        return UIImage(data: data)
    }
}

3. 修改数据操作逻辑

替换原有内存级数据操作,改为Realm持久化操作:

import RealmSwift

class VideoListVC:  UIViewController, UISearchResultsUpdating {
    var tableView=UITableView()
    var videos: Results<Video>! // 使用Realm的Results类型,自动监听数据变化
    private let realm = try! Realm() // 获取Realm数据库实例

    // ... 保留原有UI配置代码 ...

    override func viewDidLoad(){
        super.viewDidLoad()   
        title = ""
        fetchData()
        configureTableView()    
        // 监听Realm数据变化,自动刷新表格
        NotificationCenter.default.addObserver(self, selector: #selector(realmDataChanged), name: NSNotification.Name.RealmDidChange, object: realm)
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    @objc private func realmDataChanged() {
        tableView.reloadData()
    }

    func fetchData() {
        // 查询所有Video数据,Results会自动实时更新
        videos = realm.objects(Video.self)
    }

    // 新增:保存Video数据到Realm
    func saveVideo(title: String, image: UIImage) {
        let video = Video()
        video.title = title

        // 方案一:保存图片到沙盒并记录路径
        if let imageData = image.jpegData(compressionQuality: 0.8) {
            let documentsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
            let imageName = UUID().uuidString + ".jpg"
            let imageURL = documentsDir.appendingPathComponent(imageName)
            try? imageData.write(to: imageURL)
            video.imagePath = imageURL.path
        }

        // 方案二:直接存储图片Data
        // video.imageData = image.jpegData(compressionQuality: 0.8)

        // 写入Realm必须在事务中执行
        try! realm.write {
            realm.add(video)
        }
    }

    // 修改删除逻辑:同步删除Realm中的数据
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            let targetVideo = videos[indexPath.row]
            try! realm.write {
                realm.delete(targetVideo)
                // 方案一需同步删除本地图片文件
                if !targetVideo.imagePath.isEmpty {
                    try? FileManager.default.removeItem(atPath: targetVideo.imagePath)
                }
            }
            tableView.deleteRows(at: [indexPath], with: .fade)
        }
    } 
}

4. 更新Cell配置方法

适配Realm版Video模型,修改VideoCell的set方法:

class VideoCell: UITableViewCell {
    // ... 保留原有UI组件代码 ...

    func set(video: Video) {
        videoTitleLabel.text = video.title
        videoImageView.image = video.image
    } 
}

5. 关键注意事项

  • Realm会自动创建数据库文件,可通过print(Realm.Configuration.defaultConfiguration.fileURL)查看文件路径。
  • 所有添加、删除、修改数据的操作必须放在realm.write事务中执行。
  • Results类型自带实时数据监听,配合Realm通知可实现UI自动刷新。
  • 优先选择存储图片路径的方案,避免数据库体积膨胀影响应用性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 15:24:23