Blocking vs. Non-Blocking API

Many of our SDK methods, such as registering a new user and uploading data, require network communication with the Kii Cloud. The Kii Cloud SDK for Android provides both blocking and non-blocking versions of these methods.

Threading model in application

Avoid directly accessing the network from UI threads when you use the Kii Cloud SDK.

  • Android, iOS and HTML5 adopt an event-driven architecture. When application developers make some actions (e.g. clicking a button or scrolling a screen), the dedicated event handler will be called. All UI-triggered events will be handled by the dedicated UI thread, so the executing time-consuming process in this thread will degrade the overall performance of the application.

Accessing Kii Cloud server can usually take up to a few dozen of milliseconds. If the network condition is bad, it might even take a few seconds. Executing these features in the UI thread, therefore, is a big no-no.

Client SDK API

Some of the APIs provided by the client SDK do not require any networking while other APIs do require the network accesses. For those APIs that require some network accesses, Kii Cloud client SDK provides both non-blocking and blocking APIs.

API without network access

This type of API will return the result instantly because the process is executed on the device (e.g. fetching values from an Object).

API with network access - Blocking API

This type of API will send an HTTPS request to Kii Cloud and waits for the response. It will block the process until it gets the response from Kii Cloud.

To prevent blocking the overall application, you should make a worker thread and call this type of API from this worker thread, as shown in the diagram below.

If any problem occurs at runtime, this type of API returns an exception in a platform-dependent way. An exception is thrown on a platform such as Android and Swift. An exception object is returned on a platform such as Objective-C.

API with network access - Non-blocking API

This type of API will also send an HTTPS request to Kii Cloud, but it will handle the network access in a background and return the control instantly. The result will be notified with a callback passed to the API.

You can call this type of API from a UI thread. The callback execution by the SDK will be also made in the UI thread.

When an error occurs, it will be usually notified using an exception object in the callback argument. Some errors, like invalid parameters, could be thrown at the time when you call the API.

For the mobile application development, non-blocking APIs are handy because you do not have to manage multiple threads. You might, however, want to use blocking API when you want to call sequentially multiple APIs or need to coordinate with other background processes.

In any cases, take note that your process might take some time to finish. Make sure to design your mobile application so as to prevent the duplicating execution and such.

Sample code

In the guides, we generally provide sample code for both non-blocking and blocking APIs.

Here is the sample code for registering a new user with a blocking API.

Swift:

let user = KiiUser(username: "my_username", andPassword: "mypassword")

do{
  try user.performRegistrationSynchronous()
} catch let error as NSError {
  // Handle the error.
  return
}

Objective-C:

NSError *error;
KiiUser *user = [KiiUser userWithUsername:@"my_username"
                              andPassword:@"mypassword"];
[user performRegistrationSynchronous:&error];
if (error != nil) {
  // Handle the error.
}

For actual application development, if you aren't handling threading on your own, you may want to use non-blocking APIs instead to keep your main thread from freezing the UI. Kii iOS SDK provides the following two ways of executing a method asynchronously, in a non-blocking way:

  1. Using Blocks
  2. Using Callbacks

We recommend using the Blocks if you are starting a new implementation. Some APIs do not support the Callbacks.

Unlike the Android SDK, you can call a blocking API from the main thread in the iOS SDK. To prevent your application from "freezing", however, we encourage you to either use a non-blocking API or call a blocking API from a background thread.

Using blocks

Here is an example of using a block-based function. The block mechanism allows a function to be performed in a background thread, and the result will be returned to the main thread.

Swift:

let user = KiiUser(username: "my_username", andPassword: "mypassword")

user.performRegistration { (user :KiiUser?, error : Error?) -> Void in
  if (error != nil) {
    // Handle the error.
  }
}

Objective-C:

KiiUser *user = [KiiUser userWithUsername:@"myusername"
                              andPassword:@"mypassword"];
[user performRegistrationWithBlock:^(KiiUser *user, NSError *error) {
  if (error != nil) {
    // Handle the error.
  }
}];

For more information on how to use non-blocking APIs, see the appledoc. If you are not familiar with blocks, see iOS Developer Library.

Using callbacks

The following sample code illustrates how to invoke the same feature with a callback-based function. In this case, we are setting a callback for getting the notification when the method execution is done.

Swift:

class myDelegate : NSObject{
  func userRegistered(user:KiiUser?, error: Error?){
    print("User registered: \(user) withError: \(error)")
    if (error != nil) {
      // Handle the error.
    }
  }
  func test_asynchronous_example(){
    let user = KiiUser(username: "my_username", andPassword: "mypassword")
    user.performRegistration(self, withCallback: Selector(("userRegistered")))
  }
}

Objective-C:

- (void) userRegistered:(KiiUser*)user withError:(NSError*)error {
    NSLog(@"User registered: %@ withError: %@", user, error);

    if (error != nil) {
        // Handle the error.
    }
}

- (void) test_asynchronous_example {
    KiiUser *user = [KiiUser userWithUsername:@"my_username"
                                  andPassword:@"mypassword"];
    [user performRegistration:self
                 withCallback:@selector(userRegistered:withError:)];
}

For more information on how to use non-blocking APIs, see the appledoc.

Whether to use blocking APIs or non-blocking APIs depends on the situation. Typically, using non-blocking APIs will allow you to implement you application easily. If your application needs to execute multiple processes serially, however, you might want to create a background thread and use blocking APIs to execute the processes in the correct order.