Realm data Insertion took over 7mins for big size json

孤者浪人 提交于 2019-12-08 08:26:35

问题


I use Alamofire to download big json data which was about around 7MB and use RealmSwift to store data at realmobject and SwiftyJSON to parse.My realm object insertion after it finished download the json seems really slow at insertion.Was something wrong with my bad code?Please guide me.

First of all I will show simplest Json :

{
    {
        "Start" : "40000",
        "End" : "1000000",
        "Name" : "Smith",
        "Address" : "New York"
    },{...},more than 7000 records...
}

Here is my AlamofireAPI Protocol

import Foundation
import Alamofire
import SwiftyJSON

protocol RequestDataAPIProtocol{
    func didSuccessDownloadingData(results:JSON,statusCode : Int)
    func didFailDownloadingData(err : NSError)
}

class RequestDataAPI{

var delegate : RequestDataAPIProtocol
init(delegate: RequestDataAPIProtocol){
    self.delegate=delegate
}

func post(requestURL:String,param:[String:String]){
    Alamofire.request(.GET, requestURL, parameters: param)
        .validate(statusCode: [200,500])
        .responseJSON(completionHandler: { (response: Response<AnyObject, NSError>) -> Void in
            if let error = response.result.error {
                self.delegate.didFailDownloadingData(error)
            } else if let jsonObject: AnyObject = response.result.value {
                let json = JSON(jsonObject)
                self.delegate.didSuccessDownloadingData(json,statusCode: (response.response?.statusCode)!)
            }
        })
}

func doRequestSiteData(token : String){
    post(REQUEST_DATA,param:["data":"All","token":token])
}

}

Here is my Realm DB Helper

import Foundation
import RealmSwift

class DBHelper{

func insertUserData(list: UserList){
    do {
        let realm = try! Realm()
        try realm.write({ () -> Void in
            realm.add(list,update: true)
        })
    } catch let error as NSError {
        print("Insert Error : \(error)")
    }
}
}

Here is my realm modelObject

import Foundation
import RealmSwift

class UserList: Object {

     dynamic var start : String = ""
     dynamic var end : String = ""
     dynamic var name : String = ""
     dynamic var address : String = ""

}

And Final Code,View Controller,

class ViewController : UIViewController , RequestDataAPIProtocol{
       var dbHelper = DBHelper()
       var requestDataAPI : RequestDataAPI!

       override func viewDidLoad() {
           super.viewDidLoad()
           requestDataAPI = RequestDataAPI(delegate : self)
       }

       override func viewDidAppear(animated : Bool){
            //assume there is one token to request data
            requestDataAPI.doRequestSiteData(token)
       }

       func didSuccessDownloadingData(results: JSON, statusCode: Int){
        dispatch_async(dispatch_get_main_queue(), {
            print("Downloaded JSON")
            switch statusCode{
            case 200 :
               if results.count > 0{
                   if let users = results.array {
                      for user in users{
                         let userList=UserList()
                         userList.start=user["Start”].stringValue
                         userList.end=user[“End”].stringValue
                         userList.name=user[“Name”].stringValue
                         userList.address =user[“Address”].stringValue
                         self.dbHelper.insertUserData(userList)
                      }
                   }
               }
               // took about more than 7 mins
               print(“Insertion Done”)
               break

           case 500,401,400 :
               //TODO: 
           default : break
           }
        })
    }
}

I know its really stupid about describing all the code steps,I write as simple as i could for my working flow for inserting json data into realm swift.

I just want all to know about my working flow is good or bad when handling so many json data,and also insertion.

The reason why I am asking this was the data insertion took about more than 7 mins to finish.

So,I really need help,to make optimize at my code.

Any guide?

UPDATE : I use Delegate and Protocol from RequestDataAPI which i learn that style from JamesQueue Tutorial because I am completely beginner who is still learning Swift.ViewController is updated.That is my whole process detail,no more code left.Editing my question or answer a new is appreciated for code optimizing.


回答1:


insertUserData method method opens transactions so many times in the loop. To commit transaction is a little bit expensive operation.

Can you try to put out to open/commit a transaction outside of the loop? In other words, open the transaction before entering the loop, and commits the transaction once after the end of the loop. Like the following:

if results.count > 0 {
    if let users = results.array {
        let realm = try! Realm()
        try realm.write {
            for user in users{
                let userList=UserList()
                userList.start=user["Start”].stringValue
                userList.end=user[“End”].stringValue
                userList.name=user[“Name”].stringValue
                userList.address =user[“Address”].stringValue
                realm.add(userList,update: true)
            }
        }
    }
}



回答2:


I have fixed slow insertion issue by using this code.

func addAsBatch<T: Object>(_ data: [T]) {
    if !isRealmAccessible() { return }

    let realm = try! Realm()
    realm.refresh()

    realm.beginWrite()
    for object in data {
        realm.add(object)
    }
    try? realm.commitWrite()
}

Showing function use with your example -

let userList = UserList()
userList.start = user["Start”].stringValue
userList.end = user[“End”].stringValue
userList.name = user[“Name”].stringValue
userList.address  = user[“Address”].stringValue

addAsBatch(userList)


来源:https://stackoverflow.com/questions/36057103/realm-data-insertion-took-over-7mins-for-big-size-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!