Search code examples
iosobjective-ccloudparse-platform

Parse.com : Pass an array of dictionaries to backgroundJob through httprequest


I have an array containing all contacts of addressbook. My requests always timeout when I saveAll in client side and in cloudcode, resulting in partially saving the contact list. This is the reason why I want to use cloudcode backgroundjob.

I cannot find a way to pass my array to the background job. How can I do that?

iOs client calling httpRequest and passing allItems

 [PFCloud callFunctionInBackground:@"httpRequest" withParameters:@{@"myArray" :allItems} block:^(NSString *result, NSError *error) {
        if (!error) {
            NSLog(@"Result is: %@", result);
        }
    }];

my httpRequest

Parse.Cloud.define('httpRequest', function(request, response) {
  var body =  request.params.myArray;

  Parse.Cloud.httpRequest({
      method: "POST",
      url: "https://api.parse.com/1/jobs/userMigration",
      headers: {
        "X-Parse-Application-Id": "...",
         "X-Parse-Master-Key": "...",
         "Content-Type": "application/json"
      },
      body:
        "body" : body;
      ,
      success: function(httpResponse) {
        console.log(httpResponse);
      },
      error: function(error) {
        console.log("ERROR"); 
      }
    });
});

my background job function. (this function is working fine when used as a basic cloudcode function)

Parse.Cloud.job("userMigration", function(request, status) {
  // Set up to modify user data
  var array = request.params.myArray;
  var arr = new Array();
  var user = request.user;

  array.forEach(function(entry) {
      var Contact = Parse.Object.extend("Contacts");
      var contact = new Contact();
      contact.set("name", entry.name);
      contact.set("email", entry.email);
      contact.set("phone", entry.phone);
      contact.set("phoneFormated", entry.phoneFormated);
      contact.set("userId", user);
      arr.push(contact);
  });
    Parse.Object.saveAll(arr, {
        success: function(objs) {
            // objects have been saved...
            reponse.success("object saved")
        },
        error: function(error) { 
            // an error occurred...
            response.error("mistake")
        }
    });
});

Solution

  • Have you tried passing the array as JSON ? Like :

    ...
          body: JSON.stringify(body),
    ...
    

    and in the background job :

      var array = JSON.parse(request.body);
    

    Also, note that your cloud function will wait for the response of the background job, so your cloud function is still likely to timeout (but I'm not sure if the background job will be killed or not).

    If you have the free plan in parse.com, don't forget you can only have one background job running at the same time. That's why calling a background job from your iOS application is not a good solution. Maybe you should try schedule the background job directly from parse.com or calling multiple cloud function / save.

    I think the best solution for you is something like that :

    NSUInteger arraySize = 10;
    __block NSUInteger callCount = array.length / arraySize; // the number of call to saveAll you will make
    
    for (NSUInteger i = 0 ; i < array.length / arraySize ; ++i) {
        NSArray * tmpArray = [allItems subarrayWithRange:NSMakeRange(i * arraySize, arraySize)];
    
        [PFObject saveAllInBackground:tmpArray block:^(BOOL succeeded, NSError *error) {
            callCount--;
            if (succeeded) {
                if (callCount < 0) {
                    NSLog(@"last item has been saved");
                }
            } else {
                // handle error
            }
        }];
    }