对于大尺寸json

时间:2016-03-17 09:58:23

标签: swift insert realm alamofire swifty-json

我使用Alamofire下载大约7MB的大json数据,并使用RealmSwift将数据存储在realmobject和SwiftyJSON进行解析。我完成下载后,我的域对象插入json在插入时看起来很慢。我的问题是什么代码不好?请指导我。

首先,我将展示最简单的Json:

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

这是我的AlamofireAPI协议

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])
}

}

这是我的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)")
    }
}
}

这是我的领域modelObject

import Foundation
import RealmSwift

class UserList: Object {

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

}

最终代码,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
           }
        })
    }
}

我知道描述所有代码步骤真的很愚蠢,我尽可能简单地编写了将json数据插入到realm swift的工作流程。

我只是希望在处理这么多json数据和插入时,所有人都知道我的工作流程是好还是坏。

我之所以这么说是因为数据插入花了大约7分钟才完成。

所以,我真的需要帮助,对我的代码进行优化。

任何指南?

更新:我使用来自RequestDataAPI的委托和协议,我从JamesQueue教程中学习了这个样式,因为我是完全初学者,还在学习Swift.ViewController更新。这是我的整个过程细节,不再代码left.Editing我的问题或回答新的代码优化赞赏。

2 个答案:

答案 0 :(得分:6)

insertUserData方法方法在循环中多次打开事务。提交事务是一项有点昂贵的操作。

你可以尝试在循环之外打开/提交事务吗? 换句话说,在进入循环之前打开事务,并在循环结束后提交事务一次。如下所示:

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)
            }
        }
    }
}

答案 1 :(得分:0)

我已通过使用此代码解决了慢速插入问题。

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()
}

显示示例使用的功能-

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)