I am using Parse.com with my iOS application (written in Swift) since 6 month and I would like to use Parse local Datastore for many reasons :
- Make my application usable (retrievable) offline
- Reduce data usage (many queries returning « non updated data »)
- Reduce loading time (mainly when starting application and loading all data from network)
In order to do so I would like to write a global function handeling these scenarios for all the query I do from my application.
I already have a specific idea of what the function should do but I don’t know how to technically write this function :)
Scenarios :
Sign Up / Log In (chain multiple query) :
- Get data from Network
- Save date inside « lastUpdateLocalDatastore » variable in NSUserDefaults
- Pin data in Local Datastore
- Display data from Local Datastore —> RETURN & update TableView
Loading App (chain multiple query) :
- Display data from Local Datastore —> RETURN & update TableView
- Get data from Network (where « lastUpdateDate » in Parse is newer than « lastUpdateLocalDatastore » from NSUserDefault)
- Pin data in Local Datastore
- Display updated data from Local Datastore —> RETURN & update TableView
Trigger update (simple query) :
- Get data from Network (where « lastUpdateDate » in Parse is newer than « lastUpdateLocalDatastore » from NSUserDefault)
- Pin data in Local Datastore
- Display updated data from Local Datastore —> RETURN & update TableView
Log Out :
- Unpin all data in Local Datastore
- Clear « lastUpdate » values in NSUserDefault
Function structure :
IF ( "First login" -> Local Datastore is empty ) {
Get data from Network
Pin data in Local Datastore
Save « lastUpdateLocalDatastore » in NSUSerDefaults
—> RETURN data in Cache
} ELSE {
IF ( "Launching application" -> Cache is empty ) {
Get data from Local Datastore
—> RETURN data in Cache
} ELSE IF ( "trigger update" ) {
Get data from Network
Pin new data in Local Datastore
Save « lastUpdateLocalDatastore » in NSUSerDefaults
—> RETURN data in Cache
}
}
Problems :
- How to handle multiple (asynchronous) returns
- How to make a function capable of chaining multiple queries (for example I need to retrieve data from 6 different queries when I load my app)
Finally I found a way to do it based on this GitHub topic : https://github.com/ParsePlatform/ParseUI-iOS/issues/53
Here is the function I use :
func findObjectsLocallyThenRemotely(query: PFQuery!, block:[AnyObject]! -> Void) {
let localQuery = (query.copy() as! PFQuery).fromLocalDatastore()
localQuery.findObjectsInBackgroundWithBlock({ (locals, error) -> Void in
if (error == nil) {
println("Success : Local Query", msg: "\(query.parseClassName)")
block(locals)
} else {
println("Error : Local Query", msg: "\(query.parseClassName)", error: error)
}
query.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
if(error == nil) {
println("Success : Network Query", msg: "\(query.parseClassName)")
PFObject.unpinAllInBackground(locals, block: { (success, error) -> Void in
if (error == nil) {
println("Success : Unpin Local Query", msg: "\(query.parseClassName)")
block(objects)
PFObject.pinAllInBackground(objects, block: { (success, error) -> Void in
if (error == nil) {
println("Success : Pin Query Result", msg: "\(query.parseClassName)")
} else {
println("Error : Pin Query Result", msg: "\(query.parseClassName)", error: error)
}
})
} else {
println("Error : Unpin Local Query", msg: "\(query.parseClassName)", error: error)
}
})
} else {
println("Error : Network Query", msg: "\(query.parseClassName)", error: error)
}
})
})
}
TO DO : I need to add the "lastUpdateDate" option to fetch only modified data from network.
来源:https://stackoverflow.com/questions/31742400/parse-local-datastore-network-sync