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