是否有类似分页的代码用于将 JSON 数据保存到 Realmdatabase

Is there any pagination like code for saving JSON data to Realmdatabase

我有一个按钮,按钮下方是 table 视图。 Table 视图单元格有一些随机的 data.On 按钮单击我正在调用 api(函数名称是:api.urlRequest(userID:80,businessUnitID:2))。我有一个包含 35,0000 个条目的 API。我想要的是将该数据保存在 Realm 数据库中。问题是,当我调用保存函数时,我的 UI 冻结了。我将 JSON 数据附加到模型,然后将其保存到数据库。我可以获得 JSON 数据的开始索引和结束索引。

我尝试的是在后台线程上调用 API,当调用保存函数时,我在主线程上调用它。但这没有用。

class ViewController: UIViewController,getAdhocJSONDelegate{
    let realm = try! Realm()
    @IBOutlet weak var tableViewRef: UITableView!
    var array = [NSDictionary]()
    var adhocData : [AdhocModel] = []//for appending the JSON data to the model
    var adhocDB : Results<AdhocDB>?// for accessing the database
    let api = AdhocAPIParamteres()
    var adhocJSONDatafromAPI : NSDictionary!
    override func viewDidLoad() {
        super.viewDidLoad()
        adhocDB = realm.objects(AdhocDB.self)
    }

    @IBAction func buttonPressed(_ sender: Any) {
        print("BUtton Tapped")
        api.urlRequest(userID: 80, businessUnitID: 2)
        api.delegate = self   
    }
    func appTutorialData(json: NSDictionary) {
        adhocJSONDatafromAPI = json
        let apiData = adhocJSONDatafromAPI.value(forKey: "data") as! [NSDictionary]
        print("Start Index of the data : ",apiData.startIndex)
        print("End Index of the data : ",apiData.endIndex)
        apiData.forEach { (abc) in
            let model = AdhocModel()
            model.site_id = abc.value(forKey: "site_id") as! Int
            model.atm_id = abc.value(forKey: "atm_id") as! String
            model.site_address = abc.value(forKey: "site_address") as! String
            adhocData.append(model)
            print("data appended")
           DispatchQueue.main.async {
            self.saveToDb(data:model)
        }
    }

    func saveToDb(data: AdhocModel) {
        let adhoc = AdhocDB()
        try! realm.write {
            adhoc.SiteId = data.site_id
            adhoc.AtmId = data.atm_id
            adhoc.SiteAdress = data.site_address
            realm.add(adhoc)
        }
    }
}

我想以 UI 不冻结的方式保存数据。

代码存在一些问题,documentation 中介绍了在后台线程上向 Realm 写入数据,因此我不会解决该问题。遵循该设计模式将纠正 UI 锁定。

这是另一个问题

func saveToDb(data: AdhocModel) {
        **let adhoc = AdhocDB()**

您想将填充的模型写入领域,但 AdhocDB 是一个结果对象,而不是领域模型对象。此外,在 appTutorialData 中创建的领域对象 model 被传递给 saveToDb,然后 另一个 对象被创建,然后用数据填充从第一个对象。没有理由这样做(在此代码中)

假设 AdHocModel 是一个 Realm 对象,这样就干净多了

func appTutorialData(json: NSDictionary) {
    adhocJSONDatafromAPI = json
    let apiData = adhocJSONDatafromAPI.value(forKey: "data") as! [NSDictionary]
    print("Start Index of the data : ",apiData.startIndex)
    print("End Index of the data : ",apiData.endIndex)
    apiData.forEach { (abc) in
        let model = AdhocModel()
        model.site_id = abc.value(forKey: "site_id") as! Int
        model.atm_id = abc.value(forKey: "atm_id") as! String
        model.site_address = abc.value(forKey: "site_address") as! String
        try! realm.write {
            realm.add(model)
        }
    }
}

您需要将写入内容包装在后台线程中(同样,请参阅文档),如下所示

DispatchQueue(label: "background").async {
    autoreleasepool {
        .
        .
        .
        try! realm.write {
            realm.add(model)
        }
    }
}

您可能会询问有关填充数组的问题 adhocData.append(model)。我们不知道你在用它做什么,但如果你将它用作 table 视图或其他一些 UI 元素的数据源,你可能需要考虑使用结果对象而不是数组。

一个显着的优势是,如果您有 35,000 个对象,那是一个相当大的数组,如果您有更多对象,它可能会使设备不堪重负,因为所有这些数据都存储在内存中。但是,Results 对象是延迟加载的,因此您可以拥有更大的数据集而不会压倒设备。

此外,当 Realm 对象存储在数组中时,它们 'Disconnect' 来自 Realm 并失去 Realm 功能 - 它们不会自动更新,也不会在数组中反映对 Realm 中实际对象的更改,也不会你能不能只更新对象 - 它似乎没有主键。

但是,如果您使用这些模型填充结果对象,它们将实时更新 - 因此,如果 atm_id 在 Realm 中发生变化,该对象将自动更新。如果您需要更改 属性,您可以在写入事务中直接在该对象上进行更改。

所以该模式将有一个 class 的结果变量,并将您的对象加载到 viewDidLoad 中的这些结果中。当您添加更多模型时,结果对象将自动更新。

为了让您的 UI 保持新鲜,您需要向这些结果添加观察者(又名 Notifications),以便在对象更新时收到通知,以便您可以重新加载 table查看示例。