La intención de este blog es recoger las experiencias de un desarrollador de aplicaciones con Omnis Studio.
Etiqueta
17 abril 2024
Integración Paypal REST API con Omnis Studio
06 junio 2023
Omnis Studio 11, soporte para TOTP
OW3.$totpgenerate(xSharedSecretKey,iTimeStep,iDigits,&iTOTP[,&cErrorText,iHashType=kOW3hashSHA1])
Esta función genera una contraseña de un solo uso con base en el tiempo, quedará contenida en iTOTP y se utilizará para ello el algoritmo TOTP. Retornado "true" si la función es ejecutada con éxito.
Parámetros obligatorios:
xSharedSecretKey (Binary) es la clave secreta compartida, su longitud debe estar entre 16 y 256 bytes.
iTimeStep (Integer 32 bit) es el salto de tiempo en segundos el cual deberá estar entre 1 y 3600.
iDigits (Integer 32 bit) es el número de dígitos del TOTP resultante, un valor entre 6 y 8.
iTOTP (Integer 32 bit) recibe el TOTP generado.
Parámetros opcionales:
cErrorText (Character 100000000) Si se proporciona, recibirá la descripción del posible error provocado por $totpgenerate o $totpvalidate (si resultó "false").
iHashType (Integer 32 bit), su valor por defecto es proporcionado por la constante kOW3hashSHA1) es el tipo de "hash" a utilizar, use una de las constantes del grupo kOW3hash...
La segunda contiene 4 parámetros necesarios, más 4 opcionales y su sintaxis es la siguiente:
OW3.$totpvalidate(xSharedSecretKey,iTimeStep,iDigits,iTOTP[,&cErrorText,iHashType=kOW3hashSHA1,iStepsBefore=2,iStepsAfter=1])
Esta función valida la contraseña de un solo uso con base en el tiempo, contenida en iTOTP utilizando para ello el algoritmo TOTP. Retornado "true" si iTOTP resulta en un TOTP válido.
Parámetros obligatorios:
xSharedSecretKey (Binary) es la clave secreta compartida, su longitud debe estar entre 16 y 256 bytes.
TimeStep (Integer 32 bit) es el salto de tiempo en segundos el cual deberá estar entre 1 y 3600.
iDigits (Integer 32 bit) es el número de dígitos del TOTP resultante, un valor entre 6 y 8.
iTOTP (Integer 32 bit) es el TOTP que va a ser validado.
Parámetros opcionales:
cErrorText (Character 100000000) Si se proporciona, recibirá la descripción del posible error provocado por $totpgenerate o $totpvalidate (si resultó "false").
iHashType (Integer 32 bit), su valor por defecto es proporcionado por la constante kOW3hashSHA1) es el tipo de "hash" a utilizar, use una de las constantes del grupo kOW3hash...
iStepsBefore (Integer 32 bit), el valor por defecto es 2 y es el número de saltos de tiempo anteriores al momento actual, para llevar a cabo la verificación del TOTP proporcionado, deberá ser un valor entre 1 y 20.
iStepsAfter (Integer 32 bit), su valor por defecto es 1 y es el número de saltos de tiempo después del momento actual, para llevar a cabo la verificación del TOTP proporcionado, deberá ser un valor entre 1 y 20.
26 noviembre 2020
03 julio 2020
Nuevo asistente para la construcción de aplicaciones finales (Deployment Tool)
Opciones macOS
Opciones Windows
- La opción "Flat tree" generará una carpeta simple con todos los archivos, los de lectura y los de lectura/escritura.
- La opción "Split tree" generará una carpeta con los archivos de solo lectura, es decir aquellos cuyo destino será "Program Files" y otra de lectura/escritura con los destinados a "AppData".
- La opción "Split Tree with firstruninstall" generará una carpeta con los archivos de solo lectura y dentro de esta, otra adicional denominada "firstruninstall", con los archivos de lectura/escritura que Omnis copiará automáticamente sobre la carpeta "AppData" del usuario, la primera vez que ejecute la aplicación.
Uso del editor de recursos "RCEdit"
- $setapplicationmanifest(cFile, cManifest), cambia el manifiesto incluido cManifest según la ruta indicada por cFile), ejemplo: Do rcedit.$setapplicationmanifest(“C:\omnis.exe”, “C:\folder\newManifest.xml”) Returns #F
- $setresourcestring(cFile, cResource, cValue), cambia el recurso "cResource" por el valor de "cValue" para según la ruta indicada en "cFile", ejemplo: Do rcedit.$setresourcestring(“C:\omnis.exe”, “1”, “Nuevo valor”) Returns #F
- $setproductversion(cFile, cProductVersion), cambia el recurso del ejecutable Windows "Product Version" según lo indicado en cProductVersion para la ruta del archivo cFile, ejemplo: Do rcedit.$setproductversion(“C:\omnis.exe”, “10.1”)
- $seticon(cFile, cIcon), cambia el icono del ejecutable Windows indicado la ruta del archivo cFile, por el archivo ".ico", indicado en la ruta cIcon, ejemplo: Do rcedit.$seticon(“C:\omnis.exe”, “C:\newIcon.ico”) Returns #F
- $setversionstring(cFile, cVersion, cValue), cambia el texto de versión en "cVersion" por el especificado en "cValue" según la ruta indicada en cFile, ejemplo: Do rcedit.$setversionstring(“C:\omnis.exe”, “Comments”, “Comment version string”) Returns #F
- $setfileversion(cFile, cFileVersion), cambia el recurso del ejecutable Windows "File Version" por el contenido en cFileVersion, ejemplo: Do rcedit.$setfileversion(“C:\omnis.exe”, “10.1.0.0”) Returns #F
13 febrero 2020
Cómo mostrar un PDF desde un campo BLOB de Oracle sobre el navegador, sin descargarlo
# El dato BLOB de Oracle es iDocumentos.DOCUMENTO# pdfBuffer es una variable var de JavaScript# el método ha sido marcado como "Execute On Client"
Calculate pdfBuffer as iDocumentos.DOCUMENTOJavaScript: var arrayBuffer = base64ToArrayBuffer(pdfBuffer);JavaScript: function base64ToArrayBuffer(base64) {JavaScript: var binaryString = window.atob(base64);JavaScript: var binaryLen = binaryString.length;JavaScript: var bytes = new Uint8Array(binaryLen);JavaScript: for (var i = 0; i < binaryLen; i++) {JavaScript: var ascii = binaryString.charCodeAt(i);JavaScript: bytes[i] = ascii;JavaScript: }JavaScript: return bytes;JavaScript: }JavaScript: var blob = new Blob([arrayBuffer], {type: "application/pdf"});JavaScript: var link = window.URL.createObjectURL(blob);JavaScript: window.open(link);
On evTimerDo $cinst.$objs.timerObj.$running.$assign(kFalse)Do $cinst.$muestraPdf()
Calculate lCompara as con("where ROWID = '";iListaDctos.ROWID;"'")Do iDocumentos.$select(lCompara) Returns #FIf flag trueDo iDocumentos.$fetch()If not(isclear(iDocumentos.DOCUMENTO))Do $cinst.$objs.timerObj.$running.$assign(kTrue)End IfEnd If
El código encargado de recuperar el documento desde la base de datos, es también el encargado de activar el timer, que fue previamente alojado en el navegador del cliente.
Gracias de nuevo a Francesco de soporte Omnis, por este maravilloso truco.
22 enero 2020
La librería de conversión de DML a SQLite
Close datafile, Close lookup file, Create datafile, Floating default datafile, Open datafile, Open lookup file, Prompt for datafile, Set current datafile, Set default datafile, lookup(), Build indexes, Delete data, Drop indexes, Open runtime datafile browser, Rename data, Cancel prepare for update, Delete, Delete with confirmation, Do not flush data, Do not wait for semaphores, Flush data, Flush data now, Prepare for edit, Prepare for insert, Prepare for insert with current values, Test for only one user, Update files, Update files if flag set, Wait for semaphores, Clear all files, Clear main & connected, Clear main file, Clear range of fields, Clear selected files, Set main file, Clear find table, Disable relational finds, Enable relational finds, Find, Find first, Find last, Load connected records, Next, Previous, Prompted find, Single file find, Test for a current record, Test for a unique index value, Clear search class, Reinitialize search class, Set search as calculation, Set search name, Test data with search class, Clear sort fields, Set sort field, Build list from file, Begin reversible block, End reversible block, Quit all methods, $root.$getodbfilelist(), y alguna funciones de sys(), como: sys(11), sys(139), sys(3000) & sys(3001)
Open datafile sdb://192.168.0.10:5743/SQLiteTest
Pero si queremos también podemos optar por cambiar éste comando y hacer uso de la sintaxis de notación del modo siguiente:
Do omsqlSess.$logon(‘sdb://192.168.0.10:5743/SQLiteTest’,’’,’’) Returns #F
15 octubre 2019
¿Cómo evitar el diálogo "Install the legacy Java SE 6 runtime" en Omnis Studio 10.1 y Catalina?
≤key≥JVMCapabilities≤/key≥por:
≤array≥
≤string≥CommandLine≤/string≥
≤/array≥
≤key≥JVMCapabilities≤/key≥
≤array≥
≤string≥CommandLine≤/string≥
≤string≥JNI≤/string≥
≤string≥BundledApp≤/string≥
11 octubre 2019
¿Cómo Ignorar el aviso de actualización a Catalina?
Afortunadamente sí, sólo necesitas introducir el siguiente comando...
sudo softwareupdate --ignore "macOS Catalina"..si más adelante deseas volver a la situación anterior, introduce...
sudo softwareupdate --reset-ignored
...y ¡ya está! no correrás el peligro de que puedas actualizar a Catalina en un momento no deseado.
16 septiembre 2019
Conexión nativa a Microsoft SQL Server con Omnis Studio 10
30 agosto 2019
Acceso a datos con aplicaciones Web
El método Omnis que nos permite hacer esto se denomina $makepool, puesto que Omnis creará el grupo de sesiones de modo global (bajo $root), parece lógico invocarlo desde un método (por ejemplo $acceso) situado en la clase "Startup_Task" y que será ejecutado desde su $construct. Eso garantizará que cada vez que se haga disponible nuestra aplicación Web (se abra la librería) el grupo sea automáticamente creado. El código será algo como esto:
Do $extobjects.PGSQLDAM.$objects.PGSQLSESS.$makepool('myPool',1,'192.168.10.10','myUser','myPassword') Returns iMyPoolRef
El segundo parámetro (1 en el ejemplo) es el número de sesiones de que constará el grupo inicialmente, lo cual no plantea ningún problema, ya que todo "session pool", dispone de propiedades que nos permiten (entre otras cosas) aumentar ésta cifra según surja la necesidad debido al incremento en el número de usuarios que esten haciendo uso de la aplicación Web, o simplemente conocer su cifra actual.
El primer parámetro del método $makepool es el nombre que identifica al grupo de sesiones de modo único. Dado que su existencia es global (nivel $root), deberá eliminarse cuando se destruya su "Startup_Task"". Esto significa que no podrá existir otro grupo de sesiones con el mismo nombre. La variable "iMyPoolRef" nos permite referenciar al grupo creado, pero tambien disponemos de un modo para conocer todos los posibles y diferentes grupos de sesiones que puedan llegar a existir bajo un mismo servidor de aplicaciones Omnis, en $sessionpools.
Para cerrar el grupo de sesiones, usaremos el siguiente código situado en el método $destruct de nuestra clase "Startup_Task":
Do $sessionpools.$remove(iMyPoolRef)
Note que "iMyPoolRef" es una variable de instancia y tipo "Item Reference" cuyo valor ha sido asignado por el método $makepool.
Ahora explicaremos cómo solicitar una nueva sesión al grupo, con el fin de otorgársela al usuario durante el tiempo que esté usando nuestra aplicación Web, para ello usaremos el metodo $new. Con éste fin crearemos un nuevo método en nuestra clase "Startup_Task" al que denominaremos $getSessionFromPool, con el siguiente código:
If iSessionPoolRef.$poolsize=iSessionPoolRef.$inuse
Do iSessionPoolRef.$poolsize.$assign(iSessionPoolRef.$inuse+1)
End If
Quit method iSessionPoolRef.$new()
El tamaño del grupo de sesiones ($poolsize) puede ser aumentado en cualquier momento, nosotros lo haremos comprobando si se ha alcanzado su límite actual ($poolsize=$inuse) y cada vez que requiramos de una nueva sesión. El método $new retornará un nuevo objeto de sesión para acceso a datos.
Ahora nos queda una cuestión importante por resolver, ¿Cómo ejecutar el método $getSessionFromPool ubicado en la calse "Startup_Task" desde una clase "Remote_task"?
Naturalmente necesitamos hacerlo así, ya que queremos asignar la nueva sesión a cada nueva conexión remota. Empezaremos por crear una variable de tipo task, en la clase "Remote_task", donde alojar el nuevo objeto de acceso a datos, la llamaremos "tSessionObj", también resultará lógico que el código para invocar al método $getSessionFromPool lo situemos en el método $construct de la "Remote_task", la respuesta a la pregunta del párrafo anterior sería:
Do $itasks.myLib.$getSessionFromPool() Returns tSessionObj
El literal "myLib" deberá corresponder al nombre de nuestra librería o bien usar la notación [$clib().$name] (importante usar los corchetes) para obtener el nombre de la misma, si optamos por esto último estaríamos garantizando su funcionamiento aunque se llegue a cambiar el nombre asignado inicialmente a la librería.
Esto es todo o casi todo, ahora sólo nos quedaría asignar la sesión (normalmente) a la o las clases "table" que use nuestra aplicación Web, para esto lo más habitual es disponer de una super-clase "table" que será heredada por el resto de clases "table", de ese modo escribiremos nuestro código de asignación de sesión una única vez.
Suponiendo que el nombre de nuestra super-clase es "taSuper", escribiríamos en su método $construct lo siguiente:
Do $cinst.$sessionobject.$assign(tSessionObj)
Naturalmente el resto de clases "table", heredaran este método constructor, aunque también pueden tener el suyo propio, pero si lo usamos, tendremos que utilizar el comando "Do inherited" para ordenar la ejecución del método $construct en la superclase.
24 mayo 2019
Creación de paquetes firmados para la instalación de aplicaciones Omnis en MacOS
- Preparar tu "First Run Install" con los archivos propios de la aplicación.
- Instalar los ficheros .df1 en modo de sólo-lectura.
- Crear tu propio "package" (.pkg) de instalación.
- Colocar "script's" dentro del "package".
- Construir el "package", desde una opción de menú o mediante Cmd+B.
- Firmar el "package" resultante, para su distribución.
- Probar su carga/descarga, instalación y ejecución.
#!/usr/bin/env bash
# Este script se ejecuta una vez instalada la aplicación.
# Indica la ruta hacia tu aplicación
APPLICATION_ROOT="/Jyotish Studio 4.0/JS4.app"
# Estabece permisos
sudo chown -R root:admin "${APPLICATION_ROOT}"
sudo chmod -R 775 "${APPLICATION_ROOT}"
#!/usr/bin/env bash
# Este script se ejecuta una vez instalada la aplicación.
# Indica la ruta hacia tu aplicación
APPLICATION_ROOT="/Applications/Omnis Studio Runtime 8.0.2 x64.app"
# Estabece permisos
sudo chmod -R a+rw "${APPLICATION_ROOT}/Contents/MacOS/startup"
sudo chmod -R a+rw "${APPLICATION_ROOT}/Contents/MacOS/icons"
sudo chmod -R a+rw "${APPLICATION_ROOT}/Contents/MacOS/iconsets"
sudo chmod -R a+rw "${APPLICATION_ROOT}/Contents/MacOS/local"
sudo chmod -R a+rw "${APPLICATION_ROOT}/Contents/MacOS/omnispdf"
sudo chmod -R a+rw "${APPLICATION_ROOT}/Contents/MacOS/studio"
# Para Brainy Data's PDFDevice (omitir si no se usa)
sudo chmod a+rw ../MacOS
08 marzo 2019
Firmado y localización de aplicaciones (Parte 1 de 3)
Las carpetas "Firstruninstall" y "Application Support"
¿Qué ocurre si necesito actualizar o añadir algún componente ubicado en "xcomp" o "jscomp"?
¿Qué debo hacer para personalizar la instalación de mi aplicación y cambiar la firma?
¿Qué ocurre si necesito actualizar el núcleo de Omnis de mi aplicación final?
- Reemplazar el binario Omnis original firmado por la nueva versión.
- Volver a firmar Omnis con la misma identidad de firma que utilizó para el original.
- Usar el binario parcheado de su directorio para su distribución.
07 marzo 2019
Firmado y localización de aplicaciones (Parte 2 de 3)
Personalización de las opciones en el menú del sistema macOS
- Abra el "Omnis Catalog" (pulse F9) de Omnis Studio para MacOS
- Seleccione la pestaña "String Tables" y haga clic derecho sobre "Built-in strings"
- Introduzca los textos originales sobre la columna de la STRINGID y el texto a cambiar sobre la/s columnas correspondientes al idioma 'en', 'es_es', etc.
Un pequeño apunte final a modo de recordatorio
06 marzo 2019
Firmado y localización de aplicaciones (Parte 3 de 3)
Un par de apuntes
05 marzo 2019
Uso de iconos en Omnis Studio (Parte 1 de 2)
- En el "Iconset Studio" personalizado para nuestra librería, una sub-carpeta de "inconsets", ruta indicada en su propiedad "$iconid".
- En la tabla #ICONS de nuestra librería. (si existe)
- En los archivos de datos para iconos, los llamados ".df1", excepto "omnispic" y "userpic", (si existen)
- En la sub-carpeta denominada "studio" situada dentro de "inconsets"
- En los archivos "Omnispic.df1" y "Userpic.df1".
04 marzo 2019
Uso de iconos en Omnis Studio (Parte 2 de 2)
Denominación de archivos imagen
- "texto" Es el nombre de la imagen. Aparecerá en el cuadro de diálogo del selector de iconos, mientras asigna el “$iconid” de un objeto.
- "id" es el ID (valor entero positivo) utilizado como ID del icono. Deberá estar en el rango de 1 a 10.000.000
- "tamaño" es el tamaño expresado en píxel CSS de la imagen independiente de su resolución, lo que significa que éste valor no cambiará, para con todas sus diferentes resoluciones. Su valor debe ser expresado en la forma “
x ”, los valores 16x16, 32x32 y 48x48 deberán existir siempre, ya que corresponden a los tamaños estándar admitidos por Omnis. - "resolución" es el factor que identifica su densidad de píxeles, la cual deberá expresarse del modo siguiente:
- "_ 2x" para dispositivos HD o pantalla Retina.
- "_15x" para ciertos dispositivos, como por ejemplo teléfonos con una densidad de píxeles de 1.5x. no será necesario especificar valor alguno para dispositivos con una resolución estándar, o equivalente a _1x
pencil_1657_16x16.png
|
Icono con "estado"
|
pencil_1657_16x16_2x.png
|
Icono con "estado"
|
check_1658_32x32c_2x.png
|
Icono con estado
|
Iconos para casillas de verificación
- "estado" es el estado en que se encuentra el icono (“marcado”, “resaltado” o “normal”) y puede ser uno de los siguientes: (dejarlo en blanco indica su estado “normal”).
- “c” corresponde a la situación de “marcado” del icono
- “h” corresponde a la situación de “resaltado” del icono
- “x” corresponde a la situación de “marcado” y “resaltado” del icono