Contoh Hasil : On Android Simulator · On Android Simulator . ... buka Eclipse anda dan buat...
Transcript of Contoh Hasil : On Android Simulator · On Android Simulator . ... buka Eclipse anda dan buat...
Contoh Hasil :
On Android Simulator
On Web browser (Chrome) (Webkits supports) :
Kali ini, saya akan menshare aplikasi pertama saya menggunakan sencha-touch library. Apa itu
sencha-touch? Sencha-touch merupakan salah satu javascript library keluarga dari sencha
(sencha.com). Library ini dikhususkan untuk browser versi mobile seperti android ataupun apple.
Lebih jelas mengenai sencha-touch, anda dapat langsung mengunjungi websitenya di
http://www.sencha.com/products/touch/. Apabila anda telah memahami pengertian sencha-touch,
saya akan mendemonstrasikan aplikasi pertama saya dengan library ini.
Persiapan Environment
1. Download Sencha-Touch library
http://www.sencha.com/products/touch/download/1.1.0/
2. Download CodeIgniter (versi 2.0.3)
Kali ini saya akan menggunakan CodeIgniter versi 2.0.3 sebagai framework phpnya. Tujuannya
adalah kita akan membuat aplikasi yang menggunakan konsep MVC (Model-View-Controller).
Pengertian detail mengenai MVC, anda dapat akses di wikipedia saja, berikut linknya
http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller. Intinya dari MVC ini
adalah terdapat 3 komponen utama yaitu view yang mengatur user interface dari aplikasi kita,
controller yang mengatur business logic pada aplikasi dan model yang mengatur CRUD (Create,
Read, Update, dan Delete) pada database aplikasi.
3. Download Abraham Twitter Library
Selain itu, saya juga akan menggunakan twitter library agar memudahkan kita dapat mengatur
authentication dan authorization menggunakan oauth, serta memudahkan dalam memperoleh data-
data yang telah disediakan oleh twitter-API. Twitter library yang digunakan adalah Abraham twitter
library, untuk mendownloadnya silakan kunjungi link berikut ini :
https://github.com/abraham/twitteroauth.
4. Download Eclipse-PHP atau Eclipse Javascript
Dalam implementasinya, saya akan menggunakan IDE Eclipse-PHP. Anda dapat mendownload
terlebih dahulu jika ingin. Jika tidak maka Anda dapat menggunakan text-editor biasa seperti
notepad++.
5. Download XAMPP (untuk windows) atau LAMPP (untuk linux)
Pada saat mengerjakan aplikasi ini, saya menggunakan XAMPP sebagai servernya (windows). Jadi,
agar Anda dapat mengikuti dengan baik tutorialnya, Anda dapat menggunakan XAMPP juga, tapi
tidak berarti anda tidak dapat mengembangan aplikasi di OS Linux. Anda tetap dapat menggunakan
LAMPP sebagai pengganti XAMPP.
http://www.apachefriends.org/en/xampp-windows.html
6. Buat Application yang terdaftar pada twitter.
Silakan kunjungi https://dev.twitter.com/ untuk mendaftar aplikasi twitter anda. Pilih Create An
App.
Lalu isikan nama aplikasi dan deskripsi anda bebas, tetapi untuk website, pastikan Anda mengisi :
http://127.0.0.1/Blog/CodeIgniter_2.0.3/index.php/loginController/login
Anda dapat menconfigurasi applikasi Anda terhadap privilleges tertentu, silakan pilih settings
kemudian ubah Application typenya (dalam tutorial ini, hanya diperlukan read privilleges).
Pada bagian detail, Anda akan mendapatkan consumer key, dan consumer secret key.
Pindahkan consumer key dan secret key Anda ke file twitter.php pada folder config (akan dijelaskan
kemudian).
Semua persiapan awal sudah selesai, sekarang saatnya implementasi.
Implementasi
Install XAMPP anda kemudian letakan folder CodeIgniter (hasil download) pada folder htdocs pada
XAMPP anda. Selain itu, letakan pula folder “sencha-touch” pada level yang sama denga folder code
igniter.
Lalu, pada folder htdocs\Blog\CodeIgniter_2.0.3\application\libraries, tambahkan twitteroauth yang
telah di download (abraham twitter oauth).
Kemudian tambahkan folder style pada folder CodeIgniter, CodeIgniter_2.0.3\style, seperti tampilan
berikut ini :
Lalu, buka Eclipse anda dan buat project baru.
2. Setelah berhasil maka tampilan struktur pada Eclipse akan seperti berikut ini :
3. Jalankan XAMPP Anda dan start Apache dan MySql service.
4. Setelah xampp dan project kita pada eclipse sudah siap, Kita akan mengatur configurasi terlebih
dahulu. Pertama-tama buka file autoload.php pada folder application/config.
Untuk variable $autoload[‘libraries’] tambahkan session dan database. Pada tampilan saya
menggunakan library curl sebagai tambahan. Tujuannya sih saat ini belum digunakan tapi mungkin
akan diperlukan kemudian.
$autoload['libraries'] = array('database','session', 'curl'); //pastikan Curl.php ada pada folder
libraries.
Kemudian $autoload[‘helper’] tambahkan url dan file.
$autoload['helper'] = array('url', 'file');
Lalu, pada autoload[‘config’] tambahkan twitter. Kita akan menggunakan file twitter.php yang akan
ditambahkan pada folder config.
$autoload['config'] = array('twitter'); //pastikan twitter.php ada pada folder config.
Twitter.php akan berisi consumer key, consumer secret key dan variable lain yang dinilai akan
diperlukan oleh semua controller, view ataupun model dan bersifat final dan static.
Isi dari twitter.php tersebut adalah sebagai berikut
<?php
$config['consumer_key'] = "RulUNSxYSaYTYD5s2N5ow"; //isi dengan consumer key Anda
$config['consumer_secret']= "rXRkzsiNcLcmerfnJzTZfaExtJbyyL6jhsz9dlGxDU"; //isi dengan
consumer secret key Anda.
Setelah itu, pada config.php, ubahlah base_url sebagai berikut
http://127.0.0.1/Blog/CodeIgniter_2.0.3/
Lalu, untuk database.php ubah sesuai gambar berikut : (kosongkan nama database)
Setelah itu, buka file routes.php, ubah default_controller dengan mainController.
Tahap konfigurasi sekarang selesai. Kita akan mulai membuat Controller, View, dan Model untuk
aplikasi kita.
Sekarang, Anda dapat membuka folder Controller, hapus controller default (welcome controller) dan
buat file baru yang bernama mainController.php, loginController.php, aboutController.php, dan
streamController.php.
Terlebih dahulu kita akan membuat loginController.php. loginController akan berisi fungsi-fungsi
yang berkaitan dengan oauth menggunakan abraham twitter API. Fungsi-fungsi yang ada adalah
sebagai berikut :
-- loginController.php --
<?php
class LoginController extends CI_Controller {
public function index(){
redirect("loginController/authenticate");
}
public function login($pin = NULL){
include_once APPPATH.'libraries/twitteroauth/twitteroauth.php';
$this->load->model("oauthModel", "oauth");
$requestToken = $this->oauth->getRequestToken();
$requestTokenSecret = $this->oauth->getRequestTokenSecret();
if($accessToken != "" || $accessTokenSecret != ""){
redirect("mainController/");
}
if(!isset($requestToken) || $requestToken == "" ||
!isset($requestTokenSecret) || $requestTokenSecret == ""){
redirect("loginController/authenticate");
}
$oauth = new TwitterOAuth($this->config->item('consumer_key'),
$this->config->item('consumer_secret'), $requestToken,
$requestTokenSecret);
$accessToken = $this->getAccessToken($oauth, $pin);
print_r($accessToken);
$this->oauth->setAccessToken($accessToken['oauth_token']);
$this->oauth-
>setAccessTokenSecret($accessToken['oauth_token_secret']);
if(isset($accessToken["user_id"])){
redirect("mainController/");
} else {
redirect("loginController/authenticate");
}
}
public function logout(){
$this->load->model("oauthModel", "oauth");
$this->oauth->deleteAllToken();
redirect("loginController/login");
}
public function authenticate(){
include_once APPPATH.'libraries/twitteroauth/twitteroauth.php';
$oauth = new TwitterOAuth($this->config->item('consumer_key'),
$this->config->item('consumer_secret'));
$oauthRequest = $this->getOauthToken($oauth);
$this->load->model("oauthModel", "oauth");
$this->oauth->deleteAllToken();
$this->oauth->setRequestToken($oauthRequest['oauth_token']);
$this->oauth-
>setRequestTokenSecret($oauthRequest['oauth_token_secret']);
$registerUrl = $this->authorize($oauth, $oauthRequest);
redirect($registerUrl);
}
public function getOauthToken($oauth){
$request = $oauth->getRequestToken();
return $request;
}
private function authorize($oauth, $request){
$registerURL = $oauth->getAuthorizeURL($request);
return $registerURL;
}
private function getAccessToken($oauth, $pin){
$request = $oauth->getAccessToken(NULL, $pin);
return $request;
}
}
-- aboutController.php --
<?php
class AboutController extends CI_Controller {
public function index(){
//defaults function
}
/**
* get overview page in HTML form
*/
public function overviewHTML(){
$this->load->model("userModel", "user");
$credentials = $this->user->verifyCredentials();
$this->load->view('about/overview', $credentials);
}
/**
* get sponsors page in HTML form
*/
public function sponsorsHTML(){
$this->load->view('about/sponsors');
}
/**
* get credits page in HTML form
*/
public function creditsHTML(){
$this->load->view('about/credits');
}
}
-- mainController.php –
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MainController extends CI_Controller {
public function index()
{
$this->load->model("oauthModel", "oauth");
$accessToken = $this->oauth->getAccessToken();
if(!isset($accessToken) || $accessToken == ""){
redirect("loginController/authenticate");
}
$data['javascript']['0'] = "apps.js";
$data['javascript']['1'] = "model/stream.js";
$data['javascript']['2'] = "stores/stream.js";
$data['javascript']['3'] = "view/stream.js";
$data['javascript']['4'] = "view/about.js";
$data['javascript']['5'] = "view/html.js";
$data['javascript']['6'] = "view/form.js";
$data['javascript']['7'] = "view/main.js";
$data['css']['0'] = "apps.scss";
$data['css']['1'] = "apps.css";
$data['title'] = "Mobile Web Application";
$this->load->view('main', $data);
}
}
-- streamController.php –
<?php
class StreamController extends CI_Controller {
/**
* default function
*/
public function index(){
}
public function getStreamData(){
$this->load->model("streamModel", "stream");
$streams = $this->stream->getHomeTimeline();
$streams = json_encode($streams);
echo $streams;
}
}
Setelah itu, kita beralih ke model dari aplikasi kita.
Kita akan membuat 3 buah model yaitu oauthModel.php, streamModel.php, dan
userModel.php. Berikut adalah implementasi dari ketiga model tersebut :
--oauthModel.php—
<?php
class OauthModel extends CI_Model {
function __construct()
{
parent::__construct();
}
function setRequestToken($requestToken){
$this->session->set_userdata("oauth_token", $requestToken);
}
function setRequestTokenSecret($requestTokenSecret){
$this->session->set_userdata("oauth_token_secret",
$requestTokenSecret);
}
function getRequestToken(){
return $this->session->userdata("oauth_token");
}
function getRequestTokenSecret(){
return $this->session->userdata("oauth_token_secret");
}
function deleteAllToken(){
$this->session->unset_userdata();
}
function setAccessToken($accessToken){
$this->session->set_userdata("oauth_access_token",
$accessToken);
}
function setAccessTokenSecret($accessTokenSecret){
$this->session->set_userdata("oauth_access_token_secret",
$accessTokenSecret);
}
function getAccessToken(){
return $this->session->userdata("oauth_access_token");
}
function getAccessTokenSecret(){
return $this->session->userdata("oauth_access_token_secret");
}
}
--streamModel.php—
<?php
class StreamModel extends CI_Model {
private $oauth;
function __construct()
{
parent::__construct();
include_once APPPATH.'libraries/twitteroauth/twitteroauth.php';
$this->oauth = new TwitterOAuth($this->config-
>item('consumer_key'), $this->config->item('consumer_secret'), $this-
>session->userdata("oauth_access_token"), $this->session-
>userdata("oauth_access_token_secret"));
}
/**
* Returns the 20 most recent statuses, including retweets if they
exist, posted by the authenticating user and the user's they follow.
* @url statuses/home_timeline
https://dev.twitter.com/docs/api/1/get/statuses/home_timeline
*/
function getHomeTimeline($params = NULL){
$content = $this->oauth->get('statuses/home_timeline',
$params);
return $content;
}
}
--userModel.php—
<?php
class UserModel extends CI_Model {
private $oauth;
function __construct()
{
parent::__construct();
include_once APPPATH.'libraries/twitteroauth/twitteroauth.php';
$this->oauth = new TwitterOAuth($this->config-
>item('consumer_key'), $this->config->item('consumer_secret'), $this-
>session->userdata("oauth_access_token"), $this->session-
>userdata("oauth_access_token_secret"));
}
function verifyCredentials($params = NULL){
$content = $this->oauth->get('account/verify_credentials',
$params);
return $content;
}
}
Untuk View (User Interface) kita akan menggunakan sencha-touch library.
Pertama-tama, pastikan bahwa folder sencha-touch anda telah berada pada
tempat semestinya.
Buatlah, folder about pada views dan berisi dengan 3 buah file yaitu
credits.php, overview.php, sponsors.php serta pada folder views buatlah
file main.php.
Pada credits.php buatlah file html sederhana :
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
Credits Page
</body>
</html>
Pada overview.php :
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
Overview Page
<div>
Your name : <?php echo $screen_name; ?>
</div>
<div>
Location : <?php echo $location; ?>
</div>
</body>
</html>
Sponsors.php
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
Sponsors Page
</body>
</html>
Sedangkan, inti dari ui kita adalah pada main.php :
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title><?php echo $title; ?></title>
<script src="<?php echo base_url(); ?>../sencha-touch/sencha-touch.js"
type="text/javascript"></script>
<link href="<?php echo base_url(); ?>../sencha-touch/resources/css/sencha-
touch.css" rel="stylesheet" type="text/css" />
<script>
var baseUrl = <?php echo json_encode(base_url()); ?>;
</script>
<?php
foreach ($javascript as $row ){
?>
<script src="<?php echo base_url(); ?>style/javascript/<?php
echo $row;?>" type="text/javascript"></script>
<?php
}
?>
<?php
foreach ($css as $row ){
?>
<link href="<?php echo base_url(); ?>style/css/<?php echo
$row;?>" rel="stylesheet" type="text/css" />
<?php
}
?>
</head>
<body></body>
</html>
Dapat dilihat bahwa, path dari javascript kita berarda pada
base_url/style/javscript sedangkan, untuk css berada pada
base_url/style/css. Untuk itu, segala file javascript dan css akan
diletakan pada folder style.
Jika anda telah melihat sencha-touch tutorial, Anda dapat dengan mudah
mengetahui file javascript mana yang menjadi inti dari aplikasi. Dalam Hal
ini, apps.js merupakan inti dari ui kita. Isi file ini adalah sebagai
berikut :
Application = new Ext.Application({
name : "Twitter Application",
launch: function(){
Application.ViewPort = new mainPanel({
id: "main",
aboutPages: [{
title: 'Overview',
card: {
xtype: 'htmlpage',
url: baseUrl + 'index.php/aboutController/overviewHTML'
}
}, {
title: 'Sponsors',
card: {
xtype: 'htmlpage',
url: baseUrl + 'index.php/aboutController/sponsorsHTML'
}
}, {
title: 'Credits',
card: {
xtype: 'htmlpage',
url: baseUrl + 'index.php/aboutController/creditsHTML'
}
}]
});
}
});
Perlu diperhatikan bahwa, variable baseUrl diinisialisasi dan
dideklarasikan pada main.php (views). Variable ini berisi base_url dari
aplikasi kita.
Awalnya, kita membuat aplikasi dengan perintah new Application({}); lalu
pada bagian launch function, kita mendefinisikan panel yaitu mainPanel.
Implementasi dari mainPanel dapat dilihat pada file view/main.js.
var mainPanel = Ext.extend(Ext.TabPanel, {
fullscreen: true,
//dockedItems: [formPanel],
tabBar: {
dock: 'top',
layout: { pack: 'center' }
},
initComponent: function() {
if (navigator.onLine) {
this.items = [{
xtype: 'streamPanel',
title: 'Stream'
}, {
title: 'About',
xtype: 'aboutPanel',
pages: this.aboutPages
}
];
} else {
this.on('render', function(){
this.el.mask('No internet connection.');
}, this);
}
mainPanel.superclass.initComponent.call(this);
}
});
Dapat dilihat bahwa mainPanel merupakan tabPanel yang kita redefine yang
dapat menerima parameter tambahan misalnya aboutPages. Pada bagian
aboutPanel. Di dalam panel ini, kita mendefinisikan 2 buah items yaitu
streamPanel, dan aboutPanel. Perhatikan xtype dari masing-masing panel ini.
Stream Panel :
var XTemplate = "<div class='item-wrap'> " +
"<img class='image' src='{profile_image_url}' />" +
"<div class='shouts'>{description}</div>" +
"</div>";
var streamList = Ext.extend(Ext.List, {
itemTpl : XTemplate,
ui: 'round',
plugins: [{
ptype: 'pullrefresh'
}],
listeners :{
itemtap : function(list, index, element, event){
//clicked event handler.
}
}
});
var streamListPanel = Ext.extend(Ext.Panel,{
layout: "fit",
docktedItems : {
xtype: "toolbar",
title: "Stream Data"
},
items: [new streamList({store: streamStore})]
});
Ext.reg('streamListPanel', streamListPanel);
var streamPanel = Ext.extend(Ext.Panel, {
fullscreen: true,
layout: "fit",
style: "background-color: red",
title: "Stream Page",
items: [{xtype: "streamListPanel"}]
});
Ext.reg('streamPanel', streamPanel);
Keterangan :
Stream Panel merupakan list dari twitter stream yang kita akan peroleh dari
streamController. Perhatian bahwa terdapat streamStore disini, streamStore
diperoleh dari file stores/stream.js.
var streamStore = new Ext.data.Store({
model : "Stream",
autoLoad: true,
proxy : {
type : "ajax",
url : baseUrl +
"index.php/streamController/getStreamData",
reader: {
type: "json",
root: ""
}
}
});
Keterangan :
Perhatikan url pada store diatas, store ini memperoleh data dari fungsi
getStreamData dari streamController.
Kita lihat implementasi streamController ini :
public function getStreamData(){
$this->load->model("streamModel", "stream");
$streams = $this->stream->getHomeTimeline();
$streams = json_encode($streams);
echo $streams;
}
Sedangkan,fungsi getHomeTimeline pada streamModel adalah sebagai berikut :
/**
* Returns the 20 most recent statuses, including retweets if they
exist, posted by the authenticating user and the user's they follow.
* @url statuses/home_timeline
https://dev.twitter.com/docs/api/1/get/statuses/home_timeline
*/
function getHomeTimeline($params = NULL){
$content = $this->oauth->get('statuses/home_timeline',
$params);
return $content;
}
Disini kita akan menggunakan REST API yang disediakan oleh twitter, Anda
dapat mengakses : https://dev.twitter.com/docs/api untuk lebih detail
terhadap REST yang disediakan oleh twitter. Disini saya menggunakan GET
statuses/home_timeline API untuk memperoleh stream twitter.
Kembali ke stream.js (stores), Anda dapat melihat bahwa model yang
dipergunakan adalah Stream. Model ini didefinisikan pada folder
model/stream.js :
Ext.regModel('Stream',{
fields: [
{name : 'profile_image_url', type: 'string',
mapping:'user.profile_image_url'}, //change mapping based on structure of
retrieved json
{name : 'description', type: 'string', mapping:'text'}
]
});
Ketika kita mendapat timeline (see API), kita mendapatkan struktur data
json (karena saya memilih json). Dari sekumpulan data json tersebut, saya
hanya menggunakan 2 buah data yaitu profile_image_url dan text (lihat
mapping variable).
Bagian stream telah selesai, sekarang kita akan mengimplementasikan bagian
about. Lihat view/about.js
var aboutPanel = Ext.extend(Ext.Panel, {
fullscreen: true,
layout: "card",
style: "background-color: blue",
initComponent: function(){
var aboutList = new Ext.List({
itemTpl: '<div class="page">{title}</div>',
ui: 'round',
store: new Ext.data.Store({
fields: ['name', 'card'],
data: this.pages
}),
plugins: [{
ptype: 'pullrefresh'
}],
listeners: {
selectionchange: {fn: this.onSelect, scope: this}
}
});
this.aboutMainPanel = new Ext.Panel({
layout: "fit",
items: aboutList
});
this.aboutMainPanel.on('activate', function(){
aboutList.getSelectionModel().deselectAll();
}, this);
this.items = [this.aboutMainPanel];
aboutPanel.superclass.initComponent.call(this);
},
onSelect: function(sel, records){
if (records[0] !== undefined) {
var newCard = Ext.apply({}, records[0].data.card, {
prevCard: this.aboutMainPanel,
title: records[0].data.title
});
this.setActiveItem(Ext.create(newCard), 'slide');
}
}
});
Ext.reg('aboutPanel', aboutPanel);
Di dalam about Panel, kita mendeklarasikan aboutList (lihat
aboutMainPanel). aboutList merupakan list dari this.pages (variable input).
Lihat bagian main.js ketika membuat aboutPanel, kita menpass variable
pages, bukan. Sekarang kembali perhatian aboutPages yang dipass pada file
apps.js
aboutPages: [{
title: 'Overview',
card: {
xtype: 'htmlpage',
url: baseUrl + 'index.php/aboutController/overviewHTML'
}
}, {
title: 'Sponsors',
card: {
xtype: 'htmlpage',
url: baseUrl + 'index.php/aboutController/sponsorsHTML'
}
}, {
title: 'Credits',
card: {
xtype: 'htmlpage',
url: baseUrl + 'index.php/aboutController/creditsHTML'
}
}]
Perhatikan xtype diatas, xtype tersebut berisi htmlpage bukan ? dan padahal
sencha-touch tidak mengenal tipe ini. Untuk itu, kita perlu meregister tipe
ini agar dikenali oleh sencha. Lihat html.js untuk lebih jelasnya :
var htmlPagePanel = Ext.extend(Ext.Panel, {
scroll: 'vertical',
styleHtmlContent: true,
initComponent: function(){
var toolbarBase = {
xtype: 'toolbar',
title: this.title
};
if (this.prevCard !== undefined) {
toolbarBase.items = {
ui: 'back',
text: "About",
scope: this,
handler: function(){
//setActiveitem for ancestor
this.ownerCt.setActiveItem(this.prevCard, { type:
'slide', reverse: true });
}
};
}
this.dockedItems = toolbarBase;
Ext.Ajax.request({
url: this.url,
success: function(rs){
this.update(rs.responseText);
},
scope: this
});
htmlPagePanel.superclass.initComponent.call(this);
}
});
Ext.reg('htmlpage', htmlPagePanel);
Hasil Akhir pada Chrome. :
Hasilnya via Android Simulator :
Untuk melihatnya pada android anda perlu melakukan perubahan pada hostnya
menjadi 10.0.2.2/
Hasilnya :