Sybase Sup Clientobjectapi Cookbook

   EMBED

Share

Preview only show first 6 pages with water mark for full document please download

Transcript

Sybase Unwired Platform 1.0 Client Object API Cookbook DOCUMENT ID: DC00836-01-0100-01 LAST REVISED: September 2008 Copyright © 2008 by Sybase, Inc. All rights reserved. This publication pertains to Sybase software and to any subsequent release until otherwise indicated in new editions or technical notes. Information in this document is subject to change without notice. The software described herein is furnished under a license agreement, and it may be used or copied only in accordance with the terms of that agreement. To order additional documents, U.S. and Canadian customers should call Customer Fulfillment at (800) 685-8225, fax (617) 2299845. Customers in other countries with a U.S. license agreement may contact Customer Fulfillment via the above fax number. All other international customers should contact their Sybase subsidiary or local distributor. Upgrades are provided only at regularly scheduled software release dates. No part of this publication may be reproduced, transmitted, or translated in any form or by any means, electronic, mechanical, manual, optical, or otherwise, without the prior written permission of Sybase, Inc. Sybase trademarks can be viewed at the Sybase trademarks page at http://www.sybase.com/detail?id=1011207. Sybase and the marks listed are trademarks of Sybase, Inc. ® indicates registration in the United States of America. Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. All other company and product names mentioned may be trademarks of the respective companies with which they are associated. Use, duplication, or disclosure by the government is subject to the restrictions set forth in subparagraph (c)(1)(ii) of DFARS 52.227-7013 for the DOD and as set forth in FAR 52.227-19(a)-(d) for civilian agencies. Sybase, Inc., One Sybase Drive, Dublin, CA 94568. 2 Client Object API Cookbook 1. INTRODUCTION AND REQUIREMENTS ................................................... 5 1.1. Introduction ...................................................................................................................................5 1.2. Requirements .................................................................................................................................5 1.3. Overview.........................................................................................................................................5 1.4. Code Generation from Unwired WorkSpace..............................................................................6 1.5. Code Generation API ....................................................................................................................8 1.6. Client API Dependencies ..............................................................................................................9 1.6.1. Project Setup........................................................................................................................10 2. 3. 3.1. 3.2. 3.3. TERMINOLOGY ........................................................................................ 10 GENERAL ................................................................................................. 11 Generated and core (fixed) class organization..........................................................................11 The Managers ..............................................................................................................................11 Generic List..................................................................................................................................11 4. MANAGING CONNECTIONS.................................................................... 11 4.1.1. 4.1.2. 4.1.3. Creating a Connection ........................................................................................................11 Retrieving a Profile..............................................................................................................12 Database Utilities .................................................................................................................13 Synchronization Parameters ..............................................................................................13 Performing MBO synchronization.....................................................................................13 Performing a file synchronization......................................................................................14 Registering for SMS or HTTP Push Notifications............................................................14 Synchronization Status Listener ........................................................................................15 Synchronization Delays.......................................................................................................17 Retrieving Data from MBO ................................................................................................17 Retrieving Relationship Data .............................................................................................19 Paging Data ..........................................................................................................................20 MBO Operations .................................................................................................................20 Update Operation ................................................................................................................21 Delete Operation..................................................................................................................22 Original State .......................................................................................................................22 Parameters and Data Column Types and Sizes ................................................................22 Linked Parameters ..............................................................................................................23 Securing Data.......................................................................................................................23 Date, DateTime, Time data types .......................................................................................23 5. SYNCHRONIZATION ................................................................................ 13 5.1.1. 5.1.2. 5.1.3. 5.1.4. 5.1.5. 5.1.6. 6. MBO OBJECTS......................................................................................... 17 6.1.1. 6.1.2. 6.1.3. 6.1.4. 6.1.5. 6.1.6. 6.1.7. 6.1.8. 6.1.9. 6.1.10. 6.1.11. 7. PUSH ......................................................................................................... 24 7.1. SMS Push .....................................................................................................................................24 7.2. HTTP Push...................................................................................................................................25 7.2.1. HttpPushListener ................................................................................................................25 7.2.2. PushMessage ........................................................................................................................27 8. 8.1. 8.2. SYBASE.UNWIREDPLATFORM.COMMONS ASSEMBLY (UNSUPPORTED) MobileDevice................................................................................................................................27 NetworkUtilities...........................................................................................................................28 27 Sybase Unwired Platform 1.0 3 8.3. Windows.Forms .......................................................................................................................... 28 8.3.1. FormsManager.................................................................................................................... 28 8.3.2. StackFormsManager .......................................................................................................... 29 8.3.3. FormsManagerDataObject ................................................................................................ 31 9. 9.1. 9.2. SYBASE.UNWIREDPLATFORM.CONTROLS ASSEMBLY (UNSUPPORTED) 32 Introduction................................................................................................................................. 32 Visual Studio 2005 .NET Compact Framework 2.0 Projects.................................................. 32 10. MISCELLANEOUS ....................................................................................33 SMS Push Notification Messages........................................................................................... 33 Cleaning Up UltraLite Databases in Device Applications................................................... 34 10.1. 10.2. 4 Client Object API Cookbook 1. 1.1. Introduction Introduction and Requirements This programming cookbook includes a collection of solutions and examples for a variety of tasks and uses of the Sybase Unwired Platform (SUP) .NET Client API. Java will be available in a later release. 1.2. Requirements • Microsoft Visual Studio .NET 2005 Professional or higher. • Knowledge of Sybase Unwired Platform concepts and features. • The Sybase Unwired Platform 1.0 .NET API assemblies. • Sybase Unwired Platform code generation API (in Java). • .NET framework (and compact) 2.0+. Overview 1.3. Below is an overview of the data access stack from a mobile client. Client SUP Object Model Generated Client Object (Generated MBO and fixed classes) Data Persistence Library UltraLite API / Afaria API Unwired Server UL DB CDB Figure 1. Mobile client data access stack. The client application has three options as shown above to access data. However, the only supported API is the Generated Client Object API (shown in yellow). The Client Object API uses the Data Persistence Library in its implementation to access and store object data in the database on the device. Sybase Unwired Platform 1.0 5 The SUP Code Generation API generates the Client Object API. Here is a high level view of the code generation process (Unwired WorkSpace refers to the SUP development environment – either Eclipse Edition or Visual Studio Edition): Unwired WorkSpace/SI users Code Gen API TemplateJ (Code Gen Model) SUP Client Objects Code Generation options UEP Models in xml Templates Data Persistence Library Figure 2. Client Object API is generated by SUP Code generation. • • • • 1.4. Unwired WorkSpace in Eclipse Edition or Visual Studio Edition builds the mobile business object (MBO), or SI scripts/manually writes the deployment unit. Unwired WorkSpace calls the Code Generation API and provides MBO models and code generation objects as inputs. The Code Generation API executes TemplateJ with the given inputs. TemplateJ applies the correct Templates based on the given code generation options and the MBO model. TemplateJ outputs the Client Objects. Code Generation from Unwired WorkSpace Once the Mobile Development project is completed as desired, users can right click on the project, select “Generate Code,” and follow the instructions in the dialog to generate the client object code. 6 Client Object API Cookbook Sybase Unwired Platform 1.0 7 Note that for C#, we generate non-UI CF 2.0 compatible code regardless of what platform is selected. The generated code works with CF 2.0+ and full .NET Framework 2.0+. 1.5. Code Generation API The Client Object API can be generated from the Java code generation API instead of Unwired WorkSpace if MBO deployment is available. The MBO deployment unit can be extracted from the Mobile Development Project. import com.sybase.sup.codegen.client.CodeGenerator; import com.sybase.sup.codegen.client.impl.*; import java.util.HashMap; import java.io.*; public class CGMain { 8 Client Object API Cookbook public static void main(String[] args) { CodeGenerator cg = new SUPCodeGenerator(); HashMap cgOptions = new HashMap (); cgOptions.put(CodeGenerator.OPTION_META_DATA, CodeGenerator.META_DATA_NO); cgOptions.put(CodeGenerator.OPTION_PACKAGE_NAME, "Sybase.Test"); cgOptions.put(CodeGenerator.OPTION_LANGUAGE, CodeGenerator.LANGUAGE_CS); cgOptions.put(CodeGenerator.PLATFORM_WM_SP, CodeGenerator.PLATFORM_WM_SP); cgOptions.put(CodeGenerator.OPTION_META_DATA, CodeGenerator.META_DATA_YES); cg.generateCode (new File ("deployment_unit.xml"), "C:/tmp/SampleClientUsage", cgOptions); } } The JavaDocs for this is included in the Sybase Unwired Platform installation directory. 1.6. Client API Dependencies The client API assembly DLL dependencies as well as this cookbook are installed under the Sybase Unwired Platform installation directory. The contents of the client API directory are: • • • • • • • Afaria – Afaria assembly dependencies. apidocs – Code Generation API Javadocs. CodeGenModel – TemplateJ code generation model templates for .NET and Java. dpl\dotnet\API\bin – .NET Data Persistence Library and UltraLite assemblies. fixed – sources of the fixed classes that are used by the generated classes. lib – binaries of Code Generation API and fixed classes for .NET and Java (Rim, Java SE 5). dpl\dotnet\API\src – source code of the HTTP Push Listener included in the Sybase.UnwiredPlatform.Networking namespace. This source is included so developers can create their own custom HTTP Push Listener if needed. The dpl\dotnet\API\bin folder contains the following directory structure: • dpl – the Sybase Unwired Platform DPL assembly DLLs as individual files. o ce – files for use on Windows CE based systems. o win32 – files for use on full Windows based systems like Windows XP. • ultralite – the UltraLite assembly DLLs. o ce - Files for use on Windows CE based systems like Windows Mobile 5+. o win32 - Files for use on full Windows based systems like Windows XP. Sybase Unwired Platform 1.0 9 The assemblies listed above support CF 2.0+ on Visual Studio 2005 and 2008. Visual Studio Version Visual Studio 2005 (and 2008) Project Type Full .NET Framework 2.0+ Application Windows CE .NET CF 2.0+ Application Pocket PC .NET CF 2.0+ Application Smartphone .NET CF 2.0+ Application 1.6.1. Project Setup Add these as references in the Visual Studio project: • • Sybase.UnwiredPlatform.Data.UltraLite.dll iAnywhere.Data.UltraLite.dll iAnywhere.Data.UltraLite.resources.dll (there are several supported languages) • Add these as items in the Visual Studio project, and set “Build Action” to “Content” and “Copy to Output Director” to “Copy always”. • • ulnet10.dll mlcrsa.dll (if HTTPS protocol is used) 2. • • • Terminology Remote Client – refers to a user’s PDA, Smartphone, or PC. Remote Database or Remote Client Database – refers to the UltraLite database on a remote client that will be used to store the data. MBO – Mobile Business Objects. The fundamental unit of exchange in Sybase Unwired Platform is the MBO. An MBO corresponds to a data set from a back-end data source. The data can come from a database query, a Web service operation (including Remedy and Siebel), SAP, or a file (using Afaria). An MBO contains both concrete implementation-level details and abstract interface-level details. At the implementation-level, an MBO contains read-only columns that contain metadata about the data in the implementation, and parameters that are passed to the back-end data source. At the interface-level, an MBO contains attributes that map to columns, which correspond to client properties. An MBO may have operations, which can also contain parameters and arguments, and which may be used to create, update, or delete data. 10 Client Object API Cookbook 3. 3.1. General Generated and core (fixed) class organization Any classes for the client object API that are fixed and do not change will be part of the “core” classes (a.k.a fixed classes). All other classes are generated classes. Core classes will be provided in a package/namespace that is consistent with a language’s conventions. • .NET – Sybase.Persistence Note: Generated classes will not generate import statements due to issues with ambiguity. Fully qualified namespace will be used in generated classes. 3.2. The Managers The ConnectionManager and SynchronizationManager classes provide access to their respective portions of the Sybase.Persistence assembly. These classes follow the Singleton design pattern and are referenced using a static Instance property. Below are samples on how to acquire each of the manager classes. ConnectionManager cm = ConnectionManager.Instance; SynchronizationManager syncManager = SynchronizationManager.Instance; 3.3. Generic List Any part of the API that returns a generic List actually returns a clone of the original collection. This is useful when there is a need to delete an item while iterating over the collection to prevent the .NET Framework from throwing an InvalidOperationException. 4. 4.1.1. Creating a Connection Managing Connections Before synchronizing and getting MBO data, first set up a connection. Connection related classes in the Sybase.Persistence namespace: • Connection – a Connection is used to store information such as the host name of the MobiLink server, the MobiLink port, the username and password, etc. The Connection object also has a Name property that can be used to assign a convenient name to the Connection. Since the remote client database supports multiple Connections, the Name property must be unique. • ConnectionManager – the ConnectionManager provides a single access point for storing and retrieving and number of profiles from the remote client database. This is to create a Connection to an Unwired Server: Sybase Unwired Platform 1.0 11 Connection c = new Connection(); c.MobiLinkHost = "sup.sybase.com"; c.MobiLinkPort = 2439; c.MobiLinkStreamType = MobiLinkStreamType.Http; c.Name = "supAdmin"; c.Package = "Customer_1.0.0"; c.UserName = "supAdmin"; c.Password = "supAdmin"; c.Save(); //or //ConnectionManager.Instance.SaveConnection(c); Once the connection is set up and saved, it can be set as the default Connection. ConnectionManager.Instance.DefaultConnection = c; MBO classes use the default Connection to sync against the Unwired Server if the MBO.setConnection() is not set. 4.1.2. Retrieving a Profile To work with a Profile that has already been saved, retrieve the Profile from the ProfileManager. Connection conn = ConnectionManager.Instance.GetConnection("MyProfile"); Attempting to retrieve a Connection that has not been saved or does not exist will result in a null value being returned. This can be combined with the Connection creation code to check for a default Connection, and, if that default Connection does not exist, then create and save it. Connection c= ConnectionManager.Instance.GetConnection("MyProfile"); if(c == null) { c.MobiLinkHost = "sup.sybase.com"; c.MobiLinkPort = 2439; c.MobiLinkStreamType = MobiLinkStreamType.Http; c.Name = "supAdmin"; c.Package = "Customer_1.0.0"; c.UserName = "supAdmin"; c.Password = "supAdmin"; c.Save(); } 12 Client Object API Cookbook 4.1.3. Database Utilities The underlying storage is an UltraLite database. The cache size and page size properties affect the performance of the client application. These properties can be set in the ConnectionManager. 5. 5.1.1. Synchronization Parameters Synchronization Synchronization parameters let you change the parameters used to retrieve data from an MBO during a synchronization session. Its primary purpose is as a means of partitioning data. By changing the synchronization you will effect what data you are working with (this includes searches) and synchronizing. CustomerSynchronizationParameters params = Customer.SynchronizationParameters(); params.State = "CA"; 5.1.2. Performing MBO synchronization In order to perform MBO synchronization, a Connection object must be saved. See Creating a Connection for more information on how to create and save a Connection. Additionally, you might want to set some synchronization parameters before performing the sync. This syncs a Customer MBO using the default Connection: SynchronizationManager.Instance.SynchronizeApplication("Customer"); //or Customer.Synchronize() This syncs a Customer MBO using a specified Connection: Connection conn = ConnectionManager.GetConnection (“myconn”); SynchronizationManager.Instance.SynchronizeApplication(conn, "Customer"); //or Custoemr.SetConnection (conn); Customer.Synchronize() It is possible to synchronize multiple MBOs in one synchronization session. However, caution should be taken since performing simultaneous synchronizations on several very large Unwired Server applications can impact server performance; thus, possibly effecting other remote users as well. The following code sample demonstrates how to synchronize multiple MBO in one synchronization session. SynchronizationManager.Instance.SynchronizeApplications(conn, new string[] {"Customer", "SalesOrder"}); Sybase Unwired Platform 1.0 13 5.1.3. Performing a file synchronization Synchronizing a file MBO is the same as synchronizing regular MBOs except that the file content is saved in a physical location on the client. UserPDF.Synchronize(); string path = UserPDF.getFile() 5.1.4. Registering for SMS or HTTP Push Notifications During an MBO synchronization a custom .NET client can inform the Unwired Server to send push notifications when the MBO data changes. To register for push notifications an optional PushConfiguration object is supplied to the SynchronizationManager Synchronize method. The PushConfiguration object contains information such as the phone number of the mobile device for SMS Push, or an IP address, or the hostname of the computer for HTTP Push; an optional security token; and a pass back value that is returned to the remote client when a push notification message is sent. PushConfiguration push = new PushConfiguration(); push.Address = "+14157778888"; push.DeviceId = "myuniqueid"; push.Protocol = "UASMS"; push.PushRegistration = "Y"; push.SecurityToken = "1234"; push.MobileBusinessObject="myclient"; SynchronizationManager.Instance.SynchronizeApplication("Customer", push, true); Valid options for the Protocol property include “UASMS”, “UAHTTP”, and “UAMAIL”. Due to limitations of network connectivity in GPRS capable Windows Mobile devices, the use of IP number tracking and HTTP push notifications is not a viable solution. When used on Windows Mobile devices the Client Object API only supports using the “UASMS” protocol flag. Similarly, due to limitations in Win32 systems the Client object API only supports using the “UAHTTP” protocol flag when used on Win32 systems. When using HTTP Push, the Address property of the PushConfiguration object must be in the following format: http://:;mode=direct is the host name or IP address of the client registering for push notifications and is the port on which the push notifications will be sent. The “;mode=direct” suffix must appear at the end of the hostname/IP address and port. This additional piece of information is needed to instruct Unwired Server that the HTTP Push message is being sent directly to a remote client, and is required for HTTP Push to work. The use of e-mail based push and the “UAMAIL” flag is intended for the BlackBerry client. 14 Client Object API Cookbook 5.1.5. Synchronization Status Listener A synchronization status listener can be implemented to track the progress of running synchronization in a custom .NET client. To track synchronization status changes in a custom client, create a new class that implements the SyncStatusListener interface and pass an instance of that class to the SynchronizationManager when a new synchronization is started. MySyncListener listener = new MySyncListener(); //implements SyncStatusListener SynchronizationManager.Instance.SynchronizeApplication("Customer", listener); As the application synchronization progresses, the ApplicationSyncStatus method defined by the SyncStatusListener interface is called and is passed an ApplicationSyncStatusData object. The ApplicationSyncStatusData object contains information about the MBO being synchronized, the Connection to which it is related, and the current state of the synchronization process. By testing the State property of the ApplicationSyncStatusData object and comparing it to the possible values in the SyncStatusState enumeration a custom client can react accordingly to the state of the synchronization. Possible uses include changing form elements on the client’s screen to show the progress of the sync, such as showing a green image when the synchronization is in progress, a red image if the synchronization fails, and a gray image when the synchronization has completed successfully and disconnected from the server. Note that the ApplicationSyncStatus method of the SyncStatusListener are called and executed in the data synchronization thread. If a custom client runs synchronizations in a thread that is not the primary user interface thread then the custom client will not be able to update the client screen as the status changes. In this case, a custom client needs to use Control.Invoke, or a similar technique, to instruct the primary user interface thread to update the screen regarding the current synchronization status. For example: Create a class called SyncListener. Implement SyncStatusListener interface. In ApplicationSyncStatus method, create switch to catch the state during synchronization. //Create a class call SyncListener //add to your .net project using System; using Sybase.Persistence; namespace YourNameSpaceHere { public class SyncListener: SyncStatusListener { #region ISyncStatusListener Members public bool Sybase Unwired Platform 1.0 15 ApplicationSyncStatus(Sybase.UnwiredPlatform.Data.ApplicationSyncStatusData data) { switch (data.State) { case Sybase.UnwiredPlatform.Data.SyncStatusState.ApplicationSyncDone: //implement your own UI indicator bar break; case Sybase.UnwiredPlatform.Data.SyncStatusState.MetaSyncDone: //implement your own UI indicator bar break; case Sybase.UnwiredPlatform.Data.SyncStatusState.MetaSyncError: //implement your own UI indicator bar break; case Sybase.UnwiredPlatform.Data.SyncStatusState.ApplicationSyncError: //implement your own UI indicator bar break; case Sybase.UnwiredPlatform.Data.SyncStatusState.SyncDone: //implement your own UI indicator bar break; case Sybase.UnwiredPlatform.Data.SyncStatusState.SyncStarting: //implement your own UI indicator bar break; } return (false); } #endregion } } To synchronize with the listener, create a SyncListener instance. SyncListener syncListener = new SyncListener(); Connection conn = ConnectionManager.GetConnection (“myconn”); SynchronizationManager.Instance.SynchronizeApplication(conn, "Customer", syncListener); //or Customer.SetConnection (conn); Customer.Synchronize(syncListerner) 16 Client Object API Cookbook 5.1.6. Synchronization Delays To prevent concurrent synchronization errors in the Unwired Server, client applications need to introduce at least a two second delay between syncs. Even when the client completes the sync request, the Unwired Server might still be processing the end synchronization phase. For example, if the client application performances synchronization in a loop, a delay before the next sync request will ensure that the Unwired Server completes the previous sync request. Depending on the Unwired Server load, the client application might want to increase the delay. 6. 6.1.1. Retrieving Data from MBO MBO Objects To retrieve data from an MBO, use one of the static FindBy methods in the MBO class. Named FindBy methods are defined in the Unwired WorkSpace developer environment by the modeler and result in the generation of FindBy methods with whatever parameters and return type were defined in Unwired WorkSpace. FindBy methods return a collection of objects that match the specified search criteria defined in the named query. This retrieves a Customer by Id (Unwired WorkSpace defines Id as the only FindBy which is similar to a primary key in a database). Customer customer = Customer.FindById(101); If Unwired WorkSpace defines more than one FindBy attribute and we are using the FindById to get the customers, the Customer MBO returns a list. List customers = Customer.FindById(101); Also in this case where there are more than one FindBy attributes defined, a single Customer object is returned when calling the FindBy. List customers = Customer.FindBy(101, “Sybase”); Note that the FindBy method is always generated and returns a List of the MBO object regardless of the number of FindBy attributes defined. To get all the Customers, call the FindAll method. List customers = Customer.FindAll(); Sybase Unwired Platform 1.0 17 6.1.1.1. Arbitrary Find The Arbitrary search is meant for custom device applications that need the ability to build queries on the fly based on a user’s input. In addition allowing for arbitrary search criteria the arbitrary find method also lets the user to specify a desired ordering of the results and object state criteria. For simplicity and future proofing a Query class will be included in the client object API’s core classes. The Query class will be the single object that is passed to the arbitrary search methods and will be composed of search conditions, object/row state filter conditions and data ordering information. For example, consider you wish to locate all Customer objects based on the following: FirstName = ‘John’ AND LastName = ‘Doe’ AND (State = ‘CA’ or State = ‘NY’) Customer is New or Updated Ordered by: LastName ASC, FirstName ASC, Credit DESC Skip the first 10 and take 5 Query props = new Query(); //define the attribute based conditions //assume the variable “camd” is a CustomerAttributeMetaData retrieved earlier //Note that camd is not required for arbitrary find operation, but just //for example purpose. Users can //pass in a string if they know the attribute name. R1 column name = attribute name. CompositeTest innerCompTest = new CompositeTest(); innerCompTest.CompositionType = TestType.OR; innerCompTest.AddFilter (new AttributeTest(camd.getState().getName(), “CA”,TestType.EQUALS)); //OR //innerCompTest.add (new AttributeTest ("state", "CA", TestType.EQUALS); innerCompTest.add(new AttributeTest(camd.getState().getName(), “NY”, TestType.EQUALS)); //innerCompTest.add (new AttributeTest ("state", "NY", TestType.EQUALS); CompositeTest outerCompTest = new CompositeTest(); outerCompTest.CompositionType(TestType.AND); outerCompTest.add(new AttributeTest(camd.getFirstName().getName(), “John”, TestType.EQUALS)); outerCompTest.add(new AttributeTest(camd.getLastName().getName(), “Doe”, TestType.EQUALS)); outerCompTest.add(innerCompTest); //define the ordering SortOrderCollection sort = new SortOrderCollection(); sort.add(new SortOrder(camd.getLastName().getName(), SortOrderType.Ascending)); //OR //sort.add ("lastname", SortOrderType.Ascending); 18 Client Object API Cookbook sort.add(new SortOrder(camd.getFirstName().getName(), SortOrderType.Ascending)); sort.add(new SortOrder(camd.getCredit().getName(), SortOrderType.Descending)); //define the ordering SortOrderCollection sort = new SortOrderCollection(); sort.add(new SortOrder(camd.getLastName().getName(), SortOrderType.Ascending)); //set the Query object props.TestCriteria = outerCompTest; props.ObjectState = ObjectState.NEW | ObjectState.UPDATED; props.SortOrderCollection = sort; props.Skip =10; props.Take = 5; List customers = Customer.Find(props); 6.1.2. Retrieving Relationship Data If there is a relationship between two MBOs, the parent MBO can access the associated MBO. Sybase Unwired Platform 1.0 19 To illustrate we will assume there are two MBOs defined in Unwired Server. One is called Customer and contains a list of customer data records. The second MBO is called SalesOrder and contains order information. Additionally, we will assume there is an association from Customers to Orders on the customer id column. The Orders application is parameterized to return order information for the customer id. Customer customer = Customer.FindBy (101); List orders = customer.Orders; 6.1.3. Paging Data On low memory devices retrieving 30,000 records from the database will likely cause the custom client to fail and throw an OutOfMemoryException. Consider using the Query object to limit the result set. 6.1.4. MBO Operations MBO operations are performed on the MBO instance. Operations in the model that are marked as Create, Update or Delete (CUD) operations will result in the creation of instance (non-static) operations in the generated client side objects. Any parameters in the CUD operation that are mapped to the object’s attributes will be internally handled by the client object API and will not be exposed. Any parameters not mapped to the object’s attributes will be left as parameters in the generated object API. Note: If the Sybase Unwired Platform Object model defines one instance of a create operation and one instance of an update operation, and all operation parameters are mapped to the Object’s attributes, then a convenience Save method can be automatically generated which, when called internally, determines if it should insert or update data to the local client side database. This generated save method is colloquially referred to as the “magic save” method. Under other situations, where there are multiple instances of create and/or update operations, it is not possible to automatically and smartly generate a magic Save method. 6.1.4.1. Insert Operations To execute insert operations on an MBO, create a new instance of the MBO, set the MBO attributes and then either call save() or the insert the operation name. Customer cust = new Customer(); cust.Fname = "supAdmin"; cust.Company_name = "Sybase"; cust.Phone = "777-8888"; cust.Save(); If a custom client needs to create a second customer record the custom client must create a new instance of the MBO and call its save method. 20 Client Object API Cookbook Note: An MBO can have multiple parents if it is in relationships, and when a new MBO instance is created for an insert operation, it has no knowledge of which parent to which to associate. For version 1.0, if the insert operation is added to the MBO, the MBO must be marked as “syncable” in order for Insert operations to work correctly. This limitation is scheduled to be addressed in a major EBF. To insert an order for an existing customer, first find the customer, and then create a sales order with the customer id retrieved: Customer customer = Customer.FindBy (101); SalesOrder order = new SalesOrder(); order.Cust_id = customer.Id; order.Order_date = DateTime.UtcNow; order.Region = "Eastern"; order.Sales_rep = 102; order.Id = 1001; order.Save(); SalesOrder.Synchronize(); //to get the latest customers and orders Customer.Synchronize(); 6.1.5. Update Operation To execute update operations on an MBO, get an instance of the MBO, set the MBO attributes, and then either call Save() or the update operation name. Customer cust = Customer.FindBy (101); cust.Fname = "supAdmin"; cust.Company_name = "Sybase"; cust.Phone = "777-8888"; cust.Save(); From a relationship, an update can be done like this: Customer cust = Customer.FindBy (101); List orders = cust.Orders; SalesOrder order = orders[0]; order.Order_date = DateTime.Now; order.Save(); Sybase Unwired Platform 1.0 21 6.1.6. Delete Operation To execute delete operations on an MBO, get an instance of the MBO, set the MBO attributes, and then call the delete operation name. Customer cust = Customer.FindBy (101); cust.Delete(); From a relationship, a delete can be done like this: Customer cust = Customer.FindBy (101); List orders = cust.Orders; SalesOrder order = orders[0]; order.Delete(); 6.1.7. Original State Before a client synchronizes a called instance operation, the original data values may be retrieved by calling a special property that returns the object as it was before the change(s). After synchronization is completed successfully, the special original value property is cleared and set to null. Customer cust = Customer.FindBy (101); cust.Fname = "supAdmin"; cust.Company_name = "Sybase"; cust.Phone = "777-8888"; cust.Save(); Customer org = cust.OriginalState; 6.1.8. Parameters and Data Column Types and Sizes By default, the Unwired Server stores all columns as char(300) columns. This can be customized by changing the Sybase Unwired Platform property. Edit sup.properties and change the string.maxlen=300 to a size that works with your application. Note: UltraLite char(n) columns have a maximum length of 2048 bytes. In order to store text data values longer than the 2048 byte maximum length, use the Data Type screen to set the following values: • • Data Type = Add New New Data Type = LONG VARCHAR By setting a column to LONG VARCHAR the UltraLite database will store the column as an arbitrary length long varchar column. 22 Client Object API Cookbook 6.1.9. Linked Parameters The linked parameters feature enables you to set up chained relationships among field/parameter values, and makes it easier to create and update applications. Chained relationships ensure that a selection the user makes limits subsequent selection choices to those logical to the initial choice. For example, selecting the state of California limits subsequent city choices to those in California. This feature is deferred. 6.1.10. Securing Data By default, UltraLite databases are unencrypted on disk and in permanent memory when they are created. Text and binary columns are plainly readable within the database file when using a viewing tool such as a hex editor. All UDB files created by the API can be encrypted to provide security against skilled and determined attempts to gain access to the data, but has a significant performance impact. Note that once the encryption key is set, you cannot change the encryption key unless the UDB file is deleted and recreated. Also, the API does not store the encryption key anywhere. It is up to the client application to provide the encryption key to the API when needed. The API creates UDB files based on a connection’s MobiLink host, MobiLink port number, and package values (.udb). Other connections with the same host name, port number, and package share the same UDB file. To encrypt these UDB files, set an encryption key using the Connection object's EncyptionKey property before the UDB file is created. UDB files are created when a connection is opened to the database for the first time. Note: If the Profile instance is retrieved from ConnectionManager, the Connection.EncryptionKey property needs to be set again. 6.1.11. Date, DateTime, Time data types Datetime, time, and date data types are set in UTC time zone in Unwired Server; however, the date and time fields are maintained when they are taken from EIS, such as datetime in Databases, with no time zone information. For EIS, such as Web Services, with time zone information in datetime data types, the Unwired Server converts them to UTC time zone. The Generated Object API returns DateTime object with the date time fields maintained in DateTimeKind.Unspecified kind. It is up to the client application to make sense of the DateTime object returned by the API. //show a date from Database EIS List orders = customer.Orders; foreach (SalesOrder order in orders) { DateTime orderDate = order.Order_date; MessageBox.Show(orderDate.ToString()); } //update date information List orders = customer.Orders; foreach (SalesOrder order in orders) { DateTime orderDate = DateTime.Parse ("9/12/2008 5:30 PM"); Sybase Unwired Platform 1.0 23 } //Convert a date to local time assuming the Date we get back is in UTC from Web Services CaseList mycase = CaseList.FindBy("HD10001"); DateTime caseDate = mycase.CaseDate; caseDate = new DateTime(caseDate.Ticks, DateTimeKind.Utc); caseDate = caseDate.ToLocalTime(); //set a UTC date for EIS after parsing it in local time CaseList newcase = new CaseList(); newcase.CaseDate = DateTime.Parse("10/1/2008 3:00 PM").ToUniversalTime(); 7. 7.1. SMS Push Push Custom clients can implement an SMS listener to receive SMS push messages from Unwired Server to synchronize MBOs. For example: //Your form must include namespace using Microsoft.WindowsMobile.PocketOutlook.MessageInterception; //Your reference must reference Microsoft.WindowsMobile Microsoft.WindowsMobile.PocketOutlook dll //Register for sms reciever on your Form’s Load method private void FormXYZ_Load(object sender, EventArgs e) { Program.NetworkUtilities.MessageInterceptor = new MessageInterceptor(InterceptionAction.NotifyAndDelete, true); Microsoft.WindowsMobile.PocketOutlook.MessageInterceptor.MessageCondition = new MessageCondition(MessageProperty.Body, MessagePropertyComparisonType.Contains, "mbo=customer"; Microsoft.WindowsMobile.PocketOutlook.MessageInterception.MessageReceived += new MessageInterceptorEventHandler(SmsPushMessageReceived); } public void SmsPushMessageReceived(object sender, MessageInterceptorEventArgs e) { //this method will be called if any sms push happen 24 Client Object API Cookbook Sybase.Persistence.Connection conn = Sybase.Persistence.ConnectionManager.Instance.DefaultConnection(); if (profile != null) { //Create your own auto login this.AutoLogin(); } } 7.2. HTTP Push HTTP Push is only supported on remote clients with network connections that allow inbound traffic and have a consistent IP address or hostname. Cellular providers typically do not allow inbound traffic to devices on their networks. Additionally, IP addresses for GPRS connections are usually pooled and change frequently as GPRS connections are established and dropped. Therefore, HTTP Push is neither a practical nor viable push method for cellular based network connections. This leaves HTTP Push best suited for 802.X LAN or WLAN connected clients. 7.2.1. HttpPushListener A simple HTTP Push listener class is included in the Sybase.UnwiredPlatform.Networking namespace. The source code for the listener is included in the client installation directory for customization purposes. When an HTTP Push message is received, a PushMessage object is passed to the client application hosting the HTTP Push listener. The following code demonstrates how to register for HTTP Push. //Register for HTTP Push notifications. PushConfiguration push = new PushConfiguration(); push.Address = “http://my_pc_hostname.mydomain.com:25000;mode=direct"; push.DeviceId = "myuniqueid"; push.Protocol = "UAHTTP"; push.PushRegistration = "Y"; push.SecurityToken = "1234"; push.MobileBusinessObject="myclient"; SynchronizationManager.Instance.SynchronizeApplication("Customer", push, true); The following code shows how to instantiate and start an HttpPushListener. //Create an HttpPushListener isntance, listen on all network connections on port 25000 HttpPushListener httpPushListener = new HttpPushListener(System.Net.IPAddress.Any, 25000); //assign an event handler for the HttpPushMessageReceived event Sybase Unwired Platform 1.0 25 httpPushListener.HttpPushMessageReceived += new HttpPushMessageReceivedEventHandler(HttpPushMessageReceivedHandlerProc); //assign an event handler for the HttpPushMessageError event httpPushListener.HttpPushMessageError += new HttpPushMessageErrorEventHandler(HttpPushMessageErrorHandlerProc); //start the HttpPushListener httpPushListener.Start(); Here is a sample implementation of the HttpPushListener event handlers. Both of these event handler methods are called by the HttpPushListener’s own processing thread. Therefore, these event handler methods are not called in the main user interface thread of a client application. If any user interface changes need to take place in these event handler methods the client application may hang or throw an exception. Therefore, be sure to use proper invocation techniques, such as the Control.Invoke method, so the user interface change takes place in the main user interface thread. public void HttpPushMessageReceivedHandlerProc(object sender, HttpPushMessageReceivedEventArgs e) { //push notification properties can be access via e.PushMessage //make sure the push message is not empty, this means the entire push //message was received and make sure it is meant for this client application if(!e.PushMessage.IsEmpty && e.PushMessage.ApplicationName == "MyApp") { //this is a valid push message, initiate a synchronization } } public void HttpPushMessageErrorHandlerProc(object sender, HttpPushMessageErrorEventArgs e) { //There was an error in processing the received push message //Any exception information can be accessed via e.Exception } The following code demonstrates how to stop and tear down the HttpPushListener. //unassign the HttpPushMessageReceived handler method httpPushListener.HttpPushMessageReceived -= new HttpPushMessageReceivedEventHandler(HttpPushMessageReceivedHandlerProc); //unassign the HttpPushMessageError handler method httpPushListener.HttpPushMessageError -= new HttpPushMessageErrorEventHandler(HttpPushMessageErrorHandlerProc); //stop the HttpPushListener thread 26 Client Object API Cookbook httpPushListener.Stop(); 7.2.2. PushMessage The PushMessage class contains the following properties. req_id=;op=sync;wid=;profile=;app=;mbo= • • • • • • ApplicationName – the “app” section of the push message. Operation – the “op” section of the push message. ProfileId – the “profile” section of the push message. RequestId – the “req_id” section of the push message. SecurityToken – the “token” section of the push message (not used by Unwired Server). WindowId – the “wid” section of the push message. For more details on the meanings of the sections of a push message please refer to the section of this document titled SMS Push Notification Messages. 8. Sybase.UnwiredPlatform.Commons Assembly (unsupported) 8.1. MobileDevice The MobileDevice class is provided as is and is only intended for use on physical Windows Mobile PocketPCs and Windows Mobile Smartphones. The behavior and results on emulators is not consistent and varies on different emulator versions. Using the MobileDevice class on anything other then actual Windows Mobile PocketPCs or Windows Mobile Smartphones is not supported. //Get the unique device ID for the Windows Mobile device. //MobileDevice.DeviceId can be used on non-telephone Windows Mobile PocketPCs as well. string deviceId = MobileDevice.DeviceId; //Get the device phone number, the device must be a phone. string phone = MobileDevice.PhoneNumber; //Get the device IMEI, the device must be a phone. string imei = MobileDevice.Imei Sybase Unwired Platform 1.0 27 8.2. NetworkUtilities The NetworkUtilities.IsNetworkConnectionActive property returns a Boolean true if there is an IP address other then the loopback 127.0.0.1 address assigned to the device. Having an IP address other then 127.0.0.1 means the device has an open network connection. However, having a network connection does not necessarily mean the internet or a particular server is currently accessible. This is similar to having a desktop PC connected to an internal company network but having the external gateway disabled. While the desktop PC has an IP address the internet and external servers can not be accessed. The IsNetworkConnectionActive property is intended to serve as a quick test to see if a network connection has been established. It is not intended to determine if a particular remote computer is accessible. Only an attempt to connect to a remote computer can determine if the remote computer is accessible or not. 8.3. Windows.Forms The Sybase.UnwiredPlatform.Windows.Forms namespace provides a set of utility classes for managing inter-form navigation and communication. Two different form manager classes are included. They are named FormsManager and StackFormsManager. Both form manager classes support caching forms to minimize the amount of device memory used by multiple screen applications. 8.3.1. FormsManager The FormsManager can be thought of as a forward-only form navigation/communication manager, since it does not track the history of form navigation steps. The forward-only nature of the FormsManager class makes it ideal for use in large multi-form applications that do not have a structured form navigation hierarchy. In order for a form that is managed by the FormsManager class to receive cross form communication messages as a form navigation step takes place, the form must implement the IFormsManagerForm interface. By implementing the IFormsManagerForm interface the forms class will implement a method named PassDataForward. The PassDataForward method is called when the form that is being navigated to by the FormsManager implements the IFormsManagerForm interface. //Create a new FormsManager, this should be stored in a globally accessible variable //since it is needed by all forms in the client application. FormsManager formsManager = new FormsManager(); //Set the first form the FormsManager will manage formsManager.FirstForm = formsManager.GetForm(typeof(FormCustomers)); //Use the first form with the Application.Run method in the Main function of the client. Application.Run(formsManager.FirstForm); //Because the first time that FormCustomers is loaded and shown must be handled by the //Aplication.Run method the PassDataForward method of FormCustomers will not be called. //Instead, the FormLoad event should be handled and used to signal that the first form has //been loaded and shown. Subsequent navigations to FormCustomers from another form in the //client will trigger a call to FormCustomer's PassDataForward function. 28 Client Object API Cookbook After a globally accessible FormsManager has been created and the first form is shown a custom client can navigate to other forms using the FormsManager ShowForm method. See the API documentation for information regarding the several overloaded versions of the ShowForm method. //Create a new FormsManagerDataObject to pass a collection of data to the next form. FormsManagerDataObject data = new FormsManagerDataObject(); //Set the key VALUE1 to be "ABC" data["VALUE1"] = "ABC"; //Set the key "VALUE2" to be 42 data["VALUE2"] = 42; //Tell the FormsManager to navigate to a form class named Form2 and pass along the //FormsManagerDataObject data to the next form. //The form specified in the second parameter is the form that the FormsManager will hide //as the navigation to the next form is made. Since we are leaving the current form the //second parameter is set to the 'this' keyword. formsManager.ShowForm(typeof(Form2), this, data); During form navigation the FormsManager hides the form specified in the second parameter of the ShowForm method. This prevents end users from using the Running Programs section of the Memory Settings screen to incorrectly return to a previous form before the application logic allows. In addition to the PassDataForward method the IFormsManagerForm interface requires that a CloseForm method be implemented as well. The CloseForm method is intended to be called by the FormsManager when the form is being closed and removed from the FormsManager cache. The CloseForm method can also be called manually from custom client code if a custom client uses a specialized shutdown and clean up method. 8.3.2. StackFormsManager The StackFormsManager form manager class is similar to the FormsManager class in that it manages cross form navigation/communication and caches previously instantiated forms. The difference between StackFormsManager and FormsManager is that StackFormsManager maintains a form navigation history by keeping a stack containing information about the previously visited forms. By using the stack information, the StackFormsManager allows a custom .NET client to navigate backward through the history of previously visited forms. The StackFormsManager is ideal for use in large multi-form applications that do have a structured form navigation hierarchy tree. In order for a form that is managed by the StackFormsManager class to receive cross form communication messages as a form navigation step takes place the form must implement the IStackFormsManagerForm interface. The IStackFormsManagerForm class implements the PassDataForward and PassDataBackward methods. The PassDataForward method is called when forward form navigation uses the StackFormsManager. Conversely, the PassDataBackward method is called when backward form navigation is made using StackFormsManager history. //Create a new StackFormsManager, this should be stored in a globally accessible variable Sybase Unwired Platform 1.0 29 //since it is needed by all forms in the client application. StackFormsManager stackFormsManager = new StackFormsManager(); //Set the first form the StackFormsManager will manage stackFormsManager.FirstForm = stackFormsManager.GetForm(typeof(FormCustomers)); //Use the first form with the Application.Run method in the Main function of the client. Application.Run(stackFormsManager.FirstForm); //Because the first time that FormCustomers is loaded and shown must be handled by the //Aplication.Run method the PassDataForward method of FormCustomers will not be called. //Instead, the FormLoad event should be handled and used to signal that the first form has //been loaded and shown. Subsequent forward navigations to FormCustomers from another form //in the client will trigger a call to FormCustomer's PassDataForward method and //backward navigations to FormCustomers from another form will trigger a call to //FormCustomer's PassDataBackward method. After a globally accessible StackFormsManager has been created and the first form is shown, a custom client can navigate to other forms using the StackFormsManager ShowForm method. See the API documentation for information regarding the several overloaded versions of the ShowForm method. //Create a new FormsManagerDataObject to pass a collection of data to the next form. FormsManagerDataObject data = new FormsManagerDataObject(); //Set the key VALUE1 to be "ABC" data["VALUE1"] = "ABC"; //Set the key "VALUE2" to be 42 data["VALUE2"] = 42; //Tell the StackFormsManager to navigate to a form class named Form2 and pass along the //FormsManagerDataObject data to the next form. //The form specified in the second parameter is the form that the FormsManager will hide //as the navigation to the next form is made. Since we are leaving the current form the //second parameter is set to the 'this' keyword. stackFormsManager.ShowForm(typeof(Form2), this, data); From the above sample the custom client can add code to the Form2 class to navigate backward to the FormCustomers class by using the following code. //Hide Form2 (do not unload it from the StackFormsManager's cache of forms or from memory) //and navigate back to the parent form in the StackFormsManager's history. This will //result in returning to FormCustomers. //And optional FormsManagerDataObject can be sent to FormCustomers by supplying one to //the HideForm method. stackFormsManager.HideForm(); 30 Client Object API Cookbook Using HideForm leaves Form2 in the StackFormsManager form cache. This speeds up subsequent navigations to Form2 because the form is already instantiated and in the cache. If a custom client needs to navigate back a form and wants to close the current form and remove it from the cache in order free up some memory, then the following alternative code can be used. //Close Form2 (unload it from the StackFormsManager's cache of forms and from memory) //and navigate back to the parent form in the StackFormsManager's history. This will //result in returning to FormCustomers. //And optional FormsManagerDataObject can be sent to FormCustomers by supplying one to //the HideForm method. stackFormsManager.CloseForm(); Calling either HideForm or CloseForm will result in a call to the PassDataBackward method of the previous form in the StackFormsManager history if the previous form implements the IStackFormsManagerForm interface. During forward form navigation the StackFormsManager hides the form specified in the second parameter of the ShowForm method. This prevents end users from using the Running Programs section of the Memory Settings screen to incorrectly return to a previous form before the application's logic allows them to. In addition to the PassDataForward and PassDataBackward methods, the IStackFormsManagerForm interface requires that a CloseForm method be implemented as well. The CloseForm method is intended to be called by the StackFormsManager when the form is being closed and removed from the StackFormsManager cache. The CloseForm method can also be called manually from a custom client's code if a custom client uses a specialized shutdown and clean up method. 8.3.3. FormsManagerDataObject The FormsManagerDataObject is a collection class that contains a set of key/value pairs. The FormsManagerDataObject provides a quick and simple way to pass any number of values of any type from one form to another during form navigation when using the FormsManager or StackFormsManager classes. To test if a FormsManagerDataObject contains a value for a specific key the following code can be used. //Assume the FormsManagerDataObject is a variable named 'data'. //Check for a key named CompanyID, if it is not found it will return 'null'. if(data["CompanyID"] != null) { MessageBox.Show(data["CompanyID"].ToString()); } else { MessageBox.Show("Company ID not provided."); Sybase Unwired Platform 1.0 31 } The key of the key/value pairs is a string object and the value of the key/value is returned as an object. Therefore, any object passed from one form to another using the FormsManagerDataObject must be cast to its true type after it is extracted from the FormsManagerDataObject before it can be used. //Cast the ArrayList that is extracted from the FormsManagerDataObject before it //can be used ArrayList list = (ArrayList) data["CustomerList"]; The keys of the FormsManagerDataObject must be unique. If a custom client sets a specific key/value pair twice then the first key/value pair is replaced with the second pair. 9. 9.1. Sybase.UnwiredPlatform.Controls Assembly (unsupported) Introduction The Sybase.UnwiredPlatform.Controls API is not intended as a replacement to the default user interface controls provided by Microsoft. The Controls API contains two image button controls and a color customizable label that custom .NET client developers can use to build better user interfaces. These controls are only intended for use in PocketPC .NET Compact Framework applications. The Controls API is not intended for use on Windows Mobile Smartphone devices because Smartphones do not support button controls. Additionally, the full .NET Framework already includes an image button control. The included controls are: • ImageButton – a button control that can display a background image. The ImageButton control supports displaying different images for the mouse up, mouse down and disabled (Enabled = false) states. ToggleImageButton – extends the basic ImageButton control further with a toggle on/off property. Label – a basic label control that can have custom background, foreground and border colors. The Label control is useful for creating labels with white backgrounds and black borders, creating the effect of a read only text box. • • 9.2. Visual Studio 2005 .NET Compact Framework 2.0 Projects To add the Sybase.UnwiredPlatform.Controls user interface components to the Toolbox for Visual Studio 2005 .NET Compact Framework 2.0 applications: 32 Client Object API Cookbook 1. Close all instances of Visual Studio 2005. 2. Place the Sybase.UnwiredPlatform.Controls.CF2 assembly files in a central common location. All Visual Studio 2005 .NET Compact Framework 2.0 projects can reference the same Sybase.UnwiredPlatform.Controls.CF2 assembly files. Unlike Visual Studio .NET 2003 the Sybase.UnwiredPlatform.Controls.CF2 assembly files do not have to be placed in any special location under the Visual Studio 2005 installation folders. 3. Launch Visual Studio 2005 and open an existing .NET Compact Framework 2.0 PocketPC project or create a new one. 4. View a form in the Form Designer so the tools in the Toolbox are visible. 5. To prevent potential toolbox confusion and conflicts, keep the .NET Compact Framework 1.0 and 2.0 versions of the controls separated in the Toolbox using different tabs. Right click the Toolbox and select Add Tab. Name the new Tab "UA .NET CF 2". 6. Expand the UA .NET CF 2 tab and right click it. Select Choose Items. A few moments may pass as Visual Studio loads the list of assemblies and components. 7. After the Customize Toolbox screen appears click Browse and navigate to and select the Sybase.UnwiredPlatform.Controls.CF2.dll file from the central common location it was placed in during step 2. 8. Once added to the .NET Framework Components tab list on the Customize Toolbox screen, make sure the ImageButton, Label and ToggleImageButton from the Sybase.UnwiredPlatform.Controls.CF2 assembly are checked. 9. Click OK and the three components will be added to the UA .NET CF 2 Toolbox tab. This tab will only be visible and enabled in the Toolbox when the project being worked on is a .NET Compact Framework 2.0 project. 10. To use the controls drag them from the Toolbox to a form in the Form Designer and modify the control's properties using the Properties panel. 10. Miscellaneous 10.1. SMS Push Notification Messages Unwired Platform 1.0 SMS push notification messages are structured in the following format: req_id=;op=sync;wid=;profile=;app=;mbo= The SMS push notification messages are designed to not exceed the length limitation of SMS messages. The individual fields of the SMS message are as follows: • req_id – a unique identifier integer value for the push notification that was sent from Unwired Server. Sybase Unwired Platform 1.0 33 • op – the operation to perform. Potential values for this field are “sync” and “delete”. An op value of “sync” means the client should synchronize. An op value of “delete” means a registration for push notifications regarding a particular application has been deleted from the Unwired Server. See the wid field for additional information. How and if a custom client supports reacting to the “delete” operation often depends on the feature specifications of the custom client and is left to developer of the custom client to process. profile – a unique identifier for the profile associated with the application involved with the push notification message. For custom .NET clients, the profile field is a GUID for the Profile associated with the application involved with the push notification. A custom .NET client can iterate over all available Profile objects, and test the Profile object’s GUID Id property against the profile field to locate the specific Profile. wid – an identifier integer that represents the application ID of the MBO involved with the push notification message. If the op field is “sync” then wid is the application ID of the application the push notification is for. If the op field is “delete” then the wid is the application ID of the application for which the custom client is no longer registered to receive push notifications. token – the optional security token that was passed to the server when a custom client registers for push notifications via the Data API. app – the flag keyword that was specified and passed to the server when a custom client registers for push notifications via the Data API. If a custom client submits the value “MyPush” in the ApplicationName property of the PushSyncInfo object, then the app field will be “MyPush” when a push notification for the associated application is sent. mbo – the MBO name that can be used when calling the SynchronizationManager. • • • • • 10.2. Cleaning Up UltraLite Databases in Device Applications It is possible to clean up a custom client and return it to a freshly installed state without having to uninstall and reinstall the entire client application. To do this, delete all .udb files from the client’s installation folder on the device. Once the custom client is started and any necessary Profile is saved, the client will be ready to begin synchronizing with the Unwired Server again. No data downloaded will be lost if the *.udb files are deleted because it will be downloaded again when the freshly cleaned client is synchronized once again. The only data loss that can occur is for pending Operations. Pending Operations that are not synchronized with the consolidated database before cleaning and resetting the client application will be lost. 34 Client Object API Cookbook