Search code examples
objective-cswiftxcodepodio

Is there a workaround to avoid error when saving PKTItem containing a 'Calculation' field?


If a PKTItem contains a 'Calculation' field, save() fails:

item["owner"] = myProfile
item.save()
.onSuccess {(savedItem : PKTItem!) in
    print("new owner is me: \(myProfile.name)")
}
.onError {error in
    print("Error: \(error.localizedDescription)")
}

The result is Error: Values cannot be set directly for field with id 126020899 (126020899 is the calculation field).

However if no 'Calculation' field is present, the code run as expected and the "owner" field is updated.

Is it simply impossible to save items containing 'Calculation' fields? If not, how might I go about doing it?

[Edit] What I really need is a way to save changes to individual fields rather than calling save() on the entire PKTitem instance. This makes the most sense to me since I really only need to update one field. To be clear, the field I'm trying to update is NOT a 'Calculation' field. The field value I'm trying to change is a PKTProfile instance and it exists within a PKTItem instance that also contains several 'Calculation' fields. If it were up to me, I'd get rid of the 'Calculation' fields, but they are an important part of our workflow at the moment.

Note: I'm basing my example off the one given in the PodioPlatformKit SDK. While the PodioPlatformKit is depreciated, this potion is the same in PodioKit. I only use it because it gives examples in Swift rather than Objective-C. The equivalent Objective-C example is here.


Solution

  • The workaround I figured out is quite simple. I changed the save method in the PKTItem.m file like so:

    - (PKTAsyncTask *)save {
      __block PKTAsyncTask *task = nil;
    
      PKTClient *client = [PKTClient currentClient];
    
      [client performBlock:^{
    task = [[PKTApp fetchAppWithID:self.appID] pipe:^PKTAsyncTask *(PKTApp *app) {
      __block PKTAsyncTask *saveTask = nil;
    
      NSArray *itemFields = [self allFieldsToSaveForApp:app];
    
      // Filter out all fields of type PKTAppFieldTypeCalculation, which is the 'Calculation' type
      NSMutableArray *mutItemFields = [NSMutableArray new];
        for (PKTItemField* o in itemFields) {
            if ([o type] != PKTAppFieldTypeCalculation) {
                [mutItemFields addObject:o];
            }
        }
        NSArray *filteredItemFields = [mutItemFields copy];
      [client performBlock:^{
        saveTask = [self saveWithItemFields:filteredItemFields];
       }];
    
      return saveTask;
      }];
     }];
       return task;
     }