Modify the Program

Now that you've done with the tutorial, you can start implementing your mobile app by referring to the iOS Programming Guide. As a practice, let's make some modifications to our sample application.

Hello Kii allows you to delete an item by tapping it in the list. Let's modify this function so that the same action will update the content. That is, MyObject n will change to the current time in the HH:mm:ss format when an item is tapped.

The logic to run when an item is tapped in the list is defined in the tableView(_:didSelectRowAt:) method in MainViewController.swift and MainViewController.m. We will remove all the codes in the method first.

  • func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    }
  • - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    }

Copying sample code

There are several ways for updating KiiObjects. Let us fully update KiiObjects without overwriting check in this tutorial. See Full Update without the Overwrite Check in the programming guide for more information about updating KiiObjects.

The programming guide presents the sample code for the blocking and non-blocking APIs. As we've explained in the tutorial, we will use the non-blocking API since we are not maintaining the worker thread in Hello Kii.

Now, copy and paste the sample code in the programming guide into the source file. The below screen shows a sample of copying sample code for Swift 3.0. The corresponding sample code is available for Objective-C as well.

  • func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      // Update key-value pairs.
      object.setObject(NSNumber(value: 1 as Int), forKey: "myid")
      object.setObject("John Doe Jr", forKey: "name")
      object.setObject("john_jr@example.com", forKey: "email")
      object.remove(forKey: "address")
    
      // Save and fully update the KiiObject.
      // This method removes all key-value pairs from the KiiObject on the server and
      // adds the key-value pairs generated locally to the KiiObject.
      object.saveAllFields(true, with: { (object : KiiObject?, error : Error?) -> Void in
        if error != nil {
          // Handle the error.
          return
        }
      })
    }
  • - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
      // Update key-value pairs.
      [object setObject:[NSNumber numberWithInt:1]
               forKey:@"myid"];
      [object setObject:@"John Doe Jr"
               forKey:@"name"];
      [object setObject:@"john_jr@example.com"
               forKey:@"email"];
    
      // Save and fully update the KiiObject.
      // This method removes all key-value pairs from the KiiObject on the server and
      // adds the key-value pairs generated locally to the KiiObject.
      [object saveAllFields:YES
                  withBlock:^(KiiObject *object, NSError *error) {
        if (error != nil) {
          // Handle the error.
          return;
        }
      }];
    }

Fitting sample code

Next, we fit the sample code.

  • object in the sample code is the target KiiObject to update. The tapped KiiObject is obtained from objectList.
  • The setObject(_:forKey:) method in the sample code writes a dummy value. Modify the dummy value to the data to use in this tutorial. You can create it with the DateFormatter class of iOS.

Now the code looks like this:

  • func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      let object = self.objectList[indexPath.row]
    
      // Set the key-value pair.
      let df = DateFormatter()
      df.dateFormat = "HH:mm:ss"
      let value = df.string(from: Date())
      object.setObject(value, forKey: objectKey)
    
      // Save and fully update the KiiObject.
      // This method removes all key-value pairs from the KiiObject on the server and
      // adds the key-value pairs generated locally to the KiiObject.
      object.saveAllFields(true, with: { (object : KiiObject?, error : Error?) -> Void in
        if error != nil {
          // Handle the error.
          return
        }
      })
    }
  • - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
      KiiObject *object = _objectList[indexPath.row];
    
      // Set the key-value pair.
      NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
      dateFormatter.dateFormat = @"HH:mm:ss";
      NSString* value = [dateFormatter stringFromDate:[NSDate date]];
      [object setObject:value
                 forKey:OBJECT_KEY];
    
      // Save and fully update the KiiObject.
      // This method removes all key-value pairs from the KiiObject on the server and
      // adds the key-value pairs generated locally to the KiiObject.
      [object saveAllFields:YES
                  withBlock:^(KiiObject *object, NSError *error) {
        if (error != nil) {
          // Handle the error.
          return;
        }
      }];
    }

Next, we adjust the post-execution logic.

Most of the sample code blocks in the programming guide have no post-execution code inside the callback method. This time, we will add logic to refresh the list in case of successful update and to output a message in case of failure.

The final code after adding the post-execution logic will be as follows:

  • func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      let object = self.objectList[indexPath.row]
    
      // Set the key-value pair.
      let df = DateFormatter()
      df.dateFormat = "HH:mm:ss"
      let value = df.stringFromDate(NSDate())
      object.setObject(value, forKey: objectKey)
    
      // Save and fully update the KiiObject.
      // This method removes all key-value pairs from the KiiObject on the server and
      // adds the key-value pairs generated locally to the KiiObject.
      object.saveAllFields(true, with: { (object : KiiObject?, error : Error?) -> Void in
        if error != nil {
          self.showMessage("Update failed", error: error as NSError?)
          return
        }
        self.objectList[indexPath.row] = object!
        self.tableView.reloadData()
      })
    }
  • - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
      KiiObject *object = _objectList[indexPath.row];
    
      // Set the key-value pair.
      NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
      dateFormatter.dateFormat = @"HH:mm:ss";
      NSString* value = [dateFormatter stringFromDate:[NSDate date]];
      [object setObject:value
                 forKey:OBJECT_KEY];
    
      // Save and fully update the KiiObject.
      // This method removes all key-value pairs from the KiiObject on the server and
      // adds the key-value pairs generated locally to the KiiObject.
      [object saveAllFields:YES
                  withBlock:^(KiiObject *object, NSError *error) {
        if (error != nil) {
          [self showMessage:@"Update failed" error: error];
          return;
        }
        [self.objectList replaceObjectAtIndex:indexPath.row withObject:object];
        [self.tableView reloadData];
      }];
    }

Running

Now build and run the code. You should be able to change an object to show the current time by tapping it.


As we've presented, you can start your implementation by copying the sample code in the programming guide and by adjusting it a bit. By copying the sample code, you will be able to spot the method and the corresponding arguments easily. In this example, the saveAllFields(_:with:) method is called and KiiObject and Error are specified as the types of arguments for the closure.

If you want to know the specification of the API, you can check the appledoc written for Objective-C. Use them together with the iOS programming guide.


What's next?

We will wrap up the tutorial by presenting some hints to understand Kii Cloud. We will also introduce some features that will be useful when implementing some real mobile apps.

Go to Hints for Next Step.