terça-feira, 22 de outubro de 2013

Curso de Criação de Apps Móveis com PhoneGap e jQuery Mobile - Licão 2


Bom, você já conhece o básico do desenvolvimento Mobile, inclusive já criou uma aplicação Android. Agora, é hora de ver o PhoneGap em ação.

Baixe os arquivos correspondentes a esta aula. A pasta completa está em: 




O trabalho "Criação de aplicações Móveis com PhoneGap e jQuery Mobile" de Cleuton Sampaio de Melo Jr está licenciado com uma Licença Creative Commons - Atribuição-CompartilhaIgual 4.0 Internacional. Isso inclui: Textos, páginas, gráficos e código-fonte.


Aplicações multiplataforma

Um grande problema para qualquer desenvolvedor de aplicações móveis é a Ubiquidade da informação, ou seja, a possibilidade do usuário querer acessar as informações a partir de qualquer dispositivo.


Assim sendo, os desenvolvedores precisam criar múltiplas versões de suas aplicações. Porém, como vimos na sessão passada, o desenvolvimento móvel de cada plataforma tem características muito peculiares, que impedem a portabilidade.


Android
iOS
Windows Phone
Java / Dalvik / ART
Objective C / Swift (iOS 8)
C#
Android API
Cocoa Touch
Windows Phone 8 SDK


Alternativas

Existem vários frameworks e pacotes de software para tentar resolver o problema da portabilidade, por exemplo:





Permite criar aplicações usando o C#, que rodam em Android, iOS e Windows Phone.



Permite criar aplicações multiplataforma (Android e iOS) utilizando a linguagem Lua e XML.


Titanium


O Titanium utiliza um engine Javascript e permite criar aplicações para: Android, iOS e Windows Phone.

Frameworks de Webview

Quando o iPhone foi lançado, Steve Jobs queria que os desenvolvedores criassem apenas aplicações usando HTML 5, que sempre foi considerada a plataforma ideal para desenvolvimento móvel.


Quase todas as plataformas móveis possuem um “Widget” para exibição de páginas HTML, também conhecido como “Webview”.



→ Abra o eclipse e importe o projeto “DemoWebView”.

File / Import / General / Existing Projects into Workspace -> archive file


Este projeto utiliza uma “Webview” para exibir o código HTML que está dentro da pasta “assets/www”. E utiliza uma interface Javascript:
myWebView.addJavascriptInterface(new TCBInterface(this), "Android");
myWebView.loadUrl("file:///android_asset/www/index.html");



A classe “TCBInterface” serve como um “plugin”, para que o código Javascript possa invocar o compartilhamento do aparelho (enviar como: SMS, Email etc). Ela tem o método “share”:


public void share(String assunto, String texto) {
  Resources res = contexto.getResources();
  Intent sendIntent =
      new Intent(android.content.Intent.ACTION_SEND);
  sendIntent.putExtra(Intent.EXTRA_TEXT,
      texto);
  sendIntent.putExtra(Intent.EXTRA_SUBJECT,
      assunto);
  sendIntent.setType("text/plain");
  contexto.startActivity(
  Intent.createChooser(sendIntent,
  res.getString(R.string.compartilhar)));
}


Esse método é invocado a partir do código Javascript, que está no arquivo “index.html”:


function compartilhar() {
  var assunto = "Querido(a) chefe!";
  var texto = document.getElementById("output").innerText;
  Android.share(assunto,texto);
}
...
<input type="button" value="Compartilhar" onclick="compartilhar()" />


A própria Webview faz uma “ponte” entre a classe TCBInterface e o Javascript.


Então, por que precisamos do PhoneGap?


O iOS tem algo parecido, porém a implementação é completamente diferente, pois teríamos que usar um UIWebView Delegate. Até mesmo o código Javascript teria que ser modificado, o que invalida a portabilidade.


O PhoneGap ajuda a quebrar essa barreira porque implementa uma interface única, com runtimes para vários tipos de plataforma.


Podemos desenvolver uma aplicação HTML 5 Javascript em uma plataforma (por exemplo: Android) e depois portá-la para outra (iOS), bastando copiar os arquivos HTML e Javascript.



PhoneGap

O PhoneGap é um framework de desenvolvimento de aplicações tipo Webview, livre e open source, que roda em múltiplas plataformas móveis. Ele permite criar aplicações que rodam em:

  • Amazon Fire OS;
  • Android;
  • BlackBerry 10;
  • Firefox OS;
  • iOS;
  • Ubuntu;
  • Windows Phone;
  • Windows 8;
  • Tizen;
http://phonegap.com/


Apache Cordova vs PhoneGap


Quando a Adobe comprou a empresa que criou o PhoneGap (Nitobi), o código-fonte foi doado à Apache Foundation, que o disponibilizou como Apache Cordova. O PhoneGap é uma distribuição do Apache Cordova.


Arquitetura de uma aplicação PhoneGap



A aplicação consiste em páginas HTML, recursos (CSS, imagens etc) e código Javascript. Quando ela necessita de algum recurso do aparelho, invoca um Plugin PhoneGap ou um Plugin de terceiros, utilizando a API nativa do PhoneGap.


Eis a matriz dos recursos que o PhoneGap expõe para cada plataforma móvel:


Componentes de uma aplicação PhoneGap

As aplicações Apache Cordova (base do PhoneGap), possuem um arquivo de configuração comum: “config.xml”, que fornece informação sobre a aplicação e seus parâmetros de configuração, por exemplo, como a app responde às mudanças de orientação do aparelho.



A aplicação em si é implementada como uma página Web, chamada “index.html”, por default, que faz referências a vários outros componentes: CSS, JavaScript, imagens, arquivos de mídia etc. A aplicação executa como uma WebView dentro da aplicação nativa que a abriga, a qual você pode distribuir para uma AppStore.

A WebView Cordova fornece a interface de usuário da aplicação. Em algumas plataformas, é possível misturar a WebView Cordova com outros elementos.



Existe uma interface de plugins que permite ao Cordova acessar componentes nativos. Isto permite invocarmos código nativo a partir do Javascript. Você pode usar os plugins nativos do PhoneGap, ou criados por terceiros, ou ainda pode criar seus próprios plugins.


Test drive com o PhoneGap


Vamos criar uma aplicação PhoneGap para ver como funciona:

  1. Abra uma janela terminal;
  2. Crie uma pasta para abrigar seus projetos PhoneGap e vá para ela;
  3. Digite: “phonegap create primeira”;
  4. Digite: “cd primeira”;
  5. Digite: “phonegap run android”;
Podem acontecer os seguintes problemas:
  1. Você não criou um AVD (instância de Emulador). Leia o “guia-install-curso.pdf” e crie um AVD;
  2. Não foi instalado a plataforma Android no PhoneGap. Digite: “cordova platform add android”;
  3. Não foi instalada a plataforma Android 19. Neste caso, leia o “guia-install-curso-pdf”, abra o SDK Manager e instale a API 19.

Se tudo der certo, você verá um emulador como o da figura seguinte.



A estrutura da aplicação é assim:



Dentro da pasta “platforms/android”, vemos a estrutura do Projeto Android:


Vamos importar para o Eclipse:

  1. Abra o menu “File / import” e Selecione “Android / Existing Android code into workspace”;
  2. Selecione a pasta do seu projeto;
  3. Marque os dois projetos (“HelloWorld” e “HelloWorld-CordovaLib”);
  4. Pode dar erro no projeto principal, pois está faltando a Lib, então, abra “properties/android” e adicione o projeto “HelloWorld-CordovaLib” como uma library;


Observação importante




A partir do PhoneGap/Cordova 3, sempre crie o projeto usando a linha de comando, e depois importe para o Eclipse. Não tente criar o projeto no Eclipse.


Usando os comandos Cordova

Você também pode usar os comandos do Cordova (dentro do PhoneGap) para criar um projeto:
  • $ cordova create hello com.example.hello HelloWorld
  • $ cd hello
  • $ cordova platform add android
  • $ cordova build

Analisando uma aplicação PhoneGap

  1. Crie um projeto PhoneGap: “cordova create <diretório> <pacote> <nome do projeto>”:
    • cordova create DesculpasFuradas com.teste.desculpas DesculpasFuradas
  1. Vá para o diretório “DesculpasFuradas” e rode: “cordova platform add android”;
  2. Importe o plugin “WebIntent” para podermos compartilhar o “caô” gerado:
    • cordova plugin add https://github.com/Initsogar/cordova-webintent.git

  1. Importe o projeto para o Eclipse:
    • De início, você não verá a pasta “assets/www” e nem o arquivo “config.xml”. Abra o menu “properties/resource” e depois “resource filters” e delete os filtros de exclusão;
  1. Abra o zip “desculpas.zip” e copie os arquivos para as pastas apropriadas:
    • index.html para “assets/www”;
    • logo.png para “assets/www/img”;
    • index.js para “assests/www/js”;


Execute o projeto;



Você poderá compartilhar a desculpa furada gerada. Para usar e-mail ou SMS, rode em seu celular ou então rode usando a Google API.

Essa aplicação utiliza um plugin chamado “Webintent”. Vamos analisar como ele é configurado:


1) Para começar, instalamos o plugin em nosso projeto:
2) O PhoneGap registra o plugin no arquivo “res/xml/config.xml”:
<feature name="WebIntent">
<param name="android-package" value="com.borismus.webintent.WebIntent" />
</feature>
3) Um pacote com uma classe é incluído dentro da pasta “src”:
package com.borismus.webintent;

import java.util.HashMap;
import java.util.Map;


import org.apache.cordova.CordovaActivity;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Intent;
import android.net.Uri;
import android.text.Html;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaResourceApi;
import org.apache.cordova.PluginResult;

/**
* WebIntent is a PhoneGap plugin that bridges Android intents and web
* applications:
*
* 1. web apps can spawn intents that call native Android applications. 2.
* (after setting up correct intent filters for PhoneGap applications), Android
* intents can be handled by PhoneGap web applications.
*
* @author boris@borismus.com
*
*/
public class WebIntent extends CordovaPlugin {

private CallbackContext onNewIntentCallbackContext = null;

//public boolean execute(String action, JSONArray args, String callbackId) {
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
try {


4) Usamos o plugin dentro do Javascript:



function compartilhar() {
var extras = {};
extras["android.intent.extra.SUBJECT"] = "Querido(a) chefe!";
extras["android.intent.extra.TEXT"] =
document.getElementById("output").innerHTML;
window.plugins.webintent.startActivity({
action: "android.intent.action.SEND",
type: 'text/plain',
extras: extras
},
function() {},
function() {
alert('Erro ao compartilhar');
}
);
}

OOPS, você não conhece bem Javascript!

KEEP CALM AND READ “javascript-cookbook.pdf”, dentro da sessão 2.

Recursos do dispositivo

Armazenamento de dados



O PhoneGap Storage usa a implementação Web SQL, do HTML 5, para criar bancos de dados locais.


Vamos ver uma aplicação exemplo que cria uma tabela e retorna os dados:



Descompacte e importe os projetos “database” e “database_cordovalib”, que estão na pasta “database”, da sessão 2.



Abrindo o banco:


receivedEvent: function(id) {
if (id == 'deviceready') {
var db = window.openDatabase("test", "1.0", "Test DB", 1000000);



Criando uma transação e inserindo registros:


db.transaction(function(tx) {
  tx.executeSql('DROP TABLE IF EXISTS DEMO');
  tx.executeSql('CREATE TABLE IF NOT EXISTS DEMO (id unique,
    data)');
  tx.executeSql('INSERT INTO DEMO (id, data) VALUES (1,
    "First row")');
  tx.executeSql('INSERT INTO DEMO (id, data) VALUES (2,
    "Second row")');
  },
  function(erro) {
    alert("Erro: "+erro.code);
  },
  function() {
    alert("successo!");
});


Lendo os registros incluídos e mostrando em uma DIV:

function() {
alert("successo!");
var saida = document.getElementById('saida');
saida.innerHTML = "<ul>";
db.transaction(function(tx) {
  tx.executeSql('SELECT * FROM DEMO', [],
   function(tx, results) {
     var len = results.rows.length;
     for (var i=0; i<len; i++) {
       saida.innerHTML += "<li>"
       + results.rows.item(i).id
       + ", "
       + results.rows.item(i).data
       + "</li>";
     }
    saida.innerHTML += "</ul>";
  },
  function(erro) {
    alert("erro query: " + erro.code);
  });
 },
  function(erro){
    alert("erro: " + erro.code);
  });
});

Notas sobre uso real de banco de dados:

Em uma aplicação REAL, não vamos querer apagar e recriar as tabelas a cada execução. O comando SQL “DROP TABLE IF EXISTS DEMO” sempre apagará a tabela, cada vez que a aplicação for executada.


O Comando SQL “CREATE TABLE IF NOT EXISTS” vai fazer exatamente isso: Criar a tabela, caso ela não exista. É assim que você deve iniciar uma aplicação de Banco de dados. Os dois comandos INSERT também estão incorretos e só servem para demonstração.

Banco SQLite

O PhoneGap não suporta mais nativamente o banco de dados SQLite, que é padrão em várias plataformas móveis.


Ele utiliza o Web SQL, que é um padrão do HTML 5, suportado até pelo navegador do Android 2.3, conforme pode ser atestado pelo site “http://html5test.com”: 


O uso do SQLite é desaconselhado por apresentar diversos problemas e não ser suportado nativamente. Pode apresentar problemas entre as várias plataformas (Android, iOS e Windows Phone).

Se realmente for necessário o uso do SQLite, há duas opções:
  1. Criar um plugin e um DAO nativo, fazendo todo o acesso ao Banco de Dados na plataforma nativa (Java para Android, Objective C para iOS); ou
  2. Utilizar um plugin de terceiros para uso do SQLite dentro do PhoneGap;


Vamos fazer um pequeno teste com ele. Para usar o plugin, você deve instalá-lo logo após criar a aplicação. Esta aplicação já está pronta, dentro da sessão 2: databasesqlite.zip (e databasesqlite-cordovalip.zip). Se você for criar uma aplicação para usar SQLite do zero, então devem rodar os comandos como os abaixo:

  • cordova create DatabaseSqlite com.teste.databasesqlite DatabaseSqlite
  • cordova platform add android
  • cordova plugin add https://github.com/millerjames01/Cordova-SQLitePlugin.git

Eis o código “index.js” modificado para acessar um banco SQLite:

// Update DOM on a Received Event
receivedEvent: function(id) {
if (id == 'deviceready') {
var db = window.sqlitePlugin.openDatabase({name: "testesqlite.db"})

Você pode abrir um banco SQLite pré-existente com o mesmo comando.

Eventos

O PhoneGap permite colocarmos código em resposta a vários eventos que podem acontecer com o aparelho. Nós já vimos o “device ready”:


var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
},


Ele acontece quando a API do Cordova (PhoneGap) está totalmente carregada. Não tente fazer nada ANTES deste evento acontecer!

Uma dica: Procure sempre usar a estrutura do “index.js” criada pelo PhoneGap! Use sempre o “index.js” e o objeto “app” que ele criou, pois assim, evitará problemas.

Usamos a propriedade “bindEvents”, do objeto “app” do PhoneGap, que é um ponteiro para um “callback”, que deverá associar os tratamentos aos eventos. Usamos o método “addEventListener” para associar os diversos eventos às nossas rotinas, que são implementadas como métodos do objeto “app”.


Existem vários outros, que devem ser acionados dentro do “callback” do evento “device ready” (Só estou mostrando os eventos que acontecem pelo menos para Android):
  • pause: Quando a aplicação for movida para “background” (devido a outra aplicação assumir o controle, como uma chamada, por exemplo). Aqui, você pode salvar recursos para evitar o consumo de bateria;
  • resume: Quando a aplição é trazida do “background” para o primeiro plano. Se você fechou alguma conexão de banco de dados no “pause”, é o momento de reabrir;
  • backbutton: Quando o botão “voltar” (aparelhos Android) foi acionado. Se você quiser substituir o comportamento padrão, adicione o Event Listener dentro do tratamento do evento “device ready”. Esse evento NÃO EXISTE NO iOS!!!
  • menubutton: Quando o botão “menu” for acionado. Esse evento NÃO EXISTE NO iOS!!!
  • searchbutton: Quando o botão de pesquisa for acionado. Esse evento NÃO EXISTE NO iOS!!!

Configurações

O arquivo “config.xml” pode ser utilizado para configurar a sua aplicação. No Android, ele é copiado para dentro de “res/xml”. Procure modificar nos dois lugares (dentro da aplicação e dentro de “res/xml”) para manter sincronia. Eis algumas configurações interessantes:


<?xml version='1.0' encoding='utf-8'?>
<widget id="com.teste.databasesqlite" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>DatabaseSqlite</name>
<description>
A sample Apache Cordova application that responds to the deviceready event.
</description>
<author email="dev@cordova.apache.org" href="http://cordova.io">
Apache Cordova Team
</author>
<content src="index.html" />
<access origin="*" />

</widget>
  • widget: Identifica a aplicação pelo seu nome de pacote, incluindo a versão;
  • name: Nome da aplicação, que aparecerá na tela de ícones do dispositivo, e na AppStore;
  • content: Qual é a página inicial da aplicação (não mude isso!);
  • access: Whitelist, ou lista de domínios externos que a aplicação pode acessar. O default é “*”, o que não é muito seguro. Você pode especificar todas as URLs que a aplicação poderá acessar, tornando sua aplicação mais segura (em produção):
    • <access origin="*.obomprogramador.com" />


Preferências globais:
  • Fullscreen: Some com a barra de status, ocupando a tela toda:
    • <preference name="Fullscreen" value="true" />
  • Orientation: Define a orientação da aplicação (“portrait” ou “landscape”);

Depuração de Apps

Se você está acostumado ao conforto de depurar pelo Eclipse, esqueça... Não dá para depurar apps PhoneGap / Cordova usando os mecanismos tradicionais. Existem algumas iniciativas, mas ainda não funcionam bem.

Primeiramente, vamos mostrar uma técnica usando o Ripple, que é multiplataforma. Depois, vamos mostrar uma técnica usando o Chrome, que serve para plataforma Android.

Porém, como é uma aplicação HTML 5 / Javascript, é possível depurar usando um plugin de depuração em Browser, como o Chrome, que já vem com isso instalado. No firefox costuma dar problema.

Instruções

1) Instale o Chrome, da Google;

2) Instale a extensão “Ripple”: http://emulate.phonegap.com/:




3) Prepare a app para ser depurada:
  1. Copie tudo que está dentro de “assets/www” para a pasta “www” da raiz do projeto;
  2. Copie o arquivo “Config.xml”, que está dentro de “res/xml”, para a pasta “www”.

4) Abra o Google Chrome e configure a extensão “Ripple”:
  1. Navegue para “chrome://extensions”;
  2. Habilite as duas checkboxes:
5) Abra a página “index.html” da aplicação (a página que fica na pasta “www”, dentro da raiz do projeto Android);

6) Clique no botão “Ripple” e selecione “Enable”;

7) Na primeira vez, você terá que selecionar a plataforma (Cordova / PhoneGap 1.x);


8) Abra o depurador de scripts do Chrome: “Ferramentas / Ferramentas do Desenvolvedor”, coloque “Breakpoints” e regarregue a página:




Você poderá rodar, colocar “breakpoints”, mudar eventos, ver conteúdo de variáveis etc:


Limitações

  • Não funciona com todos os plugins do Cordova / PhoneGap;
  • Não emula a plataforma Android, mas a API básica do PhoneGap;
  • Para acessar Webservices, há o problema CORS (Cross-Origin Resource Sharing). Uma solução é usar “datatype: jsonp”, se puder. Outra, é acrescentar o HEADER “Access-Control-Allow-Origin: *” na resposta do Webservice. Uma terceira opção é simular o acesso ao Webservice;

Depuração usando o Chrome remote debugging

Um grande problema para aplicações PhoneGap / Cordova é a depuração de scripts. Embora seja possível utilizar bibliotecas que emulam o PhoneGap, como o Ripple, geralmente os problemas são muito grandes e impedem o correto funcionamento, especialmente quando consumimos WebServices.

Chrome Remote WebView Debugging

O Android, a partir da versão 4.4.x, permite a depuração remota de WebViews, o que atende perfeitamente à necessidade dos desenvolvedores.

Isto pode ser feito rodando a aplicação em um dispositivo Android real (com Android 4.4.x) ou em um Emulador, com plataforma Android 4.4.x.

Assim, podemos depurar nossa aplicação e depois exportar os arquivos fonte para outras plataformas, como: iOS, Windows Phone etc.

Preparando sua aplicação

Para começar, você deve alterar o código do evento “onLoad()”, da Activity principal do seu projeto PhoneGap / Cordova, para permitir a depuração remota da WebView. Acrescente este código:

public class StockQuote extends CordovaActivity 
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        super.init();
        // Set by <content src="index.html" /> in config.xml
        super.loadUrl(Config.getStartUrl());
        //super.loadUrl("file:///android_asset/www/index.html");
        
        //Debug: 
        
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WebView.setWebContentsDebuggingEnabled(true);
        }
    }
}

Repare que estamos testando se a versão do projeto é KitKat (4.4.x). Mesmo que você pretenda desenvolver para plataformas mais antigas (Ice Cream Sandwich, Ginger Bread etc) você TEM que alterar o arquivo AndroidManifest.xml e colocar a versão mínima para 19:

<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="0.0.1" android:windowSoftInputMode="adjustPan" package="com.exemplo.stockquote" xmlns:android="http://schemas.android.com/apk/res/android">
    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
    <uses-permission android:name="android.permission.INTERNET" />
    <application android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:name="StockQuote" android:theme="@android:style/Theme.Black.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-sdk android:minSdkVersion="19"
  android:targetSdkVersion="19" />
</manifest>

Abrindo o Chrome

Você tem que ter a última versão do Google Chrome instalada em sua máquina. Eu testei com MS Windows, Mac OSX e também com Ubuntu 14.04, e tudo funcionou. Abra o Chrome e digite: “chrome://inspect/#devices”. Uma tela com os dispositivos Android conectados ou emulados vai aparecer:



Se você não quiser ver os dispositivos reais, desligue o checkbox “Discover USB devices”.

Muito importante: Tanto o Emulador como o seu dispositivo devem estar com a “Depuração USB” habilitada. Isto é feito dentro do menu “Configurações”.

Depurando a aplicação

Execute sua aplicação Android (PhoneGap / Cordova) da maneira tradicional (Run As / Android Application). Escolha o dispositivo Android ou a instância do Emulador apropriada. Você notará que vai aparecer uma lista com as WebViews disponíveis no dispositivo (ou no Emulador), dentro da página do Chrome: 



Selecione a instância da WebView que você quer depurar e clique no link “inspect”. Vai abrir uma nova Janela do Chrome, com o depurador de scripts aberto:




Funciona da mesma maneira que o depurador de scripts normais do Chrome. Você pode selecionar qual arquivo-fonte deseja depurar (sources) e colocar “breakpoints”, navegar passo a passo ou pular chamadas.
Se quiser recarregar a página, basta digitar F5 na janela “Developer tools” (no Mac use CONTROL + R).
Veja o exemplo abaixo, que invoca um WebService. Colocamos um breakpoint no callback de sucesso do Ajax:




Você pode ver conteúdo de variáveis, usando a janela “Watch expressions”, ou então simplesmente passando o mouse por cima, como nesse exemplo:





E pode controlar a execução usando os botões de depuração:


 Da esquerda para a direita:
  • Run: Continua a execução até o próximo “breakpoint”;
  • Step: Depura a próxima instrução, sem entrar dentro de subrotinas;
  • Step into: Depura a próxima instrução, entrando dentro de subrotinas;
  • Step out: Sai da subrotina corrente;
  • Desativar breakpoints.

PhoneGap no iOS

O PhoneGap funciona muito bem no iOS e praticamente não há necessidade de alterar sua aplicação para que seja executada em dispositivos da Apple.

Para desenvolver aplicações iOS, é necessário ter:
  • Um computador da Apple (arquitetura Intel) com sistema operacional Mac OS X, versão mínima: Lion (10.7);
  • Um dispositivo móvel da Apple: iPhone, iPad ou iPod Touch. É possível desenvolver sem ter o dispositivo, usando apenas o Simulador, porém, para alguns recursos será necessário ter o dispositivo real;
  • Um certificado iOS Developer Program. Uma conta de iOS Developer Program (US$ 99,00 por ano) e um Provisioning Profile serão necessários para executar a aplicação em um dispositivo real.
Depois de instalar o PhoneGap (“sudo npm install -g phonegap”) e o Cordova (“sudo npm install -g cordova”), você terá todas as ferramentas para desenvolver sua aplicação. Na verdade, você pode ter um só projeto PhoneGap, com versões para várias plataformas, bastando, para isto, executar:
  • cordova platform add <plataforma>;

Bem, para criar um projeto, abra um Terminal e siga os passos:

1) cordova create teste1 com.teste.teste1 teste1
- Aguarde o Download da plataforma básica (www)

2) cordova platform add iOS
- Aguarde o Download da plataforma iOS


3) Abra o projeto no Xcode, dando duplo-clique no arquivo:
  • <pasta do projeto>/platforms/ios/xxxxx.xcodeproj

Selecione menu ˜Product / Run” e aguarde o simulador aparecer.


Uma vez que tenha instalado o Cordova, você também poderá criar projetos PhoneGap dentro do Xcode:



Você pode executar o projeto na linha de comando, mas eu recomendo que o faça sempre dentro do Xcode. Uma vez que o projeto tenha sido importado, você poderá executá-lo selecionando o menu: “Product / Run”:



Na figura anterior, vemos o projeto dentro do Xcode, com o simulador aberto, executando a aplicação.




A estrutura é simples. Abra o arquivo “projeto-ios.zip” dentro da sessão 2, e veja a estrutura do projeto:
O arquivo “config.xml” fica dentro da pasta com o nome do projeto (nesse caso: “teste1”), que, por sua vez, fica dentro de “platforms/ios”:


Mas dá para ser totalmente compatível com o Android?



Bem, a maioria das coisas sim. Vamos pegar o exercício que fizemos para a plataforma Android, e executar no iOS. Para isto, substitua os arquivos “index.html” e “js/index.js”, dentro do “platforms/ios/www”.


Aí está! O projeto roda sem alterações (e usa Banco de Dados!)

Exercício


KEEP CALM AND MÃO NA MASSA”


Vocês vão fazer um exercício de banco de dados. Vão criar uma app que permita incluir registros, como a do exemplo:


Ao entrar, ela exibe a lista dos registros existentes, possibilitando incluir novos registros. Ela possui duas caixas de texto e um botão para isso.



Ao ser acionado o botão, o novo registro deve ser incluído na tabela, e a lista de saída deve ser atualizada.


Como incluir registros no banco, evitando “SQL Injection”:


var id = document.getElementById("id");
var data = document.getElementById("data");
db.transaction(function(tx) {
tx.executeSql('INSERT INTO DEMO (id, data) VALUES (?, ?)',
[id.value, data.value]);
},
function(erro) {
alert("Erro ao incluir: " + erro.code);
},
function() {
atualizarDiv();
}
);


A solução está nos dois projetos: “exercicio.zip” e “exercicio-cordovalib.zip”.


VOLTAR AO MENU DO CURSO