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

Swift中如何将字符串数组保存到Realm并在TableView展示

解决方案:将字符串数组保存到Realm并在TableView展示

Realm不支持直接存储原生[String]类型,需要通过**List<Object>包裹自定义模型**的方式来适配,以下是具体实现步骤:


1. 创建单个字符串的Realm模型

首先定义一个封装单个字符串的Object子类,用来作为List的元素类型:

import RealmSwift

class StringItem: Object, Decodable {
    @objc dynamic var value: String = ""
    
    // 便捷初始化方法
    convenience init(value: String) {
        self.init()
        self.value = value
    }
    
    // 解码时直接将字符串转为StringItem
    required init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let stringValue = try container.decode(String.self)
        self.init(value: stringValue)
    }
}

2. 修改MessageModel适配Realm

将原有的[String]替换为List<StringItem>,并实现Decodable协议处理服务器返回的数组:

import RealmSwift

class MessageModel: Object, Decodable {
    let result = List<StringItem>()
    
    // 解码服务器返回的[String]并转为List<StringItem>
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let stringArray = try container.decode([String].self, forKey: .result)
        super.init()
        result.append(objectsIn: stringArray.map { StringItem(value: $0) })
    }
    
    // Realm必须的空初始化方法
    required override init() {
        super.init()
    }
    
    enum CodingKeys: String, CodingKey {
        case result
    }
}

3. 修改ViewController实现数据持久化与展示

将数据源替换为Realm的Results(实时更新的查询结果),并通过通知监听数据变化自动刷新TableView:

import UIKit
import RealmSwift

final class StartController: UIViewController {
    // 使用Realm Results作为数据源,支持实时更新
    private var messageResults: Results<StringItem>?
    // 监听数据变化的通知令牌
    private var notificationToken: NotificationToken?

    override func viewDidLoad() {
        super.viewDidLoad()
        setUpView()
        setUpConstraints()
        configData()
        setupRealmObserver()
    }

    private func configData() {
        service.addMessage(offset: offsetStart) { [weak self] result in
            switch result {
            case .success(let dataMessage):
                // 将服务器数据保存到Realm
                do {
                    let realm = try Realm()
                    try realm.write {
                        // 可选:清空旧数据再添加新数据,或者直接追加
                        realm.delete(realm.objects(StringItem.self))
                        let items = dataMessage.map { StringItem(value: $0) }
                        realm.add(items)
                    }
                } catch {
                    print("Realm保存失败: \(error)")
                }
            case .failure(let error):
                print(error)
                DispatchQueue.main.async {
                    self?.showAlert(title: "Error", message: "Error connecting to the server")
                }
            }
        }
    }

    // 设置Realm数据监听,自动刷新TableView
    private func setupRealmObserver() {
        let realm = try! Realm()
        messageResults = realm.objects(StringItem.self)
        
        notificationToken = messageResults?.observe { [weak self] _ in
            DispatchQueue.main.async {
                self?.messageTable.reloadData()
            }
        }
    }

    // 页面销毁时移除监听
    deinit {
        notificationToken?.invalidate()
    }

    // MARK: - TableView DataSource
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return messageResults?.count ?? 0
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = messageTable.dequeueReusableCell(withIdentifier: identifier, for: indexPath)
        cell.backgroundColor = UIColor(named: "backgroundColor")
        
        guard let messageItem = messageResults?[indexPath.row] else { return cell }
        var content = cell.defaultContentConfiguration()
        content.text = messageItem.value
        
        return cell
    }
}

关键说明

  • Realm仅支持存储Object子类或其包裹的List,因此必须用StringItem封装单个字符串。
  • 使用Results作为数据源可以自动同步Realm中的数据变化,配合NotificationToken无需手动调用reloadData。
  • 所有Realm的写入操作必须在write事务中执行,确保线程安全。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:40:23