Archivi tag: How-to

Ottenere le coordinate GPS dal browser con HTML5

Un modo semplice e veloce per ottenere le coordinate gps ,in una pagina html, mediante html5 .

La funziona javascript getCurrentPosition interroga ,se disponibile ,il nostro dispositivo gps (previa richiesta di autorizzazione)  . Se non riesce ad ottenerla da gps può comunque derivarla dall’indirizzo ip, ma il comportamento e le regole sono completamente a carico dell’implementazione del browser.

Questa è la funzione che va usata:

1
2
3
4
5
6
7
8
9
10
11
12
13
if(navigator.geolocation){

navigator.geolocation.getCurrentPosition(successCallback,

errorCallback,

{timeout:60000});

}else{

alert("Il browser non ha un dispositivo GPS");

}

Come vedete la funzione ha due callback, uno che viene invocato in caso di successo e l’altro di errore. Nei parametri e’ possibile impostare il timeout, cioè il tempo di attesa di synch con il gps prima di andare in errore di timeout. Da notare che questo tempo scatta da prima che appaia la popup di richiesta autorizzazione, quindi influisce molto nell’usabilità dell’interfaccia utente. 60 secondi in genere sono un valore sufficiente.

Ora descriviamo cosa deve fare la nostra pagina con i due callback:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//callback in caso di successo

function successCallback(position){

alert("Posizione:[lat="+position.coords.latitude+"][long="+position.coords.longitude+"]");

}

//callback in caso di errore

function errorCallback(error){

switch(error.code){

case error.PERMISSION_DENIED: alert('accesso negato');break;

case error.POSITION_UNAVAILABLE:alert('impossibile ottenere posizione');break;

case error.TIMEOUT:alert('timeout');break;

default: alert('errore generico');break;

}

}

Alcuni browser memorizzano l’autorizzazione con durata giornaliera, altri richiedono l’autorizzazione ogni volta.

Una cosa a cui prestare attenzione è il fatto che la funzione è asincrona, quindi difficile da gestire all’interno di un evento di button pressed o cose simili.

Consigli:

Meglio sfruttarlo nell’onload del document , magari facendo una pagina adHoc che aspetti il timeout della funzione mostrando l’icona di loadinprogress, in modo da far capire all’utente che la lettura dei dati dal gps è in corso.

Qui troverete una documentazione accurata, anche se solo in draft, ma vi consiglio di testare le vostre pagine con tutti i browser in quanto hanno comportamenti molto differenti.

http://dev.w3.org/geo/api/spec-source.html

 

Java AspectJ e Spring Framework: Aspect Oriented Programming in poche mosse

Il caso: vogliamo realizzare una funzione monitoraggio sulle nostre classi senza dover modificare tutta la nostra applicazione. Un sistema molto veloce è quello di utilizzare Aop.

Andiamo quindi a realizzare un aspetto che esegua rilevazioni di tempi (ovviamente e’ solo un esempio , ci sono centinaia di sistemi per farlo) sull’esecuzione di un metodo in particolare di alcune classi che andremo ad intercettare.

Realizzeremo quindi un aspect che scatterà durante l’esecuzione (around) di un particolare metodo di una particolare famiglia di classi che definiremo direttamente su spring. Questo ci permetterà di rilevare il tempo alla chiamata, eseguire il metodo, e rilevare il tempo a fine chiamata o a eccezione tornata.

Ovviamente ci sono molti modi per fare questo (utilizzando le annotations ad esempio).

Questo esempio e’ fatto completamente sfruttando il lato configurazione, con nessun intervento specifico sul nostro sorgente iniziale(apparte la definizione del nostro advice), quindi adatto ad essere introdotto in un progetto gia in fase avanzata di sviluppo.

Innanzitutto definiamo la classe che rappresenta il nostro advice:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package it.mypackage.aspect;

import org.aspectj.lang.ProceedingJoinPoint;

public class AspectProfiler {

public Object profile(ProceedingJoinPoint call,MiContesto context) throws Throwable {

long start = System.nanoTime();

//proseguo con l'invocazione del metodo intercettato

try {

return call.proceed();

}catch(Exception ex){

ex.printStackTrace();

throw new Exception(ex);

}finally{

long stop = System.nanoTime();

System.out.println("Tempo esecuzione:" + ((stop-start)/1000000) + " ms");

}

}

}

Utilizziamo Spring 3 , quindi come prima cosa portiamo dentro il nostro file di configurazione i namespace corretti:

importante il namespace AOP.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:p="http://www.springframework.org/schema/p"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

http://www.springframework.org/schema/context

<a href="http://www.springframework.org/schema/context/spring-context-3.0.xsd">
http://www.springframework.org/schema/context/spring-context-3.0.xsd</a>">

Ora sempre nel file di configurazione abilitiamo il component-scan del package interessato ad essere intercettato e proxato:

1
2
3
<context:annotation-config/>

<context:component-scan base-package="it.mypackage" />

Ora definiamo il nostro advice, l’aspetto profiler:

1
<bean id="profiler" class="it.mypackage.aspect.AspectProfiler" />

Ovviamente per poter essere intercettati in maniera corretta, gli oggetti devono essere creati tramite la bean factory di

Spring (in quanto devono essere creati come proxy) quindi definiti al suo interno:

1
<bean id="miaClasse" class="it.mypackage.mieclassi.miaclasseimpl/>

Ora definiamo tutta la parte aop su spring:

  • definiamo un aspetto e come riferimento gli diamo l’id del bean che mappa il nostro advice definito in precedenza;
  • definiamo un pointcut, dandogli un id arbitrario, e un’espressione . Questo è a tutti gli effetti il joint-point che una volta raggiunto (al verificarsi dell’espressione) nell’esecuzione del nostro codice, farà scattare ed eseguire l’advice;
  • definiamo la tipologia dell’advice come around(intorno all’esecuzione del metodo) e indichiamo il metodo dell’advice che verrà eseguito, ad esempio il metodo “profile” nell’espressione andiamo ad indicare che il joint-point da intercettare e’ quando viene eseguito il metodo execute di una classe che estenda la classe MiaClasseBase e che abbia come argomento un parametro chiamato context.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<aop:config >

<aop:aspect ref="profiler">

<aop:pointcut id="theExecutionOfExcecMethod"

expression="execution(* it.mypackage.mieclassi.MiaClasseBase+.execute(*)) and args

(context)"
/>

<aop:around pointcut-ref="theExecutionOfExcecMethod" method="profile"/>

</<aop:aspect >

</aop:config >

Utilizzando un bean con id miaClasse ottenuto dal context di spring, vedremo eseguire il codice del nostro advice..

La documentazione di AspectJ e di Spring Framework e’ in continua evoluzione, quindi vi consiglio di controllarla spesso.

NSXmlParser il default XmlParser di iOS

Per chi lavora da molto con la programmazione, sia Java che .Net, avere a disposizione un Dom per la lettura dei files xml tramite un documento a grafo e magari espressioni xpath, è oramai legge.

Eppure per lavorare su IPhone tramite iOS e in generale su Mac OSX, di default troviamo solo ed esclusivamente un SaxParser, l’NSXmlParser..

Superato l’impatto delle Sax (da sempre ostiche ma sicuramente molto performanti), facciamo un velocissimo esempio di come usarle in una nostra classe, per leggere velocemente dei dati da un file xml.

Innanzitutto aggiungiamo l’interfaccia  NSXMLParserDelegate alla classe che riceverà gli eventi Sax, perche le Sax lavorano completamente ad eventi. Quando verrà lanciato il parser, scatteranno eventi ogni volta che si verificherà una condizione (aperto nodo, presenza testo, chiuso nodo, etc etc etc )

1
@interface MiaClasse : NSObject <NSXMLParserDelegate>

 

in questa classe (che può essere una qualsiasi classe del nostro progetto, dichiariamo l’xml parser nell’header , l’elemento che conterrà l’array di dati che andiamo ad estrarre, i puntatori per i singoli valori (on the fly come variabili secche, ma in genere meglio definire un oggetto Item che esponga tutti gli attributi), il puntatore all’elemento xml corrente che il parser sta analizzando:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@interface MiaClasse : NSObject <NSXMLParserDelegate>

//parser

NSXMLParser *xmlParser;

//array che conterrà i dati

NSMutableArray *elencoItems;

//variabile temporanea per ogni elemento

NSMutableDictionary *item;// nome del nodo corrente che il sax parser sta analizzando

NSString *currentElement;

//elementi che leggeremo e poi memorizzeremo

NSMutableString *nome, *cognome, *indirizzo;

ora che abbiamo definito l’header, passiamo all’implementazione.

Inizializziamo il parser e l’array di dati nel metodo in cui lo andiamo ad usare, nel costruttore o dove vogliamo.

In questo caso andiamo a leggere il file xml da risorsa locale, ma possiamo accedere tranquillamente ad un file remoto .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- (void)applicationDidFinishLaunching:(UIApplication *)application {

elencoItems= [[NSMutableArray alloc] init];

xmlParser = [[NSXMLParser alloc] initWithData:[NSData dataWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"test.xml"]  ]];

//definiamo il delegato che riceverà gli eventi (in questo caso la classe stessa

[xmlParser setDelegate:self];

//saltiamo i problemi di namespace

[xmlParser setShouldProcessNamespaces:NO];

[xmlParser setShouldReportNamespacePrefixes:NO];

[xmlParser setShouldResolveExternalEntities:NO];

// avviamo il parsing XML

[xmlParser parse];

}

 

ora definiamo i metodi essenziali per soddisfare l’interfaccia NSXMLParserDelegate:

didStartElement , che viene eseguito ad ogni inizio di elemento xml trovato

didEndElement, che viene eseguito quando viene analizzata la chiusura di un tag xml

foundCharacters, che viene eseguito quando si analizza il contenuto di tipo “text” di un elemento

parserDidEndDocument, che scatta quando si raggiunge la fine del documento xml.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{

currentElement = [elementName copy];

//qui mettiamo tutte le regole di match del nostro xml, ad esempio cosa fare quando

// si incontra un nodo denominato "persona"

if ([elementName isEqualToString:@"persona"]) {

// inizializza tutti gli elementi che conterranno i dati. memorizzeremo ogni item come tabella per praticità

item = [[NSMutableDictionary alloc] init];

nome = [[NSMutableString alloc] init];

cognome = [[NSMutableString alloc] init];

indirizzo = [[NSMutableString alloc] init];

}

}

 

Nel metodo didEndElement andremo fisicamente a prendere i dati letti e a memorizzarli in una struttura (il nostro array)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{

if ([elementName isEqualToString:@"persona"]) {

[item setObject:nome forKey:@"nome"];

[item setObject:cognome forKey:@"cognome"];

[item setObject:indirizzo forKey:@"indirizzo"];

[elencoItems addObject:[item copy]];

}

}

 

Ed ora il metodo che fisicamente legge i dati dai nodi:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {

if ([currentElement isEqualToString:@"nome"]){

[nome appendString:string];

} else if ([currentElement isEqualToString:@"cognome"]) {

[cognome appendString:string];

} else if ([currentElement isEqualToString:@"indirizzo"]) {

[indirizzo appendString:string];

} }

 

Infine se a termine del traversing del grafo xml dobbiamo effettuare delle operazioni, come prendere il risultato e passarlo ad altri oggetti, utilizziamo il parserDidEndDocument:

1
2
3
4
5
6
7
- (void)parserDidEndDocument:(NSXMLParser *)parser {

[mioOggetti setData:elencoItems];

[elencoItems release];

}

In linea di massima e’ molto semplice utilizzare XmlParser.

Come tutti i framework e metodologie su iOS si fa un grande uso dei delegati.

Spero di esservi stato di aiuto.