Cam*_*aba 1 objective-c ios parse-platform
在我使用Parse的iOS应用程序中,一些用户需要在一个操作中保存数千个对象.我已经尝试迭代数据数组并逐个创建/保存对象,但这会导致对象保存到我的数据浏览器的速度非常慢.每个对象只需要包含几个字符串,所以我不明白为什么它需要这么长时间来保存这些对象.
有没有更快的方法将数千个对象保存到Parse?
编辑:
我一直用[PFObject saveAllInBackground:数组块:^(BOOL成功,NSError*错误){}]; 但....我刚刚尝试半成功的另一种方法是上传一个Json字符串作为PFFile(没有128k限制),然后使用云代码解析它并创建必要的PFObjects.我能够以小批量工作,但不幸的是,当使用大量数据时,云代码超时.我改为选择使用后台作业来执行解析.这在数据完全可用之前需要相当长的时间,但可以处理大量数据.上传时间本身要快得多.当使用具有3个字符串的1000个对象时,每个上载大约为0.8秒,而在后台执行全部保存则为23秒,5000个对象3个字符串,每个上传时间仅为2.5秒.除了更快的时间,您还可以获得进度更新.根据使用情况,如果立即快速上传很重要,那么利用这种替代方案可能效果最佳,而不是立即提供数据.
IOS代码:
NSMutableArray *array = [NSMutableArray array];
for (int i = 0; i<5; i++) {
//subclass of PFObject
Employee *employee = [Employee object];
employee.firstName = @"FName";
employee.lastName = @"LName";
employee.employeeID = @"fid54";
[array addObject:[employee dictionaryWithValuesForKeys:employee.allKeys]];
}
//Seperate class only to store the PFFiles
PFObject *testObject = [PFObject objectWithClassName:@"fileTestSave"];
testObject[@"testFile"] = [PFFile fileWithData:[NSJSONSerialization dataWithJSONObject:array options:0 error:nil]];
NSLog(@"started");
//**notice I am only saving the test object with the NSData from the JSONString**
[testObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error && succeeded) NSLog(@"succeeded");
else NSLog(@"error");
}];
Run Code Online (Sandbox Code Playgroud)
编辑:可以随时运行下面的后台作业,而不是保存在beforeSave或afterSave Cloud Code中,这可能导致超时问题.它抓取"fileTestSave"表中的所有行,解析这些行中的JSON字符串,并将它们添加到"Person"表中.一旦完成,它将从表中行.所有异步!
var _ = require('underscore.js');
Parse.Cloud.job("userMigration", function(request, status)
{
// Set up to modify user data
Parse.Cloud.useMasterKey();
//Table called fileTestSave stores a PFFile called "testFile" which we will use an HTTPRequest to get the data. Is there a better way to get the data?
//This PFFile stores a json string which contains relavent data to add to the "Person" table
var testFileSave = Parse.Object.extend("fileTestSave");
var query = new Parse.Query(testFileSave);
query.find().then(function(results)
{
//Generate an array of promises
var promises = [];
_.each(results, function(testFileSaveInstance){
//add promise to array
promises.push(saveJsonPerson(testFileSaveInstance));
});
//only continue when all promises are complete
return Parse.Promise.when(promises);
}).then(function()
{
// Set the job's success status
console.log("Migration Completed NOW");
status.success("Migration completed");
}, function(error) {
// Set the job's error status
status.error("Uh oh, something went wrong.");
});
});
function saveJsonPerson(fileTestSave)
{
//Get the pffile testfile
var testFile = fileTestSave.get("testFile");
//get the fileURL from the PFFile to generate the http request
var fileURL = testFile["url"]();
//return the promise from the httpRequest
return Parse.Cloud.httpRequest({
method:"GET",
url: fileURL
}).then(function(httpResponse){
//return the promise from the parsing
return parsehttpResponse(httpResponse,fileTestSave);
},
function(error){
console.log("http response error");
}
);
}
function parsehttpResponse(httpResponse,fileTestSave)
{
var jsonArray = eval( '(' + httpResponse.text + ')' );
var saveArray =[];
//parse each person in the json string, and add them to the saveArray for bulk saving later.
for (i in jsonArray)
{
var personExtend = Parse.Object.extend("Person");
var person = new personExtend();
person.set("classDiscriminator",jsonArray[i]["classDiscriminator"]);
person.set("lastName",jsonArray[i]["lastName"]);
person.set("firstName",jsonArray[i]["firstName"]);
person.set("employeeID",jsonArray[i]["employeeID"]);
saveArray.push(person);
};
//return the promise from the saveAll(bulk save)
return Parse.Object.saveAll(
saveArray
).then(function(){
//return the promise from the destory
return fileTestSave.destroy(
).then(function(){
},function(error){
console.log("error destroying");
}
);
},function(error){
console.log("Error Saving");
}
);
}
Run Code Online (Sandbox Code Playgroud)
作为参考超时的旧Cloud Code:
Parse.Cloud.afterSave("fileTestSave", function(request) {
//When accessing PFFiles you don't get the actual data, there may be an easier way, but I just utitlized an HTTPRequest to get the data, and then continued parsing.
var file = request.object.get("testFile");
var fileURL = file["url"]();
console.log("URL:"+fileURL);
Parse.Cloud.httpRequest({
method:"GET",
url: fileURL,
success: function(httpResponse)
{
var jsonArray = eval( '(' + httpResponse.text + ')' );
var saveArray =[];
for (i in jsonArray)
{
var personExtend = Parse.Object.extend("Person");
var person = new personExtend();
//May be a better way to parse JSON by using each key automatically, but I'm still new to JS, and Parse so I set each individually.
person.set("classDiscriminator",array[i]["classDiscriminator"]);
person.set("lastName",array[i]["lastName"]);
person.set("firstName",array[i]["firstName"]);
person.set("employeeID",array[i]["employeeID"]);
saveArray.push(person);
};
Parse.Object.saveAll(saveArray,
{
success: function(list) {
// All the objects were saved.
},
error: function(error) {
// An error occurred while saving one of the objects.
},
});
},
error: function(httpResponse) {
console.log("http response error");
}
});
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5576 次 |
| 最近记录: |