doc/client-objc.txt in rhoconnect-3.0.5 vs doc/client-objc.txt in rhoconnect-3.0.6
- old
+ new
@@ -71,10 +71,12 @@
:::term
CREATE TABLE product (
"client_id" VARCHAR(255) default NULL);
+** NOTE: Do not use NOT NULL statement in column definitions. RhoConnect client delete object attributes by setting value to null, when all object attributes become nulls, object deleted. So objects with NOT NULL columns will not be deleted. **
+
## Coding a RhoConnect Client
This section discusses the general steps you perform to code a RhoConnect client in Objective C, using the store example. It is not a tutorial for coding a complete Xcode application, but instead discusses the RhoConnect code that you need to create.
### Initialize the Database
@@ -178,10 +180,11 @@
[[self navigationController] pushViewController:waitPage animated:YES];
[ [RhoConnectEngine sharedInstance].syncClient loginWithUser:txtLogin.text pwd:txtPassword.text callback:@selector(loginComplete:) target:self];
}
+
### Synchronize Data
Call the RhoConnectClient setNotification method to call a callback method that notifies about the state of the synchronization.
:::cplusplus
@@ -208,10 +211,35 @@
{
[[self navigationController] pushViewController:homePage animated:YES];
[ [RhoConnectEngine sharedInstance].syncClient clearNotification];
}else if ([notify.status compare:@"error"] == 0)
{
+ if([notify.error_message caseInsensitiveCompare:@"unknown client"] == 0) {
+ [[RhoConnectEngine sharedInstance].syncClient database_client_reset];
+ [[RhoConnectEngine sharedInstance].syncClient setNotification: @selector(syncAllCalback:) target:self];
+ [[RhoConnectEngine sharedInstance].syncClient syncAll];
+ } else if( err_code == RHO_ERR_CLIENTISNOTLOGGEDIN
+ || err_code == RHO_ERR_UNATHORIZED) {
+
+ NSLog(@"GO TO LOGIN PAGE!");
+ // real code to trigger view transition goes here..
+ }else
+ {
+ //This is mandatory:
+ if([notify hasCreateErrors]) {
+ [[RhoConnectEngine sharedInstance].syncClient onCreateError: notify @"delete"];
+ }
+ //These are optional:
+ /*
+ if([notify hasUpdateErrors]) {
+ [[RhoConnectEngine sharedInstance].syncClient onUpdateError: notify @"rollback"];
+ }
+ if([notify hasDeleteErrors]) {
+ [[RhoConnectEngine sharedInstance].syncClient onDeleteError: notify @"retry"];
+ }
+ */
+ }
}
}
- (void)loginComplete:(NSString*) errorMessage
{
@@ -225,10 +253,118 @@
lblMessage.text = errorMessage;
self.navigationItem.hidesBackButton = false;
}
}
+### Processing unknown-client error
+Unknown client error return by server after resetting server database, removing particular client id from database or any other cases when server cannot find client id(sync server unique id of device).
+Note that login session may still exist on server, so in this case client does not have to login again, just create new client id.
+Processing of this error contain 2 steps:
+
+* When unknown client error is come from server, client should call database_client_reset and start new sync, to register new client id.
+
+* If login session also deleted or expired on the server, then customer has to login again.
+
+Example:
+ :::cplusplus
+
+ - (void)syncAllComplete:(RhoConnectNotify*) notify
+ {
+ NSString* status = notify.status;
+ NSString* error = notify.error_message;
+ int err_code = notify.error_code;
+
+ NSLog(@"syncAll DONE, status: '%s' , error_msg: '%s' , error_code: %d",
+ [status cStringUsingEncoding: NSUTF8StringEncoding],
+ [error cStringUsingEncoding: NSUTF8StringEncoding],
+ err_code
+ );
+
+ if ( [notify.status compare:@"in_progress"] == 0) {
+
+ } else if ([notify.status compare:@"complete"] == 0) {
+
+ [[RhoConnectEngine sharedInstance].syncClient clearNotification];
+
+ } else if ([notify.status compare:@"error"] == 0) {
+
+ if([notify.error_message caseInsensitiveCompare:@"unknown client"] == 0) {
+ [[RhoConnectEngine sharedInstance].syncClient database_client_reset];
+ [[RhoConnectEngine sharedInstance].syncClient setNotification: @selector(syncAllCalback:) target:self];
+ [[RhoConnectEngine sharedInstance].syncClient syncAll];
+ } else if( err_code == RHO_ERR_CLIENTISNOTLOGGEDIN
+ || err_code == RHO_ERR_UNATHORIZED) {
+
+ NSLog(@"GO TO LOGIN PAGE!");
+ // real code to trigger view transition goes here..
+ }
+ }
+ }
+
+### Processing server errors
+* create-error:
+has to be handled in sync callback. Otherwise sync will stop on this model. To fix create errors you should call Model.on_sync_create_error or SyncEngine.on_sync_create_error:
+
+* update-error:
+If not handled, local modifications, which were failing on server, will never sync to server again.
+So sync will work fine, but nobody will know about these changes.
+
+* delete-error:
+If not handled, local modifications, which were failing on server, will never sync to server again.
+So sync will work fine, but nobody will know about these changes.
+
+Example:
+ :::cplusplus
+
+ - (void)syncAllCalback:(RhoConnectNotify*) notify
+ {
+ NSString* status = notify.status;
+ NSString* error = notify.error_message;
+ int err_code = notify.error_code;
+
+ NSLog(@"syncAll DONE, status: '%s' , error_msg: '%s' , error_code: %d",
+ [status cStringUsingEncoding: NSUTF8StringEncoding],
+ [error cStringUsingEncoding: NSUTF8StringEncoding],
+ err_code
+ );
+
+ if ( [notify.status compare:@"in_progress"] == 0) {
+
+ } else if ([notify.status compare:@"complete"] == 0) {
+
+ [[RhoConnectEngine sharedInstance].syncClient clearNotification];
+
+ } else if ([notify.status compare:@"error"] == 0) {
+
+ if([notify isUnknownClientError]) {
+ [[RhoConnectEngine sharedInstance].syncClient database_client_reset];
+ [[RhoConnectEngine sharedInstance].syncClient setNotification: @selector(syncAllCalback:) target:self];
+ [[RhoConnectEngine sharedInstance].syncClient syncAll];
+ } else if( err_code == RHO_ERR_CLIENTISNOTLOGGEDIN
+ || err_code == RHO_ERR_UNATHORIZED) {
+
+ NSLog(@"GO TO LOGIN PAGE!");
+ // real code to trigger view transition goes here..
+ }else
+ {
+ //This is mandatory:
+ if([notify hasCreateErrors]) {
+ [[RhoConnectEngine sharedInstance].syncClient onCreateError: notify action:@"delete"];
+ }
+ //These are optional:
+ /*
+ if([notify hasUpdateErrors]) {
+ [[RhoConnectEngine sharedInstance].syncClient onUpdateError: notify action:@"rollback"];
+ }
+ if([notify hasDeleteErrors]) {
+ [[RhoConnectEngine sharedInstance].syncClient onDeleteError: notify action:@"retry"];
+ }
+ */
+ }
+ }
+ }
+
### Search the Client Database for Models
Call a RhomModel find method (find, find\_first, find\_all) to find model objects in the client database. This code sample for the find\_all method fetches all the models in the database; you can also search for models containing certain attribute data.
:::cplusplus
@@ -269,10 +405,13 @@
* <a href="#syncAll">syncAll</a>
* <a href="#search">search</a>
* <a href="#setObjectNotification">setObjectNotification</a>
* <a href="#clearObjectNotification">clearObjectNotification</a>
* <a href="#addObjectNotify">addObjectNotify</a>
+ * <a href="#onCreateError">onCreateError</a>
+ * <a href="#onUpdateError">onUpdateError</a>
+ * <a href="#onDeleteError">onDeleteError</a>
### <a id="threaded_mode"></a>threaded\_mode property
BOOL. Set to false to get the result of operations as a return value. (Set to true to get notifications - not supported yet.) Default = false.
@@ -475,11 +614,90 @@
:::cplusplus
RhoConnectClient* sclient;
...
[sclient addObjectNotify: [[item objectForKey:@"source_id"] intValue] szObject:[item valueForKey:@"object"] ];
-
+
+### <a id="onCreateError"></a>onCreateError
+
+Instance method. To process 'create-error' errors from server.
+
+ :::cplusplus
+ - (void) onCreateError: (RhoConnectNotify*)notify action: (NSString*)action;
+
+<table border="1">
+<tr>
+ <td><code>notify</code></td>
+ <td>RhoConnectNotify. Notification object passed to notification callback.</td>
+</tr>
+<tr>
+ <td><code>action</code></td>
+ <td>NSString. May be "delete" or "recreate": "delete" just remove object from client, "recreate" will push this object to server again at next sync.</td>
+</tr>
+</table>
+
+Sample call:
+
+ :::cplusplus
+ RhoConnectClient* sclient;
+ ...
+ if ([notify hasCreateErrors])
+ [sclient onCreateError: notify action:@"delete" ];
+
+
+### <a id="onUpdateError"></a>onUpdateError
+
+Instance method. To process 'update-error' errors from server.
+
+ :::cplusplus
+ - (void) onUpdateError: (RhoConnectNotify*)notify action: (NSString*)action;
+
+<table border="1">
+<tr>
+ <td><code>notify</code></td>
+ <td>RhoConnectNotify. Notification object passed to notification callback.</td>
+</tr>
+<tr>
+ <td><code>action</code></td>
+ <td>NSString. May be "retry" or "rollback": "retry" will push update object operation to server again at next sync, "rollback" will write rollback objects(comes from server) to client database.</td>
+</tr>
+</table>
+
+Sample call:
+
+ :::cplusplus
+ RhoConnectClient* sclient;
+ ...
+ if ([notify hasUpdateErrors])
+ [sclient onUpdateError: notify action:@"retry" ];
+
+### <a id="onDeleteError"></a>onUpdateError
+
+Instance method. To process 'delete-error' errors from server.
+
+ :::cplusplus
+ - (void) onDeleteError: (RhoConnectNotify*)notify action: (NSString*)action;
+
+<table border="1">
+<tr>
+ <td><code>notify</code></td>
+ <td>RhoConnectNotify. Notification object passed to notification callback.</td>
+</tr>
+<tr>
+ <td><code>action</code></td>
+ <td>NSString. May be "retry" - will push delete object operation to server again at next sync.</td>
+</tr>
+</table>
+
+Sample call:
+
+ :::cplusplus
+ RhoConnectClient* sclient;
+ ...
+ if ([notify hasDeleteErrors])
+ [sclient onDeleteError: notify action:@"retry" ];
+
## RhomModel Class API
The RhomModel class contains the following properties and methods for setting and using RhomModel objects; RhomModel objects are RhoConnect models and their attributes.
* <a href="#name">name property</a>
@@ -749,9 +967,26 @@
</tr>
<tr>
<td><code>callback_params</code></td>
<td>@property(assign) NSString*. Callback parameters.</td>
</tr>
+<tr>
+ <td><code>hasCreateErrors</code></td>
+ <td>(Boolean). Return true if server return create-errors.</td>
+</tr>
+<tr>
+ <td><code>hasUpdateErrors</code></td>
+ <td>(Boolean). Return true if server return update-errors.</td>
+</tr>
+<tr>
+ <td><code>hasDeleteErrors</code></td>
+ <td>(Boolean). Return true if server return delete-errors.</td>
+</tr>
+<tr>
+ <td><code>isUnknownClientError</code></td>
+ <td>(Boolean). Return true if server return unknown client error.</td>
+</tr>
+
</table>
## RhoConnectObjectNotify Class API
This class provides access to the sync object notification as described [here](/rhodes/synchronization#notifications).