Etiqueta

28 diciembre 2018

Nueva herramienta de migración de Omnis DF1 a SQLite o PostgreSQL

Otra de las novedades que incluye Omnis Studio 10, supone una garantía de estabilidad y longevidad para nuestras aplicaciones, especialmente en lo que al uso de la base de datos nativa (los llamados df1) se refiere. La gran ventaja que supondrá el uso de ésta herramienta es, que tras su conversión a una base de datos SQLite o PostgreSQL, los antiguos comandos denominados "Omnis DML" permanecerán en la biblioteca convertida, pero, (y este es el importante detalle) se ejecutarán contra la base de datos seleccionada (SQLite o PostgreSQL), sin problemas y automáticamente, en lugar del antiguo fichero de datos Omnis. Por ejemplo, comandos como "Prepare for edit" o "Update files" se ejecutaran contra la nueva base de datos (SQLite o PostgreSQL). 



Sin duda ésta opción, es muy bien recibida por todos aquellos que hemos deseado por mucho tiempo, disponer de un almacenamiento de datos más robusto, proporcionándonos a la vez, una cómoda puerta de salida, en la migración de nuestras antiguas aplicaciones hacia el soporte de código SQL. Un mejorado "OmnisSQL DAM" será el encargado de producir el "milagro" de acceder a un fichero SQLite como si se tratase de un antiguo fichero .df1

Se han realizado pruebas con el nuevo "OmnisSQL DAM" contra archivos de datos SQLite y Omnis, tanto directamente como utilizando "Data Bridge". Las pruebas se han realizado insertando ~ 2.5MB y leyendo ~ 20MB de un archivo de datos. Los tiempos de finalización de la prueba se muestran en segundos.


27 diciembre 2018

Objetos "JavaScript Worker"

Omnis Studio 10, ahora tiene embebido (integrado) el "framework" "node.js", el cual incluye gran cantidad de módulos de código abierto desarrollados por terceros y que (por tanto) podremos usar libremente desde nuestro código Omnis. Un nuevo "Worker Object" denominado "JavaScript Worker Object" nos permitirá ejecutar métodos de "node.js", mediante simplemente invocarlo desde nuestro código Omnis, para posteriormente recibir los resultados en el método indicado como retorno del mismo. A modo de ejemplo, Omnis incluye la librería "xml2js" la cual permite convertir un XML a JSON.

Construcción de métodos JavaScript


Con éste fin Omnis dispone de un nuevo archivo JS, denominado "ow3javascript.js", el cual podremos localizar bajo el directorio "clientserver/server/remotedebug" y que es el punto de partida para todas las llamadas a los métodos de "node.js". Éstas llegaran desde Omnis como solicitudes HTTP y retornaran sus resultados también como contenido HTTP. Cada "Worker" ejecutará sus métodos secuencialmente.

Un nuevo directorio o carpeta denominada "node_modules", contendrá los módulos que serán requeridos desde el "ow3javascript.js". Es aquí, donde deberemos ubicar lo módulos "node.js" que deseemos utilizar, mediante el comando "npm -i" ejecutado desde ésta misma carpeta; éstos serán los módulos que ineraccionaran con nuestras aplicaciones Omnis.

Existen al menos dos archivos clave que siempre deberán estar ubicados y presentes en ésta carpeta:

  • omnis_calls.js - Módulo que encargado de devolver los resultados a Omnis.
  • omnis_modules.js - Módulo encargado de suministrar la lista de los que podrán ser invocados desde Omnis.

En ésta misma carpeta, podremos localizar dos módulos suministrados a modo de ejemplo denominados: "omnis_test.js" y "omnis_xml2js.js". Vistos desde Omnis sus nombres son "test" y "xml2js", a cada uno de ellos le corresponderá una entrada en el "omnis_modules.js" proporcionándose así la lista de métodos que podrán ser invocados desde Omnis.

Creación de un "Worker"


Asigne el subtipo del objeto externo "OW3 Worker Objects\JAVASCRIPTWorker", a una variable de tipo "Object" u "Object Reference", , también puede hacerse mediante crear una clase objeto a la que asignar el "subtipo" ya indicado, para luego asignarlo a una variable Omnis.

¡¡Importante!! Antes de invocar su método "$init", será necesario configurar su propiedad "$callbackinst", para indicar dónde recibir los resultados. Por ejemplo: "Calculate Object.$callbackinst as $cinst"

Propiedades


El "Worker JavaScript" soporta las propiedades "Worker" estándar: $state, $threadcount, $errorcode y $errortext.

Métodos de invocación


$init([cPath, bDebugNodeJs=kFalse])


Permite preparar el objeto, de forma que esté listo para ejecutar llamadas a métodos JavaScript. Devuelve "true" si tiene éxito. Debe ejecutarse antes que cualquier otro método.

  • cPath
    Permite cambiar la ruta de búsqueda de módulos predeterminada "NODE_PATH". La ruta predeterminada es "≤Carpeta de datos Omnis≥/node_modules". Tenga en cuenta, que sí cambia esta ruta, el resto de módulos que son obligatorios también deberán ser alojados en la nueva ruta.

  • bDebugNodeJs
    Booleano que indica si se desea poder depurar "node.js", por ejemplo, mediante Chrome. Es posible que no pueda iniciarse el "Worker" si se configura para más de un "Worker JavaScript" en activo, ya que "node.js" requiere de un puerto para depuración disponible. Para su depuración en Chrome, introduzca "chrome://inspect", y luego abra las herramientas de depuración dedicadas para "node.js". 

$start()


Ejecuta el "Worker JavaScript" en segundo plano. Devuelve "true" sí ha sido iniciado correctamente. El método $start(), se encargará de iniciar "node.js" he invocar los métodos JavaScript. Seguramente realizaremos llamadas a diferentes métodos del mismo proceso, por lo que no será necesario ejecutar $start() con frecuencia, lo que significa que la sobrecarga debida a la ejecución de procesos "node.js" es mínima.

$cancel


Cancela la ejecución del proceso "node.js". Cualquier método ya en progreso no será completado.


$callmethod(cModule, cMethod, vListOrRow [,bWait=kFalse, &cErrorText])



Permite la invocación de un método, al cual se pasa un solo parámetro desde el objeto JavaScript ("vListOrRow"). Opcionalmente se esperará a que el método complete su ejecución ("bWait"). El método devolverá "true" si la invocación es exitosa. "cModule" y "cMethod" identifican al módulo y al método dentro del módulo, que será invocado. "vListOrRow" será convertido a formato JSON antes de su paso al método como parámetro. El uso de "bWait" indicará que deseamos suspender la ejecución, hasta que el método haya terminado. "cErrorText" recibirá un texto descriptivo del error, en caso de fallo de "$callmethod".



Métodos de retorno




$cancelled


Se puede reescribir este método (Override) si se desea controlar la notificación correspondiente a una cancelación del "Worker" realizada correctamente.

$workererror(wError)


La reescritura de éste método (Override), permite recibir notificaciones de error del "Worker" no relacionados con la invocación a alguno de sus métodos, como, por ejemplo, un error producido al iniciarse "node.js". El sub-proceso del "Worker" se cerrará tras la generación de dicha notificación. "wError" contiene dos columnas, un entero llamado "errorCode" y un texto llamado "errorInfo".

$methoderror(wError)


La re-escritura de éste método (Override), permite recibir notificaciones de error tras el intento de invocar un método mediante "$callmethod". "wError" tiene dos columnas, un entero llamado "errorCode" y un texto llamada "errorInfo".

$methodreturn(wReturn)


Éste es el método al cual llegarán los resultados tras la ejecución de un "$callmethod". "wReturn" es una variable de tipo "row". Si el método de JavaScript devuelve un objeto, será el equivalente Omnis creado al convertir el JSON en una "row". Si el método de JavaScript devuelve otros datos, como por ejemplo. una imagen, esta consistirá en una "row" con una sola columna denominada "content", con los datos devueltos por el método.

26 diciembre 2018

El nuevo Depurador Remoto

La depuración remota permite depurar el código Omnis de una librería compartida en la red. Omnis usa para ello una versión “developer” independiente, el llamado “remote debug client”, el cual se conectará a través de la red a otro Omnis Studio, denominado “remote debug server”.


Algunos aspectos a tener en cuenta:

  • El “remote debug server” es quien ejecuta el código a depurar, y puede residir en cualquier tipo de instalación: “development”, “runtime”, “server” o “headless server”.
  • El código Omnis es ejecutado en modo “multi-threaded server”, creándose para ello pilas de procesos independientes de la principal.
  • El “remote debug server” y el “client” no precisan estar ejecutándose en el mismo sistema operativo.
  • La versión “client” debe ser la misma o posterior a la versión “server”.
  • Las clases protegidas y las bibliotecas bloqueadas también pueden ser depuradas.

Aunque hablamos de “depurador remoto”, en realidad, tanto el cliente como el servidor podrían residir en la misma máquina, de hecho cliente y servidor podrían contener los mismos procesos Omnis. En este último caso, el “remote debug client” es ejecutado con algunas restricciones, indicadas mas adelante en este artículo.

Conectividad


El “client” y el “server” se conectan entre sí a través de un WebSocket. Una conexión WebSocket es una conexión directa entre cliente y servidor, por lo que puede requerir de la apertura del puerto correspondiente en el “firewall”. Puesto que las conexiones WebSocket se inician como conexiones HTTP, un WebSocket puede soportar una conexión TLS segura, así como el requerimiento de un certificado de autenticación para el cliente. El “remote debug”, usa siempre una conexión TLS, por lo que el WebSocket es iniciado como HTTPS.

La conexión entre un cliente y un servidor es denominada “remote debug session” o simplemente “session”. Omnis podrá ejecutar una sola “session” a la vez.

El "Remote Debug Server"


Desde la versión “developer”, podremos configurar el “remote debug server” tras hacer clic sobre su nodo en el “Browser”, y seleccionar la opción “Remote Debug Server”.

Para una versión “runtime” de Omnis (no “headless”), y si la librería “remotedebug.lbs” está en la carpeta “startup”, se dispondrá de un menú denominado “Remote Debug”. El cual contiene una sola opción, que permite abrir la ventana de configuración. Si se trata de un servidor “headless” podremos llevar a cabo la configuración desde la ventana de administració (osadmin).

La ventana de configuración muestra dos pestañas, una para controlar el servidor y otra para configurarlo.

La pestaña “Control Server” tiene un solo botón, utilizado para arrancar o detener el servidor. De no encontrarse arrancado, no aceptará conexiones desde un cliente.

La pestaña “Configure Server” permite llevar a cabo su configuración, muestra los campos que corresponden a las entradas en el archivo de configuración y que describiremos a continuación.

El fichero de configuración


La configuración se guarda en el fichero denominado  “remote_debug_server_config.json”, ubicado en “clientserver/server/remotedebug” de la carpeta de instalación Omnis. Podemos optar por editar este archivo JSON directamente con cualquier editor o usar la opción descrita anteriormente.

Debemos tener en cuenta que Omnis hace uso de un servidor “node.js” ejecutado junto con Omnis, desde el se construye el servidor WebSocket. Como consecuencia, parte de la información de configuración es compartida también con “node.js”.

Configuración ejemplo:

{
   "debugPort": 8080, 
  "serverPfx": "server.pfx", 
  "pfxPassPhrase": "xxxxxx", 
   "ca": [ "server_cert.pem" ], 
  "requestCert": false, 
  "rejectUnauthorized":  false, 
  "userName": "myUser",
 "hashedPassword":   
 "AAGGoAAAABBSEkknQUIeHQHu1sIyWxlSAAAAIHw9kvCVF4tE//S   MpbSGVD/RKJLekoR7TlTvZVy3MbkJ", 
   "startRemoteDebugServerAtStartup": true,
   "pauseAtStartupUntilDebuggerClientStartsExecution": false,
   "logConnectionSetup": false
}

debugPort

El puerto TCP/IP en el que el servidor WebSocket escucha las conexiones entrantes desde el cliente.

serverPfx

Este es un archivo que contiene el certificado del servidor y la clave privada. Debe estar en el mismo directorio que el “remote_debug_server_config.json”. La instalación por defecto consta de un certificado auto-firmado y una clave generada mediante el comando openssl (disponible en cualquier sistema con openssl instalado). Tendrá que proporcionar su propia clave privada y su certificado. Puede generar una nueva clave privada y un certificado auto-firmado utilizando los siguientes comandos:

openssl req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem -nodes -days 1024 -subj "/CN=localhost/O=Demo" -passin pass:xxxxxx
openssl pkcs12 -export -out server.pfx -inkey server_key.pem -in server_cert.pem

Este archivo deberá ser indicado bajo la opción “PFX” y es invocado por el método https.createServer() de “node.js”. Podrá encontrar más información sobre esto, en la documentación de “node.js”:

https://nodejs.org/docs/latest-v8.x/api/https.html#https_class_https_serve 
https://nodejs.org/docs/latest-v8.x/api/tls.html#tls_tls_createsecurecontext_options

pfxPassPhrase

Esta es la frase-contraseña utilizada para proteger el archivo PFX en el servidor. En nuestro ejemplo es "xxxxxx".

ca

Ver https://nodejs.org/docs/latest-v8.x/api/tls.html#tls_tls_createsecurecontext_options para más detalles. Normalmente, usted sólo tendrá un CA, puesto que tiene un sólo certificado auto-firmado, en cuyo caso tendremos una sola entrada. En nuestro ejemplo el certificado fue firmado usando “server_cert.pem”. Generalmente su valor es una lista separada por comas de certificados de confianza, nombres de archivos los cuales deben residir en el mismo directorio que el “remote_debug_server_config.json”.

requestCert

Valor booleano. Si es verdadero, el servidor “node.js” solicitará un certificado para autenticar al cliente. Los certificados de cliente se explican más adelante, en la entrada conectividad del cliente.

rejectUnauthorized

Valor booleano. Si es verdadero, el servidor rechazará cualquier conexión no incluida en la lista de CA’s suministrada. Esta opción solo tiene efecto si “requestCert” es cierto.

userName

Si no está vacío, la conexión WebSocket también usará autenticación básica HTTP con el usuario, en cuyo caso este campo deberá contener el nombre del usuario utilizado para la autenticación básica HTTP.

hashedPassword

Si “userName” no está vacío, será el "hash" PBKDF2 de la contraseña requerida para la autenticación básica HTTP.

startRemoteDebugServerAtStartup

Esta opción booleana indica si el “remote debug server” debe iniciarse  automáticamente al iniciarse Omnis.

pauseAtStartupUntilDebuggerClientStartsExecution

Si el “remote debug server” está configurado para iniciarse automáticamente cuando se inicia Omnis, podremos configurar esta opción booleana a “true” para causar que Omnis pause su ejecución durante el momento de ejecutar la “startup_task” y otras "tasa" iniciales de nuestra librería Omnis.

Cuando se utiliza esta opción, Omnis muestra un mensaje de trabajo (Waiting for remote debug client to start execution…), entrando en un bucle de espera, hasta que se reciba un comando desde el cliente para ejecución. Durante este bucle, el cliente podrá ver y depurar el código remotamente, mediante (por ejemplo) establecer puntos de interrupción.

El bucle termina cuando el cliente envía un comando de inicio de ejecución, cuando la sesión con el “remote debug server” es cerrada o cuando un usuario hace clic sobre el botón “cancel” situado junto al mensaje de trabajo mostrado en el servidor. Cuando el bucle termina, Omnis ejecutará la “startup_task” de la librería.

El “Remote Debug Client”


El “remote debug client” es accesible a través de un nuevo nodo situado sobre el árbol del navegador de Studio denominado, "Remote Debug Client". Utiliza un modelo de sesión similar al de VCS. Tras hacer clic sobre el nodo, se mostrarán los enlaces “Session Manager”, y “Open Session”.

El “Session Manager” permite configurar las sesiones de depuración remotas. Cada sesión contendrá los parámetros que permitirá al cliente iniciar un WebSocket de conexión con un “remote debug server”. A continuación describimos cada uno de sus parámetros:

Name

Nombre que identifica el sesión.

Server

Dirección IP o nombre DNS del “remote debug server”.

Debug Port

Puerto configurado en el “remote debug server”. En su conexión al servidor, el cliente construirá la URL siguiente:
wss://Server:DebugPort

Client Certificate

Si el servidor requiere un certificado de cliente, deberá especificarse aquí. Podrá generar un certificado de cliente usando los siguientes comandos openssl:
openssl req -newkey rsa:4096 -keyout client_key.pem -out client_csr.pem -nodes -days 1024 -subj "/CN=192.168.1.11" -passin pass:xxxxxx
openssl x509 -req -in client_csr.pem -CA server_cert.pem -CAkey server_key.pem -out client_cert.pem -set_serial 01 -days 1024
Tenga en cuenta que en este ejemplo usamos la clave y el certificado de servidor utilizados con el ejemplo para el “PFX”. Paro, el certificado del cliente necesitará ser instalado en la máquina del cliente.

Para Windows, genere un archivo “client.pfx”:
openssl pkcs12 -export -out client.pfx -inkey client_key.pem -in client_cert.pem
Añada el “client.pfx” al almacén de certificados de Windows, mediante hacer doble clic  en el archivo, agregándolo a “Personal certificates” del usuario en curso.

Para macOS, genere un archivo “pkcs12”:
openssl pkcs12 -export -out client.p12 -inkey client_key.pem -in client_cert.pem
Haga doble clic sobre el archivo para agregarlo al llavero.
Puede encontrar más detalles sobre esto en la documentación sobre CURL en:
https://curl.haxx.se/libcurl/c/CURLOPT_SSLCERT.html
Tenga en cuenta que el parámetro “Client Certificate” pasa su valor al comando CURL bajo la opción CURLOPT_SSLCERT.

En caso de Windows, el parámetro es la ruta hacia el lugar donde está almacenado…
CurrentUser\MY\afe2179599460d20da08c12e8c328d84bd300735
…donde afe2179599460d20da08c12e8c328d84bd300735 es la huella digital, visible mediante hacer doble clic en “certificate” del MMC (MMC certificate snap-in view, pestaña “details”, campo “thumbprint”).

En caso de macOS, se puede especificar la ruta del archivo “p12” o el nombre que tiene en el llavero del cliente.

User Name

Si el servidor utiliza autenticación básica HTTP, es el nombre de usuario requerido.

Password

Si el servidor usa autenticación básica HTTP, será la contraseña requerida.  Alternativamente, podrá dejarse vacía, causando que se le solicite al cliente la cuando sea necesaria.

Server Connection Logging

Mediante ésta opción podremos monitorizar la conexión con el “remote debug server”, para poder observar cualquier problema de conexión. También deberemos habilitar ésta opción en el archivo de configuración, bajo la entrada “logConnectionSetup”.

Si está habilitado, se creará un archivo de registro  denominado: “.htm” en el directorio “logs/remotedebug , con el registro de lo que ha ocurrido al conectarse al “remote debug server”. Tenga en cuenta que el registro no se escribe hasta que la conexión es cerrada.

Preparación del código para su depuración remota


Deberemos habilitar en nuestras librerías e instancias de tipo tarea “task” la capacidad “remote debugging” mediante configurar su propiedad $remotedebug.

Library


Por defecto, una librería no puede ser depurada remotamente, lo que significa que cuando el cliente intente conectarse para depuración, normalmente no aparecerá en el interfaz de cliente. Si queremos que aparezca necesitaremos establecer su propiedad “$clib.$remotedebug”, como “True”, lo cual no podrá realizarse sobre librerías ya marcadas como privadas, lo que significa que deberemos fijar esta propiedad como “true” antes de hacerla privada.

Task


La configuración de “$clib.$remotedebug” permite que la librería y sus clases aparezcan sobre la ventana cliente de depuración remota. Permitiéndonos manipular su código y establecer “break points”.

Sin embargo, sólo las clases “task” y “remote task” marcadas para depuración remota, reaccionarán ante los “breack points” que fijemos. Esto permitirá un mayor control sobre lo que podrá o no podrá ser depurado remotamente y del lado del servidor, permitirá evitar que un “breack point” detenga la ejecución para otros posibles clientes en uso.

Para marcar una “task” o “remote task” para depuración remota, configure su propiedad
“$remotedebug” a kTrue.

Tabién podremos activar ésta propiedad, cómo un parámetro en el URL de conexión, hacia un “remote form” (omnisRemoteDebug = 1), por ejemplo:
http://127.0.0.1:5981/jschtml/jsDragDrop.htm?omnisRemoteDebug=1

Interfaz del depurador remoto 

Abriendo un sesión

Para usar el “remote debugger client” tras configurar una sesión, haga clic sobre el nodo “Remote Debug Client” y después sobre el enlace “Open Session”, luego haga clic sobre el enlace correspondiente a la sesión que deseemos utilizar.

Esto hará que el cliente inicie una conexión WebSocket con el servidor. Mientras se establece, se mostrará su progreso sobre el panel del navegador, aunque suele ser muy rápido. Además, aparecerá un nuevo enlace durante éste proceso denominado “Cancel Open Session”.

Browsing Libraries

Una vez abierta la sesión, se mostrarán las bibliotecas marcadas para depuración remota.

Los nodos secundarios del “Remote Debug Client” tienen un comportamiento similar al de los habituales para la edición de librerías. Cuando seleccionamos alguno de éstos nodos secundarios, el panel del navegador se actualizará para mostrar su contenido permitiendo la edición de todo el contenido de la librería.

Si se selecciona una sola clase en el panel del navegador, se mostrará un enlace denominado "Open debug window". Haga clic sobre él para abrir la ventana de depuración remota para esa clase.

Finalmente, si el servidor está en pausa y por tanto a la espera de ejecutar el inicio, entre los enlaces podrá ver uno con el nombre “Run Startup”, mediante el cual podrá indicar al servidor que debe continuar y ejecutar su proceso inicial.

La ventana del “Remote Debug”

Esta ventana muestran un diseño muy similar al del editor de métodos. Su diferencia principal está en que siempre muestra el panel de depuración y no existe un panel de edición, y en su esquina inferior derecha aparece un nuevo panel de variables.

La barra de herramientas (Instance)

Permite mostrar los métodos u objetos específicos de una instancia actualmente en uso. El menú “Instance” nos permitirá cerrarla, así como también retirarla o añadirla a la lista del depurador.

Tenga en cuenta que este menú se desactiva tan pronto como la ventana de depuración remota es asociada, es decir durante el proceso de depuración de una instancia.

Observaciones

Deberemos tener presente que el conjunto de librerías e instancias, susceptibles de ser depuradas pueden cambiar en el servidor. Omnis mantiene al cliente constantemente actualizado con respecto a la situación en que se encuentre el servidor. Por ejemplo, si una librería se cierra en el servidor, se informa al cliente y se actualiza su interfaz lo que significa su eliminación del navegador y el cierre de cualquier ventana de depuración remota relacionada. Sin embargo, si se producen cambios en un método en el servidor, el cliente no recibirá el método actualizado hasta que sea de nuevo solicitado, debe tenerse en cuenta que cada vez que el cliente realiza una operación de depuración, el cliente solicita el método y retiene una copia del mismo, hasta que la acción termina, si durante ese proceso, el método ha cambiado en el servidor, el cliente no lo recibirá hasta necesitar una nueva copia.


25 diciembre 2018

Omnis Developers Conference, Mexico City – Lunes 11 de Marzo 2019

Lunes 11 de Marzo 2019,  Omnis Developers Conference, Mexico City

Martes 12 + Miercoles 13 Marzo 2019,  Omnis Academy, Mexico City
Objetivos
  • Conocer OMNIS Studio
  • Presentar de la nueva versión 10
  • Componer aplicaciones que traspasan las fronteras
  • Componer aplicaciones Web y Moviles (Android, iOS, Windows 10)
  • Establecer contactos, conociendo más detalle sobre aplicaciones y proyectos.

Consulte la agenda e inscríbase hoy mismo...

02 noviembre 2018

¡El anuncio anticipado de un punto de viraje en la ya larga historia de Omnis!

Esta entrada en el blog, no es para describiros una característica de Omnis Studio, ni para (como os tengo acostumbrados) arrojar nueva luz sobre como hacer las cosas con ésta magnífica herramienta, simplemente es que no me he podido resistir a perder la ocasión de hacerme eco del más que interesante anuncio que Omnis a hecho el pasado 1 de Noviembre del 2018.

Sin duda y como reza en el título de ésta entrada, marcará una "antes-y-después" en la historia de Omnis Studio. Será muy emocionante ir descubriendo las novedades que nos esperan.



01 octubre 2018

Accesibilidad WCAG 2.0 con Omnis Studio

Otra de las novedades de la nueva versión 9 de Omnis Studio. permitirá dar soporte en nuestras aplicaciones Web, a las llamadas "Pautas de Accesibilidad para el Contenido Web" (WCAG 2.0) lo cual permitirá que éstas sean más accesibles, principalmente para personas con discapacidades. Estas directrices han sido adoptadas por muchas agencias gubernamentales y garantizan un nivel aceptable de acceso a la información y los servicios proporcionados por los sitios web a personas con diferentes discapacidades. Puede leer las siguientes páginas para obtener una comprensión básica de los requisitos de WCAG:

https://www.w3.org/WAI/standards-guidelines/



La implementación de WCAG en Omnis Studio hace referencia a la especificación ARIA, (Accessible Rich Internet Applications) la cual describe una forma de hacer que el tanto el contenido web, como las aplicaciones para la web, sean más accesibles para las personas con discapacidades. Especialmente hace hincapié en el contenido dinámico y los controles avanzados del interfaz de usuario, lo cual tiene un amplio soporte en la tecnología jsClient desarrollada por Omnis Studio.

En la práctica, esto significa que hemos agregado varias propiedades compatibles con ARIA a los controles JavaScript, tanto para la web como para las aplicaciones móviles, pensando siempre en los usuarios con discapacidades. Estas propiedades serán activadas automáticamente, cuando las propiedades del dispositivo estén habilitadas, bien sea en el navegador o en el móvil del usuario.

04 julio 2018

¿Que habrá en Omnis Studio 9?

En la conferencia "Omnis Developer" celebrada en mayo de este año en Alemania, Bob Mitchell, (Omnis Engineering Manager) desveló algunas de las características que podremos ver en el futuro Omnis Studio 9. De todas ellas, con seguridad la más atrayente es su totalmente renovado editor de código, realmente un paso esperado por la comunidad de desarrolladores y que hace de Omnis Studio una herramienta aún más rápida y eficaz en el desarrollo de aplicaciones web y dispositivos móviles.

En su exposición (disponible en YouTube) Bob describe los cambios de sintaxis, que también se introducen junto con la entrada del nuevo editor de código Omnis.


El nuevo editor reemplazará al actual de disposición en lista, ampliando las opciones del actual "Code Assistant". La escritura de código se realiza al estilo de un editor de texto convencional, pero cuando es necesario, el "Code Assistant" hace su aparición de forma totalmente automática ayudándonos a completar expresiones, nombres, opciones y parámetros de los comandos. No obstante y en cualquier momento, se puede presionar Ctrl-espacio para abrir el asistente de código y obtener así ayuda relativa al contexto, incluso con una descripción completa del comando y ejemplos de uso.

A continuación enumeramos algunas de sus características:

  1. Diseño rígido (el código aún se guarda de forma codificada)
  2. Utiliza una fuente de ancho fijo.
  3. Aumento de la capacidad de "deshacer" y "rehacer" (disponible también desde otros ámbitos del futuro Omnis Studio 9)
  4. Coloración de sintaxis: nuevos colores para indicar el alcance de las variables, opciones de comandos, funciones, etc.
  5. Las construcciones de comandos con cierres se auto-completan, por ejemplo, al escribir "If" se añade automáticamente el "End If".
  6. El panel de ayuda muestra tanto su sintaxis, como una descripción completa del comando.
  7. Los errores en el código, son marcados mediante un subrayado rizado.
  8. Diferentes opciones seleccionables desde la paleta situada en la parte superior del editor, permiten obtener ayuda sobre parámetros así como la localización y corrección de errores, entre otras muchas funciones.
  9. Permite la declaración de variables con ámbito y tipo automático indicado por medio de prefijos y sufijos, por ejemplo, "iVarList" será una variable de instancia (prefijo "i") de tipo "list" (sufijo "List").
  10. Nuevas opciones tales como, "Goto line number", "Select line", "Upper/Lower case", triple-clic para seleccionar una línea de código para (por ejemplo) eliminarla y búsqueda por palabras, entre otras.
  11. Una nueva propiedad denominada "$keys" que funciona en conjunción con un fichero de nombre "keys.json", permite configurar y guardar todos los atajos de teclado que queramos usar con éste nuevo y magnífico editor de código Omnis.

Otras características y disponibilidad:

Bob también nos hablo sobre algunas otras cosas que se espera incluirá Omnis Studio 9, "Remote Objects" los cuales podrán contener métodos de ejecución exclusiva en el cliente, "Omnis Datafile Migration", una herramienta para la conversión automática de archivos ".df1" a SQLite o PostgreSQL, soporte para los estándares de accesibilidad en la Web (WCAG 2.0), "Remote Debugging" el cual nos permitirá depurar nuestras aplicaciones para la web y dispositivos móviles de modo más cómodo y eficaz, nuevos controles JavaScript, entre ellos el denominado "iCalendar"".

La primera versión Beta de Omnis Studio 9, estará disponible para los desarrolladores a finales de año.

02 julio 2018

Uso del método "$pushdata"

Para dar soporte a las notificaciones "push", disponemos de un nuevo método para instancias "remote form" denominado $pushdata(), con la siguiente sintaxis:

$pushdata(wRow[~&cErrorText])

Usado en conjunción con $clientcommand("openpush";row()). El método provoca una llamada al método $pushed de la instancia "remote form" del cliente, pasando "wRow" como parámetro, su formato debe ser compatible JSON, por lo que solo puede contener tipos:

"character", "boolean", "integer", "number", "date", "list" o "row".

Omnis mantendrá encolados los datos enviados desde cada "remote task", independiente de las llamadas "openpush" que tenga asociadas. Tan pronto como llega una petición "push" de un cliente, Omnis envía los datos a la cola, para que el cliente la procese cuando esté disponible.

Cuando el cliente procesa la respuesta se emite una nueva petición "push", indicándole al servidor que recibió los datos. Esto permite al servidor eliminar de la cola, los elementos de datos ya procesados liberando memoria. La conexión permanece abierta y tan pronto como desde del servidor se ordena la ejecución de "$pushdata", Omnis envía los datos al cliente, puede dar la impresión de que existiese una conexión permanente entre servidor y cliente, pero no es así, sino que simplemente se establece un control de datos enviados y recibidos por los clientes, evitando pérdidas.

La práctica habitual sera que los clientes guarden la información entregada por "$pushdata" en una variable o en subconjunto de variables de ambito instancia, para actualizar su "remote form".

29 enero 2018

Obtener el UUID de la sesión Omnis Studio Web

Entre las muchas cosas que incorporó la versión 8.1 de Omnis Studio para la Web, nos contaba los chico de Omnis, que ahora al establecerse la comunicación desde el cliente con el servidor de aplicaciones web, se genera un UUID de identificación para la sesión, el cual es guardado como una cookie y enviada como parámetro cada vez que se produce un intercambio de datos. La cookie caduca después de un año, tras el cual, se generará un nuevo UUID. Naturalmente las cookies deberán estar habilitadas, tanto en el servidor web, como en los clientes para que esto funcione.



Nada mas leer esto me preguntaba cómo podríamos desde programación Omnis, obtener el UUID asignado y así poder usarlo, para (por ejemplo) guardar y ajustar preferencias relativas a la sesión en uso, la respuesta viene de la mano de javascript, ya sabemos que podemos incluir código javascript, en los métodos de ejecución exclusiva en el cliente, habitualmente usamos el método "$init" en nuestros "remote-form" con éste propósito, a continuación mostramos el código necesario para la obtención del UUID asignado a la sesión:

JavaScript: var getCookie = function (name) {
JavaScript: {    var cookies = document.cookie.split(';');}
JavaScript: {    for (var i = 0 ; i < cookies.length ; ++i) {}
JavaScript: {        var pair = cookies[i].trim().split('=');}
JavaScript: {        if (pair[0] == name) return pair[1];}
JavaScript: {    }}
JavaScript: {    return NULL;}
JavaScript: }
JavaScript: lIDCookie = getCookie("OMNISCLIENTID");
Do method setIDCookie (lIDCookie)
"lIdCookie" es una variable local y "setIDCookie" es el método (de ejecución en el servidor) que recibirá "lIDCookie" como parámetro.



22 enero 2018

Aplicar CSS a las líneas de un pop-menu en Omnis Studio Web

Aún existen esos "tipos raros" que dedican su tiempo libre a investigar como hacer ciertas cosas en programación con Omnis Studio, el reto que me plantee consistía en como conseguir espaciar las líneas que componen un pop-menú en Omnis Studio para la Web, la siguiente imagen describe lo que se pretende conseguir:


Haciendo un poco de investigación, se puede observar que omnis monta una tabla (etiqueta html ≤table≥) a la que asigna un nombre de clase (atributo class) compuesta del siguiente modo: [nombre-del-remoteform]_[id-del-objeto-pop-menu]_clientTable de modo que lo que hice fue incluir un identificador de clase y algunos atributos CSS en el documento "user.css" que Omnis suministra al efecto.

Ejemplo:


.RemoteForm_1001_clientTable {
border-collapse: separate;
border-spacing: 0px 10px;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
}

En el ejemplo, he añadido algo de separación  entre el primero y último elemento del grupo. Les animo a que prueben variantes del código expuesto adaptándolo a sus necesidades.

Otra variante de este CSS podría ser lo siguiente...

.RemoteForm_1001_clientTable td {
     height: 31px; 
}

...esto modificará únicamente las líneas del menú cambian su altura y por tanto también el espacio entre ellas, éste último caso es el que más me gusta y que uso habitualmente para mis menús.

NOTA: Creo que los ingenieros de Omnis se han hecho eco de éste artículo, pues en la versión 8.1.6, ya se incluyen nombres de clases CSS para poder realizar éste tipo de cambios más facilmente, para el caso que nos ocupa, sería cambiar ".RemoteForm_1001_clientTable" por ".omnis-menu-table", de éste modo funcionará para con todos los menús de nuestra aplicación.


18 enero 2018

Notificaciones y diálogos con AppleScript y Omnis Studio 8.1


En esta entrada del blog, quisiera exponer un pequeño ejemplo sobre cómo enviar notificaciones y diálogos al sistema macos, las notificaciones pueden resultar muy útiles, pues permiten enviar mensajes al usuario si esperar a que sean aceptados por éste, por otra parte, los diálogos del sistema mantendrá en suspenso la ejecución de Omnis hasta la aceptación del mismo por parte del usuario, pero salva las limitaciones en cuanto a longitud del texto a mostrar en el mismo.

A continuación un ejemplo de cada caso:

Método: $notificacion

Begin text block
Text: {display notification "Una notificación: Hola"}
End text block
Get text block lScript
Do $runapplescript(lScript;lResultado;lError)

Método: $dialogo

Begin text block
Text: {display dialog "Un texto my largo donde quiero explicar todo lo que hace éste programa, un texto my largo donde quiero explicar todo lo que hace éste programa, un texto my largo donde quiero explicar todo lo que hace éste programa,un texto my largo donde quiero explicar todo lo que hace éste programa, un texto my largo donde quiero explicar todo lo que hace éste programa, un texto my largo donde quiero explicar todo lo que hace éste programa, un texto my largo donde quiero explicar todo lo que hace éste programa, un texto my largo donde quiero explicar todo lo que hace éste programa." buttons {"Aceptar"} default button "Aceptar"}
End text block
Get text block lScript
Do $runapplescript(lScript;lResultado;lError)

Saludos cordiales a todos los seguidores de éste blog.