• Like
Tiyla @Whymca '11
Upcoming SlideShare
Loading in...5
×
Uploaded on

Tiyla is an infrastructure that enables management of software internationalization. …

Tiyla is an infrastructure that enables management of software internationalization.

- Multiplatform Libraries
- Public Api
- Support for multiple translation Crews
- Support for Crowdsourcing
- Community database of translations
.. and more :]

More in: Business , Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
302
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
2
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Mobile Translation System in CrowdsourcingStefano ZingariniLuca Figoli
  • 2. About Us xiaprojects.com  &  @xiateam2
  • 3. Our Projects3
  • 4. About Us Chi  siamo Dal  1998  sviluppiamo  so/ware  per  ges4one  da4  su  interfaccia  Web   Nel  2004  realizzata  prima  versione  piaAaforma  RAD  e  BPM  -­‐ Dal  2009  introdoAa  estensione  Mobile  Mul4piaAaforma   (                ,            ,                  ,  ,                                  ) Reparto  R&D  con  20  dipenden4  tecnici  (job@apparound.com) Il  Prodo.o  e  le  Soluzioni AAraverso  gli  strumen4  RAD  e  BPM  offer4  dalla  nostra  piaAaforma   possiamo  realizzare  velocemente  applicazioni  Mobile  Mul4piaAaforma  in   grado  di  ges4re,  da4,  contenu4  e  processi Chi  ha  scelto  al  nostra  tecnologia4
  • 5. About Us ERP/Web Enterprise/SaaS Apps5
  • 6. Intro: Roundup Internazionalizzazione del software oggi Interazione Software / Utente La soluzione Tiyla: Goals & Examples6
  • 7. Software & i18n Problematica non nuova ma attualissima Internazionalizzazione “Progettazione per mercati diversi da quello di origine in cui si sviluppa” Localizzazione “Le azioni volte a rendere il software fruibile per tali mercati”7
  • 8. Why i18n is a chance 11 persone su 12 nel mondo non conoscono l’Inglese Psicologicamente rassicurante pagare per un’App da poter usare nella propria lingua Affinità culturali trasversali alle lingue Raggiungere nuovi mercati / paesi non in crisi8
  • 9. Markets For All Markets Mobile & Desktop Multi-language and Multi Country Billing Support9
  • 10. With great opportunities... few problems Sviluppo • Supporto nativo i18n diverso per ogni dispositivo • Gestione “script automatici” traduzioni attraverso un sw specifico: integrazione? • Distribuzione delle traduzioni in diversi formati (crossplatform)10
  • 11. With great opportunities... few problems Gestione • A chi rivolgersi per le traduzioni • Come gestire le collaborazioni • Come gestire la validazione della traduzione • Tenere sotto controllo il processo per più lingue e più fornitori11
  • 12. With great opportunities... few problems Pubblicazione • Ri-Pubblicazione dell’applicativo quando è disponibile una nuova lingua • Diversi store / versioni • Tempi di attesa • Possibilità di reject (per qualsiasi fantasioso motivo)12
  • 13. Our Solution: Tiyla Crossplatform Crowdsourcing Libraries Collaboration Api Process Control13
  • 14. Tiyla Components Database AS Crossplatform • Community Api Libs • Applicazione API Gui Libs • Crowdsourcing Admin Manager14
  • 15. Tiyla Components Interaction15
  • 16. 3 core of Tiyla solution Trasparenza Flessibilità Crowdsourcing16
  • 17. Tiyla & Trasparenza Esigenza di Traduzioni “Trasparenti” con Tiyla nel Backend (es Software Enterprise) • Supporto alla crew di traduzione aziendale o ai Partner in outsourcing tramite Tiyla • Offerta traduzioni Tiyla Crew dai nostri partner • Disponibilità delle traduzioni di default “Community” • Generazione dei file per i18n multipiattaforma da includere offline17
  • 18. Tiyla & Trasparenza Le traduzioni sono generate all’atto della compilazione del progetto. Plugin Ambiente Tiyla Desktop di sviluppo • Il sistema Tiyla è completamente nascosto all’utente finale • L’azienda rimane proprietaria delle proprie traduzioni seguendone workflow & deploy18
  • 19. Tiyla & Trasparenza Workflow “Standard” • Registrazione  App • Abilitazione  Crew19
  • 20. Pannello di controllo Developer (OSx)20
  • 21. Tiyla & Trasparenza Workflow “Standard” • Registrazione  App • Traduzione • Abilitazione  Crew • Da  Partner • Da  Community • Da  Tiyla  Crew21
  • 22. Pannello di controllo Traduzione (Win)22
  • 23. Tiyla & Trasparenza Workflow “Standard” • File  i18n  generato   da  Plugin  in  IDE • File  i18n  generato   • Registrazione  App • Traduzione da  Desktop  Client   • Abilitazione  Crew • Da  Partner da  includere  al   • Da  Community progeOo • Da  Tiyla  Crew SELL • Build23
  • 24. Tiyla & Flessibilità Si abilita l’update dell’i18n App Remoto • Inclusione di un set base di lingue • Update remoto (via Api) di nuove lingue per l’app quando queste vengono validate • Possibilità di contribuire / usufruire del db Community delle traduzioni24
  • 25. Tiyla & Flessibilità Vantaggi: Tempo = Denaro • Possibilità di pubblicare l’applicazione partendo da una lingua base (abbattere i tempi di debutto sul mercato) • Arricchire l’app “on the fly” senza bisogno di ripubblicarla • Correggere le traduzioni al volo25
  • 26. Tiyla & Flessibilità Workflow Tiyla On The FLy • File  i18n  generato   da  Plugin  in  IDE • Registrazione  App • File  i18n  generato   • Abilitazione  Crew da  Desktop  Client   da  includere  al   progeOo • Build • Traduzione • Da  Partner • Da  Commuinity • Da  Tiyla  Crew • Correzioni26 • Nuove  Lingue SELL
  • 27. Tiyla & Crowdsourcing Perchè fa Fico?27
  • 28. Tiyla & Crowdsourcing Innumerevoli casi di successo... ...anche nell’ambito delle traduzioni sw28
  • 29. Tiyla & Crowdsourcing29
  • 30. Tiyla & Crowdsourcing Infrastruttura: • Gestione di base Utenti • Traduzione degli utenti a partire da una lingua E LU certificata E VA LU • Rating delle traduzioni VA • Conteggio attività dell’utente in Crowd Tiyla – Rating degli utenti (individuare best & worst) E LU – Possibilità di indire contest VA30
  • 31. Into the Code &31
  • 32. Tiyla & iOS (1/5)32
  • 33. Tiyla & iOS (2/5)33
  • 34. Tiyla & iOS (3/5)34
  • 35. Tiyla & iOS (4/5)35
  • 36. Tiyla & iOS (5/5)36
  • 37. iOS + MacOS: Supporto Nativo • Prevede un file “Localizzato” aggiunto al bundle del progetto • Automatico in base alla lingua impostata nel dispositivo • API da utilizzare • Traduce anche i contenuti XIB Disegnati usando il Designer37
  • 38. iOS + MacOS: Supporto Nativo38
  • 39. iOS + MacOS: Supporto Nativo Aggiungo la lingua a Localizable.strings Completo le traduzioni39
  • 40. iOS + MacOS: Supporto Nativo NSLocalizedString(@”Hello World”,@”Label Description”);40
  • 41. iOS + MacOS: Supporto Nativo • Richiede la ricompilazione: File (*) da mettere nel bundle • Aggiungere un file per ogni nuova lingua da tradurre • Modificare tutti i file se cambia la lingua del “programmatore”41
  • 42. Tiyla & iOS: .h //! Profile management //! create new profile, or if exist and password match return TRUE -(BOOL)registerProfile:(NSString *)email password:(NSString *)password; //! verify your password -(BOOL)loginProfile:(NSString *)email password:(NSString *)password; //! remove profile -(BOOL)dropProfile:(NSString *)email password:(NSString *)password; //! return data for profile, if password is empty you will receive public informations -(NSDictionary *)getProfile:(NSString *)email password:(NSString *)password; //! Developer API: //! create new Application, if application exists does do nothing -(NSString *)registerApp:(NSString *)bundleId email:(NSString *)email password:(NSString *)password; //! set KeyPairs App info to db -(BOOL)setApp:(NSString *)bundleId email:(NSString *)email password:(NSString *)password data:(NSDictionary *)data; //! Crew manage -(BOOL)linkCrew:(NSString *)emailCrew toApp:(NSString *)bundleId email:(NSString *)email password:(NSString *) password; -(BOOL)unlinkCrew:(NSString *)emailCrew toApp:(NSString *)bundleId email:(NSString *)email password:(NSString *) password; //! Translations Update Crew -(BOOL)setTApp:(NSString *)bundleId email:(NSString *)email password:(NSString *)password language:(NSString *) language data:(NSDictionary *)data; //! Translations Update Developer -(BOOL)setTRankApp:(NSString *)bundleId email:(NSString *)email password:(NSString *)password language:(NSString *) language data:(NSDictionary *)data; //! Translations Client -(NSDictionary *)getApp:(NSString *)bundleId email:(NSString *)email password:(NSString *)password data:(NSDictionary *)data; //! get Translation * work with shots * -(NSDictionary *)getTApp:(NSString *)bundleId email:(NSString *)email password:(NSString *)password language: (NSString *)language data:(NSDictionary *)data;42
  • 43. Tiyla & iOS: RAPI +(NSMutableDictionary *)rapi:(NSURL *)url data:(NSDictionary *)data { //! Data Variables NSString *jsonStringEncodedData=nil; ! NSData *dataFromJson=nil; ! NSData *dataCompressedFromJson=nil; NSMutableURLRequest *urlRequest =nil; NSData *replyFromServer=nil; NSString *replyFromServerString=nil; NSMutableDictionary *returnResponse=nil; //! JSON Engine SBJsonWriter *jsonWriter=[[SBJsonWriter alloc] init]; SBJsonParser *jsonParser=[[SBJsonParser alloc] init]; //! Some casts jsonStringEncodedData=[jsonWriter stringWithObject:data]; ! dataFromJson=[jsonStringEncodedData dataUsingEncoding:NSUTF8StringEncoding]; dataCompressedFromJson=[self gzipData:dataFromJson]; ! ! //! Prepare Remote API ! urlRequest =[NSMutableURLRequest requestWithURL:url]; ! [urlRequest setHTTPMethod:@"POST"]; [urlRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; ! [urlRequest setHTTPBody:dataCompressedFromJson]; ! //! Reply RAPI ! replyFromServer=[NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:nil]; ! replyFromServerString=[[NSString alloc] initWithData:replyFromServer encoding:NSASCIIStringEncoding]; //! JSON Return returnResponse=[jsonParser objectWithString:replyFromServerString]; return returnResponse;! }43
  • 44. Tiyla & iOS: GZIP /** * GZip Compression helper for NSData */ +(NSData *)gzipData:(NSData *)pUncompressedData { z_stream zlibStreamStruct; // ... int initError = deflateInit2(&zlibStreamStruct, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY); // ... NSMutableData *compressedData = [NSMutableData dataWithLength:[pUncompressedData length] * 1.01 + 12]; // ... do { // ... deflateStatus = deflate(&zlibStreamStruct, Z_FINISH); // ...! ! } while ( deflateStatus == Z_OK ); // ... deflateEnd(&zlibStreamStruct); // ... [compressedData setLength: zlibStreamStruct.total_out]; // ... return compressedData; }44
  • 45. Tiyla: Server IO GZIP <?php //  Imposto  il  Xpo  di  ritorno header  ("content-­‐type:  applicaXon/json"); //  Imposto  il  fuso  orario  (il  server  è  in  USA) date_default_Xmezone_set(UTC); //  DEBUG:  Memorizzo  lora  di  partenza  per  calcolare  il  "peso"  in  fondo $start_Xme=microXme(TRUE); //  ATTENZIONE:  lo  stream  in  ingresso  POST  deve  essere  compresso $fp=gzopen("php://input","r"); //  POST:  leggo  in  input  tuOo  il  JSON  inviato  dai  client $data  =  gzread($fp,1024000);  //  1MB  in  upload  (decompresso...) //  chiudo  il  descriOore fclose($fp); $fp=0; //  genero  un  array  associaXvo  dal  POST $data=json_decode($data,true); ?>45
  • 46. Tiyla & iOS: Libreria (1/5)46
  • 47. Tiyla & iOS: Libreria (2/5)47
  • 48. Tiyla & iOS: Libreria (3/5)48
  • 49. Tiyla & iOS: Libreria (4/5)49
  • 50. Tiyla & iOS: Libreria (5/5)50
  • 51. Tiyla & MacOS: Desktop Client51
  • 52. Tiyla & MacOS: Desktop Client52
  • 53. Into the Code &53
  • 54. Android: Supporto Nativo • Sistema di localizzazione integrato basato su file xml, presenti in diverse folder con suffisso differente a seconda della lingua (values, values-it, values-fr) • Il file chiamato strings.xml è semplicemente un elenco di righe chiave – valore dove il valore è appunto la stringa tradotta. • Da codice per recuperare la stringa corrente getString (R.string.key) • Se si vuole modificare o aggiungere una nuova lingua bisogna ricompilare il programma producendo il nuovo apk e pubblicare l’aggiornamento sul market54
  • 55. Tiyla & Android: Presentazione55
  • 56. Tiyla & Android: API //!  Profile  management //!  create  new  profile,  or  if  exist  and  password  match  return  TRUE sta7c  public  boolean  registerProfile(String  email,  String  password) //!  verify  your  password sta7c  public  boolean  loginProfile(String  email,  String  password) //!  remove  profile sta7c  public  boolean  dropProfile(String  email,  String  password) //!  return  data  for  profile,  if  password  is  empty  you  will  receive  public  informaXons sta7c  public  JSONObject  getProfile(String  email,  String  password) //!  Developer  API: //!  create  new  ApplicaXon,  if  applicaXon  exists  does  do  nothing sta7c  public  String  registerApp(String  bundleId,  String  email,  String  password) //!  set  KeyPairs  App  info  to  db sta7c  public  boolean  setApp(String  bundleId,  String  email,  String  password,  JSONObject  data) //!  Crew  manage sta7c  public  boolean  linkCrew(String  emailCrew,  String  bundleId,  String  email,  String  password) sta7c  public  boolean  unlinkCrew(String  emailCrew,  String  bundleId,  String  email,  String  password) //!  TranslaXons  Update  Crew sta7c  public  boolean  setTApp(String  bundleId,  String  email,  String  password,  String  language,  JSONObject  data) //!  TranslaXons  Update  Developer sta7c  public  boolean  setTRankApp(String  bundleId,  String  email,  String  password,  String  language,  JSONObject  data) //!  TranslaXons  Client sta7c  public  JSONObject  getApp(String  bundleId,  String  email,  String  password,  JSONObject  data) //!  get  TranslaXon  *  work  with  shots  * sta7c  public  JSONObject  getTApp(String  bundleId,  String  email,  String  password,  String  language,  JSONObject  data);56
  • 57. Tiyla & Android: RAPI //Inizialmente  comprimo  i  daX  in  formato  gzip  uXlizzando   //Ricevo  i  daX  dal  server //loggeOo  GZIPOutputStream InputStream  input  =  connecXon.getInputStream(); byte[]  compressedData  =  Library.compressData String  contentEncoding  =  connecXon.getContentEncoding (dataS.getBytes()); ();   BufferedInputStream  inputB  =  new  BufferedInputStream //-­‐-­‐-­‐ (input,  10000); //Apro  una  HOpURLConnecXon  verso  il  server connecXon  =  (HOpURLConnecXon)  new  URL //-­‐-­‐-­‐ (url).openConnec8on(); while  ((nRead  =  inputB.read(data,  0,  data.length))  !=  -­‐1)   //-­‐-­‐ { //Imposto  il  parametro  "Accept-­‐Encoding"  "deflate"  per   byteAOSB.write(data,  0,  nRead); ricevere  i  daX  in  formato  compresso   } connecXon.addRequestProperty("Accept-­‐Encoding",  "deflate"); connecXon.setRequestProperty("Content-­‐Type","applicaXon/ //-­‐-­‐         json"); //ScompaOo  i  daX  dal  server received_result  =  new  String(Library.decompressData //Invio  i  daX (received_result.getBytes())); connecXon.getOutputStream().write(compressedData); //-­‐-­‐        57
  • 58. Tiyla & BlackBerry • Java • Eclipse Sdk58
  • 59. Tiyla & Nokia QT59
  • 60. Into the Code &60
  • 61. Windows & WP7: Supporto Nativo • Sistema di localizzazione integrato basato su file di risorse (resx), con nomi organizzati gerarchicamente a partire dal file della lingua di default. Ad esempio myRes.resx contiene le informazioni in lingua di default, mentre una eventuale traduzione in francese standard si ottiene aggiungendo il file myRes.fr.resx al progetto • Un file di risorse è composto da una serie di coppie chiave-valore. Tutti i file dovrebbero avere le stesse chiavi a cui corrispondono le versioni in lingua degli stessi testi • Le interfacce utente invocano le stringhe contenute nei file di risorse tramite la loro chiave, usando l’operatore binding • Se si vuole modificare o aggiungere una nuova lingua bisogna ricompilare il programma producendo il nuovo xap e pubblicare l’aggiornamento sul market61
  • 62. Tiyla & WP7: Presentazione62
  • 63. Windows & WP7: Supporto Nativo • Le chiamate al server in WP7 sono gestite in modo asincrono. • La libreria mette a disposizione una serie di eventi che vengono generati quando la chiamata è stata completata.63
  • 64. Tiyla & WP7: Metodi (1/3)                public  delegate  void  OperationCompletedDelegate  (String  result,  Exception  error);                public  event  OperationCompletedDelegate  OperationCompleted;                ///  <summary>                ///  Profile  management                ///  create  new  profile,  or  if  exist  and  password  match  return  TRUE                ///  </summary>                              public  void  registerProfile(String  email,  String  password);                public  OperationCompletedDelegate  registerProfile_Completed;                ///  <summary>                ///  verify  your  password                ///  </summary>                public  void  loginProfile(String  email,  String  password);                public  OperationCompletedDelegate  loginProfile_Completed;                ///  <summary>                ///  remove  profile                ///  </summary>                public  void  dropProfile(String  email,  String  password);                public  OperationCompletedDelegate  dropProfile_Completed;                ///  <summary>                ///  return  data  for  profile,  if  password  is  empty  you  will  receive    informations                ///  </summary>                public  void  getProfileString(String  email,  String  password);                public  OperationCompletedDelegate  getProfileString_Completed;                ///  <summary>                ///  create  new  Application,  if  application  exists  does  do  nothing                ///  </summary>                public  void  registerApp(String  bundleId,  String  email,  String  password);                public  OperationCompletedDelegate  registerApp_Completed;64                
  • 65. Tiyla & WP7: Metodi (2/3)                ///  <summary>                ///  set  KeyPairs  App  info  to  db                ///  </summary>                public  void  setApp(String  bundleId,  String  email,  String  password,  Dictionary<string,  string>  data);                public  OperationCompletedDelegate  setApp_Completed;                ///  <summary>                ///  Crew  manage                ///  </summary>                public  void  linkCrew(String  emailCrew,  String  bundleId,  String  email,  String  password);                public  OperationCompletedDelegate  linkCrew_Completed;                                ///  <summary>                ///  Crew  manage                ///  </summary>                                public  void  unlinkCrew(String  emailCrew,  String  bundleId,  String  email,  String  password);                public  OperationCompletedDelegate  unlinkCrew_Completed;                ///  <summary>                ///  Translations  Update  Crew                ///  </summary>                              public  void  setTApp(String  bundleId,  String  email,  String  password,  String  language,  Dictionary<string,  string>  data);                public  OperationCompletedDelegate  setTApp_Completed;                ///  <summary>                ///  Translations  Update  Developer                ///  </summary>                              public  bool  setTRankApp(String  bundleId,  String  email,  String  password,  String  language,  Dictionary<string,  string>  data);                public  OperationCompletedDelegate  setTRankApp_Completed;                ///  <summary>                ///  Translations  Client                ///  </summary>                              public  void  getApp(String  bundleId,  String  email,  String  password,  Dictionary<string,  string>  data);                public  OperationCompletedDelegate  getApp_Completed;65
  • 66. Tiyla & WP7: Metodi (3/3) ///  <summary> ///  get  Translation  *  work  with  shots  * ///  </summary>               public  void  getTApp(String  bundleId,  String  email,  String  password,  String  language,  Dictionary<string,  string>  data); public  OperationCompletedDelegate  getTApp_Completed;                ///  <summary>                ///  get  Translation  *  work  with  shots  *                ///  </summary>                              public  void  getTApp(String  bundleId,  String  email,  String  password,  String  language,  Dictionary<string,  string>  data);                public  OperationCompletedDelegate  getTApp_Completed;66
  • 67. Tiyla & WP7: RAPI (1/3) • Per implementare alcune funzionalità sono state usate librerie open source pubblicate da CODEPLEX: • JSON.NET - http://json.codeplex.com/releases/view/64935 • Silverlight SharpZipLib - http://slsharpziplib.codeplex.com/releases/view/5056167
  • 68. Tiyla & WP7: RAPI (2/3)                private  void  registerProfile(String  email,  String  password,  string  method  =  "GET")                {                                                var  sender  =  new  TyilaUtils();                        sender.MyDownLoadCompletedEvent  +=  onDownloadCompleted;                        switch  (method)                        {                                case  "POST":                                        string  postData  =  JsonConvert.SerializeObject(new  command3pars()  {  func  =  "registerProfile",  email  =  email,         password  =  password  });                                        sender.executeCommandWithPost("http://tiyla.xiaprojects.com/core/echo.php",  postData);                                        break;                                case  "GET":                                default:                                        var  theUrlAndGetData  =  String.Format("func={0}&email={1}&password={2}",  "registerProfile",           HttpUtility.UrlEncode(email),  HttpUtility.UrlEncode(password));                                        theUrlAndGetData  =  "http://tiyla.xiaprojects.com/core/echo.php?"  +  theUrlAndGetData;                                        sender.executeCommandWithGet(theUrlAndGetData);                                        break;                        }                }                            private  void  onDownloadCompleted(TyilaUtils  sender,  String  content,  Exception  ex)                {                        sender.MyDownLoadCompletedEvent  -­‐=  onDownloadCompleted;                        if  (ex  !=  null)                        {                                MessageBox.Show(ex.Message);                        }                        else                        {                                MessageBox.Show(content);                        }                }68
  • 69. Tiyla & WP7: RAPI (3/3)                public  void  executeCommandWithGet(String  theUrl)                {                        var  client  =  new  WebClient();                        client.DownloadStringCompleted  +=  new                         DownloadStringCompletedEventHandler(client_DownloadStringCompleted);                        client.DownloadStringAsync(new  Uri(theUrl));                }                private  void  client_DownloadStringCompleted(object  sender,           DownloadStringCompletedEventArgs  e)                {                        if  (MyDownLoadCompletedEvent  !=  null)                                MyDownLoadCompletedEvent(this,  e.Result,  e.Error);                } 69
  • 70. Contact us xiaprojects.com  &  @xiateam Xyla.com  &  @Xylatweets70