반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

암흑의 이명박근혜 10년...

2012. 12. 31. 14:52 | Posted by 솔웅


반응형

이명박 5년 행복하셨습니까?


이명박근혜의 남은 5년 행복 하실 것 같습니까?


이명박이 망쳐놓은 우리 사회 구석구석을 이제 끝내고 앞으로 바로 잡기를 바랐지만..

그만 이명박근혜 10년이 계속 되게 생겼습니다.


대선 이후 완전 한국 소식을 끊었다가..

오늘 오랜만에 이상호 기자의 발뉴스를 들었습니다.


이상호 기자도 MBC 에서 해고 될 거 같다고 하네요.




저렇게 호전적이고 기회주의적이고 권위적이고 음모적이고 폭력적인 청산되어야할 과거 악당들의 자손들이 남북한과 일본을 끌고 나가게 됐습니다.


저기서 가운데에 있는 사진만이라도 상식적인 생각을 하는 사람이 되서 동북아의 미래를 이끌어 나가길 바랬지만...

그런 일은 일어나지 않았습니다.


이명박 5년 행복하셨습니까?



이명박근혜정권은 인정할 수 없는 썩은 과거 세력들의 분탕질일 뿐입니다.


어쨌든 그대로 흘러갈 남은 5년이기에 이런 분탕질을 최소화하도록 감시하는 역할만이 그나마 우리가 할 수 있는 일일것 같네요.


이명박근혜가 가장 망쳐버린 부문중 한 부문에 방송언론이 있을 텐데요.


시민사회에서 국민방송국을 만드려고 하는것 같네요.


관련 기사가 한겨레신문에 떳던데요... (여기)


꼭 국민방송국이 설립되서 이명박근혜의 분탕질을 최대한 막기를 바랍니다.


국민방송국이 설립 될 떄까지도 이명박근혜의 분탕질 저지는 계속 되야 하니까.

그 동안 뉴스타파, 시사인, 발뉴스, 오마이뉴스, 한겨레신문을 계속 보고 응원해야겠네요..


저는 이명박근혜의 5년을 잘 봐왔습니다. 그래서 이명박근혜의 남은 5년도 어떤 희망을 기대하지 않습니다.

희망은 우리 스스로 만들어 가야겠습니다.



반응형


반응형
Posted on . Written by


코로나 SDK 개발자들에게는 크리스마스가 일찍 왔습니다. 지난주 저희 팀들은 daily builds 에 여러 기능을 추가하느라고 하주 바쁜 시가늘 보냈습니다. 여러분들에게 소개해 드릴 새로운 기능들이 아주 많이 있습니다. 아래는 그 중 일부분입니다.


  • Build 987 — Inneractive ads SDK updated to 1.1.5
  • Build 990 — iOS 5/6 native Twitter access via native.showPopup()
  • Build 990 — new native.canShowPopup() API call to test for email, sms and twitter capability
  • Build 991 — Facebook SDK updated to 3.1.1
  • Build 992 — iAds support added
  • Build 993 — (drum roll please)… Android Push Notifications!


몇몇 개발자분들은 이런 새로운 기능들을 deploy 하고 계실 겁니다. 그리고 코로나 SDK의 new Plugin system인  Project Gluon 가 이런 작업들을 빨리 할 수 있도록 도와준 것에 대해 감사를 전합니다.


오늘은 Android Push Notifications에 대해 얘기를 해 보죠. 만약 애플에 push notification 을 deploy 해 보셨다면 아마 그 일은 certificates, keys, sandboxing, provisioning profiles, 3rd-party vendor setup 등등의 복잡한 것들을 처리하느라고 거의 로켓 과학하고 MBA 학위를 따는 것 만큼이나 힘들었을 겁니다. iOS 개발자 계정에 이러한 셋업을 다하고 나면 이제 여러분은 모바일 개발자로서 가장 어려운 부분을 해결한 겁니다.다행히도 여러분이 일단 애플쪽에 이런 setup 을 해 놓으셨다면 코로나의 push notification을 다루는 것은 아주 간단합니다.


이제 안드로이드 쪽을 살펴 보면 셋업 하는데 그렇게 많이 나쁘지는 않습니다. push notification 과 관련해 가장 큰 장애물은 Android OS 가 push notification을 관리하지 않는다는 겁니다. push 하는 것은 애플리케이션이 책임지는 겁니다. Corona Labs 는 이 안드로이드도 애플처럼 in-app implementation 을 만들기 위해 아주 많은 노력을 기울였습니다.


Four Basic Steps


안드로이드에서 push notification 을 얻는 방법은 다음 4 개의 기본 과정을 거칩니다.


  1. Setup for Google
  2. Setup for 3rd-party services (optional)
  3. Respond to registration events from your app
  4. Respond to push notifications as they arrive

1. Setup for Google



STEP 1:  브라우저에서  https://code.google.com/apis/console 로 가세요. 그리고 Services를 클릭하세요. Google Cloud Messaging for Android entry를 찾고 그것을 on 상태로 설정하세요. 아마 "Terms of Services" 에 동의 하셔야 할 겁니다.  거기서 제시하는 대로 다 동의 하세요.



STEP 2:   API Access를 클릭하세요. 그리고 Create new Server key를 클릭하세요. 아마 긴 화면이 나올 겁니다. IP address 쪽은 작성하실 필요가 없습니다. push notification을 send 할 때 사용하셔야 하니까 API Key 를 copy 하세요. (Corona Cloud service에서 했던 대로죠.)

NOTE:  Corona SDK sample app에는 push notification을 send 하는 기능이 있습니다. 여러분도 샘플로 테스트를 하시려면 이 API Key 를 사용하셔도 됩니다.



STEP 3:  API 콘솔의 Overview tab으로 가세요. 그리고 Project Number를 copy 하세요. Project ID는 무시하세요. 여러분의 Project Number는 또한 URL 이기도 합니다. 이 번호는 나중에 push notification 을 받을 때 필요하실 겁니다.



STEP 4: 이 부분은 그렇게 필요한 부분은 아닌데요. 일단 Google Play 개발자 콘솔에 방문하고 여러분이 업로드한 앱을 찾고 메타 데이터를 수정하고 Enable Google Cloud Messaging Stats entry를 찾으실 수 있습니다. 여기서 Project IDSender ID로 추가하세요. 이렇게 하면 여러분 앱의 GCM usage에 대한 stats 를 볼 수 있도록 해 줍니다.


2. Setup for 3rd-Party services (optional)


이 부분에서는 그다지 언급할 부분은 많이 없을 것 같습니다. Corona Cloud Services (Game Minion)에서부터 Urban Airship까지 많은 서비스 중 하나를 이용하실 수도 있고 또는  standard REST API call 을 사용해서 메세지를 보내는 여러분들만의 서비스를 사용하고 싶을 수도 있을 테니까요. 어느 경우에든 API Server Key는 있어야 됩니다.  GCM Server Key같은 걸 요구할 겁니다. 여러분이 제공해야 될 것은 이게 전부 입니다.


3. Respond to registration events from your app


iOS에 대한 push notification에 대한 코로나 Labs의  블로그 글을 올린것이 한 일년 전 쯤의 일입니다. 애플의 push notification을 셋업하는 일이 어려운 일의 대부분이었습니다. 대부분의 step 들이 다 거기에 대한 방법이었죠. step 4,5 번이 코로나와 관련된 부분이었습니다. 이 부분은 안드로이드에 대해서도 똑 같이 적용 됩니다.

push notification을 받기 위해서는 3개의 파일을 수정하셔야 합니다. 첫번째는 config.lua입니다.

아래 부분을 추가해 넣으시면 됩니다.


notification =
{
google =
{
projectNumber = "yourprojectnumberhere",
},
},

프로젝트 번호는 전부 다 숫자라도 따옴표 안에 있어야 합니다. 최근에 블로그에 올린 Ultimate config.lua 를 사용하실거라면  이 블록을 두번 복사해 넣으시면 됩니다. 하나는 tall 안드로이드 디바이스 부분 하나 하고 다른 디바이스 부분하고요.      


elseif ( display.pixelHeight / display.pixelWidth > 1.72 ) then
 
application =
{
content =
{
width = 320,
height = 570,
scale = "letterBox",
xAlign = "center",
yAlign = "center",
imageSuffix =
{
["@2x"] = 1.5,
["@4x"] = 3.0,
},
},
notification =
{
google = { projectNumber = "yourprojectnumberhere", },
},
}
else
application =
{
content =
{
width = 320,
height = 512,
scale = "letterBox",
xAlign = "center",
yAlign = "center",
imageSuffix =
{
["@2x"] = 1.5,
["@4x"] = 3.0,
},
},
notification =
{
google = { projectNumber = "yourprojectnumberhere", },
},
}
end

iOS device 부분에는 이 블럭을 넣으실 필요는 없습니다. 하지만 iOS 에 대한 push notification code를 이 블럭에 넣으셔야 된다는 점 기억해 두세요.

이제 두번째 수정하셔야 될 파일은 build.settings file입니다.

settings = {} table 안에 넣으셔야 될 겁니다. 그 안에 iPhone과 orientation 혹은 다른 블럭들이 있을 텐데요. 아래와 같이 안드로이드 부분을 세팅하시면 됩니다.


android =
{
permissions =
{
{ name = ".permission.C2D_MESSAGE", protectionLevel = "signature" },
},
usesPermissions =
{
"android.permission.INTERNET",
"android.permission.GET_ACCOUNTS",
"android.permission.RECEIVE_BOOT_COMPLETED",
"com.google.android.c2dm.permission.RECEIVE",
".permission.C2D_MESSAGE",
},
},



이제 마지막으로 main.lua 파일 입니다. 추가해야 될 코드가 있는데요. 이미 iOS push notification을 위해 이 코드를 넣으셨다면 이미 좋은 참고 자료를 확보한 셈입니다. 이 부분이 처음이라면 여러분이 추가하셔야 될 부분은 세부분으로 나눌 수 있습니다.   


첫번째로는 notification events 에 대해 respond 하기 위한 handler function을 셋업하셔야 합니다. 핸들링해야 할 이벤트가 두가지가 있는데요. (Registration and the Push Event itself) 둘 다 같은 handler function으로 관리하시면 됩니다. 이 함수를 사용하시기 위해 Runtime Listener 도 셋업 하셔야 됩니다.

suspended 나 stopped 상태에서 push notification이 여러분의 앱을 launches 시킬 어떤 특정 화면으로 가도록 프로그래밍을 하셔야 되는 걸 잊지 마세요. 


“remoteRegistration” event를 get 하면 애플이나 구글에 완전히 register 된 겁니다. 그리고 event.token variable에 여러분의 token 이 들어있는 상태가 됩니다. 이 값을 다른 서비스들과 함께 여러분의 디바이스에 register 시킬때 사용하실 수 있습니다. 이 remoteRegistration event 는 다른 서비스와 함께 register 시킬때나 나중에 token을 저장할 때 아주 유용합니다. (만약 여러분이 push sending service와 함께 로그인 과정이 끝나고 난 후 register 해야 할 떄 말이죠.)


local function onNotification(event)
 
if event.type == "remoteRegistration" then
-- This device has just been registered for push notifications.
-- Store the Registration ID that was assigned to this application by Google or Apple.
myRegistrationId = event.token
 
-- Display a message indicating that registration was successful.
local message = "This app has successfully registered for push notifications."
native.showAlert("Information", message, { "OK" })
-- Print the registration event to the log.
print("### --- Registration Event ---")
--
-- Here is where you put code to register with your push notification service
--
else
-- A push notification has just been received. Print it to the log.
print("### --- Notification Event ---")
-- here is where you respond to a push notification that comes in while the
-- app is running.
end
 
end


Now, to make this function do something useful, you need to hook it up to Corona’s event system:


Runtime:addEventListener( "notification", onNotification )


마지막으로 여러분의 앱이 running 상태가 아니라면 (i.e. it’s stopped/suspended, a push notification comes in for the app, and you tap on it) OS가 여러분의 앱을 launch 시킬 겁니다. 그 다음에 아무런 행동을 하지 않으면 유저가 앱 아이콘을 두드렸을 때 실행 되듯이 앱이 실행 될 겁니다. 하지만 그럴 경우 push notification의 content 내용에 따라 다른 특정 화면으로 앱을 시작하고 싶을 때는 어떻게 해야 할 까요? 예를 들어서 뉴스 관련 앱을 만들었고 새로운 속보가 push 됐다면 바로 그 story 로 화면이 시작되길 원하실 겁니다.


이럴 경우 launchArgs를 사용합니다. push notification은 custom data를 포함하고 있습니다.

앱이 시작될 때 이 launchArgs를 체크하세요. 그리고 필요하면 앱 실행부분을 코딩하셔서 원하는 기능을 구현하시면 됩니다. 이 코드는 대개 main.lua의 윗 부분에 있게 됩니다.


local launchArgs = ...
if launchArgs then
-- do something with the data in the launchArgs table
end


In Summary


이 튜토리얼의 내용은 여기까지 입니다. 이 push notification은 오직 iOS 디바이스와 Google Play 에 인스톨 된 앱과  안드로이드 디바이스 에서만 사용할 수 있다는 것을 유의하세요. Kindle Fire나 Barnes & Noble Nook 디바이스들에서는 이 기능을 제공하지 않습니다.

앞으로도 계속 튜토리얼들이 추가 될 겁니다. 관심있게 지켜봐 주시기 바랍니다.

Corona Labs 는 여러분들이 모두 연말 연시를 잘 보내시고 이 선물이 도움이 많이 되셨기를 바랍니다.

반응형


반응형

Posted on . Written by



2012년 모바일의 세계는 완전 날아다녔습니다. 코로나도 거기에 올라 탔었구요. 하드웨어 쪽에서는 정말 매끄럽고 날렵한 태블릿들과 수를 헤아일수 없는 전화기를 포함해서 많은 device 들이 release 됐었죠. 또한 iOS6 와 안드로이드 4.x 같은 메이저 OS 들의 업그레이드가 다양한 기능들과 함께 소개 됐었죠. 지난 1년 동안 Corona Labs는 이렇게 빠르게 변화하는 환경에 맞춰 계속 새로운 개발을 해 왔습니다.



우리는 2012년을 더 큰 그리고 더 강력한 팀으로 마감하게 됐습니다. 거기다가 저희들은 계속 성장해 나가고 있습니다. 저희가 개발자분들의 community 에 전달하고 싶은 말씀은 저희들은 아주 strong 하고 Corona 커뮤니티가 세계적으로 성장할 수 있도록 환상적인 명예 대사들과 함께 꾸준히 노력을 하고 있다는 겁니다. 기술적인 부분에서는 주요 milestone들을 기록할 수 있었습니다. 8월에 Corona Enterprise를 선보여 코로나 개발자 분들이 native code도 같이 사용해서 개발할 수 있도록 했습니다. 그리고 Project Gluon과 함께 코로나의 새로운 plugin system을 소개해 드리기 위해 열심히 개발하고 있습니다. 거기에다가 12월에는 end-to-end development platform인 Corona Cloud 를 2013년도 초에 실시하겠다고 발표 했었습니다.



또한 코로나 커뮤니티도 지속적으로 성장해 나가고 있습니다 2012년도에 코로나 개발자 수는 11만명에서 20만명으로 거의 두배가 뛰었습니다. 이 사실을 접하고 저희들은 놀라기도 했고 또 겸손해 지기도 했습니다. 여러분들의 도움으로 저희들은 같이 활기차고 자랑스러운 커뮤니티를 만들어갈 수 있었기 때문입니다. 인디 개발자에서부터 큰 규모의 스튜디오까지 코로나는 그분들의 열정을 받고 성장할 수 있었습니다. 2013년에는 훨씬 신나는 일이 생길거라고 약속 드립니다. 여러분들이 코로나로 만들어 낼 훌륭한 제품들이 정말 기대 되네요.



위대한 기회의 해인 2013년을 cheer 합니다.





반응형

GPS 와 구글 맵 사용하기

2012. 12. 29. 10:18 | Posted by 솔웅


반응형
GPS and Google Maps



최신 브라우저에는 location-based 기능들이 다 있습니다. 전화기나 태블릿의 GPS 를 사용하는 기능이죠. 이것은 HTML5 의 기본 기능입니다. 그러니까 jQuery Mobile 과는 별도의 기능인거죠. 하지만 jQuery Mobile 과 함께 사용하면 아주 유용하죠. 이전 글의 데이터베이스 같이요.


geolocation 기능을 사용해서 Google Map  기능을 이용할 수도 있습니다. Google은 이를 위한 API 를 제공하고 있습니다. 개발자들은 자바스크립트를 이용해서 지구상의 어떤 곳이든 지도로 display 할 수 있습니다.


It is these two aspects we study in this chapter, in conjunction with jQuery Mobile.

이 두가지 기능에 대해 jQuery Mobile 에서는 어떻게 다루는지 오늘 다뤄 보겠습니다.


Using GPS with jQuery Mobile


GPS는 navigator.geolocation object를 통해서 구현 가능합니다. 이 object는 getCurrentPosition (ok, error) method 를 제공합니다.


  • ok (position) is a callback function called when the GPS position could be calculated. The position parameter is an object with a coords property defined by {latitude, longitude, heading, speed, altitude} containing the GPS position. This parameter is required otherwise the GPS position can not be recovered.

  • error () is a callback function called only if GPS position has not been found. This parameter is optional.


현재의 GPS 위치를 표시하기 위해 이 메소드를 사용하시면 됩니다. (예를 들어 현재의 위도와 경도를 표시하실 수 있습니다.)


Display current GPS coordinates


<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <span> Latitude : </span> <span id=lat></span> <br />

    <span> Longitude : </span> <span id=lng></span> <br />

  </div>

</div>


</body>

</html>


<script>


navigator.geolocation.getCurrentPosition (function (pos)

{

  var lat = pos.coords.latitude;

  var lng = pos.coords.longitude;

  $("#lat").text (lat);

  $("#lng").text (lng);

});


</script>



tistory574_01.html







Integrating Google Maps in our application


구글 맵은 Google에서 제공하는 구글 맵 API 를 통해서 구현 가능합니다. 이 API에 접근하려면 HTML 페이지에 자바스크립트를 include 시키시면 됩니다.


Inclusion of the JavaScript file of Google Maps


<script src=http://maps.googleapis.com/maps/api/js?sensor=true></script>



이전 프로그램을 변형시켜서 GPS 위치에 의해 파악된 위치를 지도에 표시하는 새로운 화면을 display 시키겠습니다. 첫번째 화면을 우리가 정하는 GPS 코드를 entering 하도록 약간 변형시키겠습니다.


View the map of the position provided by GPS


<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

  <script src=http://maps.googleapis.com/maps/api/js?sensor=true></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <span> Latitude : </span> <input type=text id=lat />

    <span> Longitude : </span> <input type=text id=lng />

    <a data-role=button id=btn>Display map</a>

  </div>

</div>


<div data-role=page id=win2 data-add-back-btn=true>

  <div data-role=header>

    <h1>Window 2</h1>

  </div>


  <div data-role=content>

  </div>

</div>


</body>

</html>


<script>


navigator.geolocation.getCurrentPosition (function (pos)

{

  var lat = pos.coords.latitude;

  var lng = pos.coords.longitude;

  $("#lat").val (lat);

  $("#lng").val (lng);

});


$("#btn").bind ("click", function (event)

{

  var lat = $("#lat").val ();

  var lng = $("#lng").val ();

  var latlng = new google.maps.LatLng (lat, lng);

  var options = { 

    zoom : 15, 

    center : latlng, 

    mapTypeId : google.maps.MapTypeId.ROADMAP 

  };

  var $content = $("#win2 div:jqmData(role=content)");

  $content.height (screen.height - 50);

  var map = new google.maps.Map ($content[0], options);

  $.mobile.changePage ($("#win2"));

  

  new google.maps.Marker ( 

  

    map : map, 

    animation : google.maps.Animation.DROP,

    position : latlng  

  });  

});


</script>


tistory574_02.html


텍스트 필드에 위도 경도 좌표를 넣으면 그 값을 받아올 겁니다. (디폴트로는 GPS 에서 얻은 값이 표시 됩니다. 파라미터에서 google.maps.Map object 를 생성하면 해당 위치의 지도가 display 될 겁니다. 지도를 표시할 <div> element 의 높이를 지정하는 부분을 잘 봐 두세요. (여기서는 두번째 화면의 content 입니다.)


여기에 해당 위치에 Marker 를 표시하기 위해 google.maps.Marker object를 생성했습니다. 이것은 옵션이지만 지도에서 해당 위치를 찾는데 아주 유용한 기능입니다.



반응형


반응형

What's at risk for Rhode Island if the 'fiscal cliff' is not averted?


December 27, 2012 3:57 pm
By Philip Marcelo


PROVIDENCE, R.I. -- With the U.S. House set to reconvene Sunday on a possible "fiscal cliff" deal, millions of dollars in federal aid driving government services and significant parts of the Rhode Island economy hang in the balance, according to recent national studies.


PROVIDENCE, R.I. 미하원 입법위원회는 일요일 "fiscal cliff" 협의를 위해 재소집합니다. 이에 따라 연방정부가 지원하는 수십만 달러의 지원금을 주정부에 지원하고 주정부는 이를 경제 균형 발전에 사용할 수 있습니다.


Nearly $19 million of the total $254 million or so in federal funding the state receives annually for social service programs for the poor, children and seniors, as well as education and job training are at risk for automatic cuts, if a deal is not reached, according to a July study commissioned by the office of U.S. Sen. Tom Harkin, chairman of the Senate Committee on Health, Education, Labor and Pensions. 


연방정부의 전체 2천5백4십만불의 지원금 중 로드 아일랜드 주정부는 백9십만불 가량을 받을 예정이며 이는 저소득 계층과 어린이 그리고 노인계층을 위한 social service 프로그램에 사용될 예정입니다. 또한 교육과 job training 부문에도 일부 사용될 예정이지만 예산이 부족할 경우 지원이 중단될 수도 있다고 건강,교육,노동,연금 상원의원회 의장 Tom Harkin 상원의원은 말했습니다.


The state can also expect significant reductions in federal spending on defense procurement, salaries and wages, which account for 2.8 percent of Rhode Island's gross domestic product, according to a November report by the Pew Center on States.

Those come on top of the income tax hikes all taxpayers can expect to pay in the new year, as well as the expiration of federal benefits for some on unemployment.

또한 주정부는 로드 아일랜드의 총 생산중 2.8 퍼센트를 차지하는 조달과 임금, 급여 등에서도 연방정부 지원 규모 축소로 예산을 삭감 해야 되는 상황에 있습니다. 이러한 조치들은 새해 세금을 내야할 납세자들의 소득세 상승과 관련돼 있습니다. 또한 일부 실업자들에 대한 연방 정부 지원금도 새해부터는 중단 될 예정입니다.





이 기사는 지역신문인 Providence Journal 의 인터넷판 기사인데요.

아마 인터넷 판에는 기사의 일부분만 싣는 것 같습니다.

어쨌든 번역하기가 좀 어렵네요.


미국 연방정부의 fiscal cliff 때문에 로드 아일랜드 주에도 지원금도 삭감되고 중단되는 지원도 있고 해서 여러모로 어려워 지는군요.


저소득자나 실업자에 대한 지원도 줄어들 수 있고 무엇보다 소득세가 높아져서 제가 내야 할 세금도 더 늘어나겠네요.


Fiscal Cliff 를 막기 위해서는 공화당의 협조가 필요한데 공화당은 전제조건으로 오바마의 의료보험법 개정 관련 예산 삭감과 국방예산 삭감 취소 그리고 부자 감세를 요구하고 있습니다.


한마디로 공화당은 일반 국민들에게 돌아가는 혜택을 줄이고 무기 생산업자들 그리고 부자들의 소득을 늘리는 정책을 펴라는 요구네요.


어쩌면 이렇게 이명박근혜랑 똑 같은지.... 나쁜 놈들......







반응형


반응형

Databases on the client side


이번에 다루는 챕터는 jQuery Mobile 에서 제공하는 기능은 아닙니다. HTML5에서 제공하는 기능을 jQuery Mobile 이 활용하는 겁니다. HTML5는 요즘 브라우저에서 대부분 지원하고 있습니다. 특해 대부분의 스마트 폰이나 tablet 들의 브라우저에서도 지원하구 있습니다.


이 기능은 jQuery Mobile 의 기능과 같이 사용되면 아주 유용합니다. 원격 서버가 아닌 local database 에 저장된 데이터에 접근하기 위해 jQuery Mobile 과 함께 사용하는 자바스크립트 프로그램으로 그 기능을 구현할 수 있습니다.


HTML5 offers two types of data storage on the client:


  •  SQL로 만들어진 브라우저 내의 데이터베이스. 저장할 데이터가 많을 경우 이 저장방법을 사용할 수 있습니다.

  • localStorage and sessionStorage objects를 통한 저장공간. string 으로 만들어진 정보를 저장합니다. 데이터베이스보다 제한사항들이 적습니다. 그리고 구현하기가 간단합니다. 적은 양의 정보를 저장하는데 사용합니다.


Permanent storage and session storage


permanent storage 와 session storage의 다른 점은 저장기간에 있습니다.

permanent storage에서는 정보를 유저가 지울 때까지 저장합니다. 즉 그 application이 close 되도 phone 을 껐다가 켜도 그 데이터는 유지가 됩니다.


session storage는 정보가 그 세션의 context 내에서만 저장됩니다. 즉 세션에 저장된 정보는 우리가 만든 사이트의 모든 페이지에서 접근할 수 있지만 그 기간은 application 이 run 하고 있을 때 만입니다. 이 application 이 닫히거나 다른데로 넘어가 버리면 즉 세션이 끝나버리면 그 정보는 없어집니다.


이 두 기능을 구현하기 위해서는 다음 두개의 JavaScript 객체들을 사용하시면 됩니다. : localStorage and sessionStorage:


  • localStorage allows permanent storage,

  • sessionStorage allows storage in the session.


예를 들어 성과 이름을 저장하려면 아래와 같이 하시면 됩니다.


Permanent storage


localStorage.lname = "Sarrion";

localStorage.fname = "Eric";


Session storage


sessionStorage.lname = "Sarrion";

sessionStorage.fname = "Eric";


Using a database


위에서 본 Permanent storage 와 temporary storage 는 SQL 을 사용하는 데이터베이스에서 제공하는 많은 기능들을 제공하지는 않습니다.

이런 데이터베이스를 이용하려면 HTML5 에서 제공하는 SQL 데이터베이스를 자바스크립트를 사용해서 활용하시면 됩니다.


Creating the database



첫번째로 데이터베이스에 대한 access 를 생성합니다. 이게 첫번째로 실행될 경우 그 데이터베이스는 빈 DB 가 되겠죠.


Create access to the database


var db = openDatabase ("Test", "1.0", "Test", 65535);



위 소스에서는 string size 를 65,535 bytes 로 지정했습니다.


Using the database


일단 데이터베이스가 생성됐으면 이제 사용하시기만 하면 됩니다.


  • Creating tables,

  • Inserting data into tables,

  • Retrieving data from the tables,

  • Deleting data,

  • Eventually deleting tables.


데이터 관리하는 방법은 간단합니다. db object 가 recover 됐다면 이제 SQL 명령문을 사용하시면 됩니다.


Using the database


var db = openDatabase ("Test", "1.0", "Test", 65535);

db.transaction (function (transaction) 

{

  var sql = SQL query;

  transaction.executeSql (sql, [parameters] / undefined, 

  function ()

  

    // JavaScript code to execute if the query was successful

    // ...

  }, 

  function ()

  

    // JavaScript code to execute if the query failed

    // ...

  } );

});



parameters들은 배열 형태이고 SQL query 안에서 "?" 로 replace 됩니다. 이 파라미터들은 "?" 가 없으면 사용할 필요가 없습니다.


이어지는 두 함수들옵션인데요 둘 중 하나가 indicated 되지 않았다면 undefined replace 되어야 합니다. 첫번째 함수는 트랜잭션이 성공했을 때 실행되고 두번째 함수는 실패 했을 때 실행됩니다.


두번째 함수의 return 은 중요한 의미가 있죠. request 가 실패했다는 의미이니까요. 이렇게 request 가 실패 했을 때 그 트랜잭션의 request 들을 rollback 하는 부분을 구현해야 합니다. 실패 했을 때 제대로 rollback 하기 위해 해당 함수의 마지막에 true return 하면 됩니다. 그렇지 않다면 성공했다고 간주하게 됩니다.


Example of using a database


customers table로 데이터베이스를 관리할 겁니다. 그러려면 테이블을 생성하고 그 안에 내용을 넣고 지우고 보여주고 하는 기능들을 구현해야죠.


Managing a database of clients locally


<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <a href=# data-role=button id=create> Create customers table </a>

    <a href=# data-role=button id=remove> Delete customers table </a>

    <span> Last name </span>

    <input type=text id=lname>

    <span> First name </span>

    <input type=text id=fname>

    <a href=# data-role=button id=insert> Insert the customer </a>

    <a href=# data-role=button id=list> List customers </a>

  </div>

</div>


<div data-role=page id=win2 data-add-back-btn=true>

  <div data-role=header>

    <h1>List of customers</h1>

  </div>


  <div data-role=content>

  </div>

</div>


</body>

</html>


<script>


var db = openDatabase ("Test", "1.0", "Test", 65535);


$("#create").bind ("click", function (event)

{

  db.transaction (function (transaction) 

  {

    var sql = "CREATE TABLE customers " +

        " (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +

        "lname VARCHAR(100) NOT NULL, " + 

        "fname VARCHAR(100) NOT NULL)"

    transaction.executeSql (sql, undefined, function ()

    

      alert ("Table created");

    }, error);

  });

});


$("#remove").bind ("click", function (event)

{

  if (!confirm ("Delete table?", "")) return;;

  db.transaction (function (transaction) 

  {

    var sql = "DROP TABLE customers";

    transaction.executeSql (sql, undefined, ok, error);

  });

});


$("#insert").bind ("click", function (event)

{

  var lname = $("#lname").val ();

  var fname = $("#fname").val ();

  

  db.transaction (function (transaction) 

  {

    var sql = "INSERT INTO customers (lname, fname) VALUES (?, ?)";

    transaction.executeSql (sql, [lname, fname], function ()

    

      alert ("Customer inserted");

    }, error);

  });

});


$("#list").bind ("click", function (event)

{

  db.transaction (function (transaction) 

  {

    var sql = "SELECT * FROM customers";

    transaction.executeSql (sql, undefined, 

    function (transaction, result)

    {

      var html = "<ul>";

      if (result.rows.length)

      {

        for (var i = 0; i < result.rows.length; i++) 

        {

          var row = result.rows.item (i);

          var lname = row.lname;

          var fname = row.fname;

          html += "<li>" + lname + "&nbsp;" + fname + "</li>";

        }

      }

      else

      {

        html += "<li> No customer </li>";

      }

      

      html += "</ul>";

      

      $("#win2").unbind ().bind ("pagebeforeshow", function ()

      {

        var $content = $("#win2 div:jqmData(role=content)");

        $content.html (html);

        var $ul = $content.find ("ul");

        $ul.listview ();

      });

      

      $.mobile.changePage ($("#win2"));

      

    }, error);

  });

});


function ok ()

{

}


function error (transaction, err) 

{

  alert ("DB error : " + err.message);

  return false;

}


</script>


tistory573_01.html


쿼리가 데이터베이스에서 기록들을 return 할 경우 자바스크립트 함수는 ResultSet object 에 해당하는 result parameter를 성공적으로 수행했을 때 실행됩니다. 이 쿼리에 의해 생성된 자료들을 담고 있는 rows property 가 생기게 됩니다.


Access to the records returned by a SELECT


for (var i = 0; i < result.rows.length; i++) 

{

  var row = result.rows.item (i);

  var lname = row.lname;

  var fname = row.fname;

  html += "<li>" + lname + "&nbsp;" + fname + "</li>";

}


이 프로그램에서 흥미로운 부분은 리스트를 display 하는 부분 입니다. 화면의 content 로 insert 하기 위해 <ul> list HTML 코드를 사용했습니다. 리스트를 listview () method를 사용해서 listview component 로 변환하는 것은 화면에 들어갈 리스트가 이미 생성돼 있을 때에만 가능합니다.
pagebeforeshow event 가 그 당시 화면이 생성돼 있는지 여부를 체크할 수 있도록 해 줍니다.


unbind () method가 bind () method 이 전에 사용된 점을 유념하세요. bind () method를 성공적으로 call 하면 perform 해야할 일들이 쌓이게 됩니다. (만약 리스트가 여러번 display 되야 하는 경우에요.) unbind ()
method를 call 하면 이전에 add 됐던 모든 이벤트 핸들러들을 remove 합니다.  그러니까 마지막에 우리가 bind ()로 추가한 것만 남게 되죠.


이 소스를 실행시키면 아래와 같은 화면을 보실 수가 있을 겁니다.





customers table 생성의 다른 action 들은 이 테이블이 아직 생성되지 않았을 경우 에러 메세지를 보여줄 겁니다.  일단 생성되면 다른 action들을 취할 수 있습니다. 두개의 클라이언트를 생성하고 list 해 보죠. 해당 버튼을 잘 눌러서요.



Improving the program (continued)


위의 프로그램을 조금 더 개선 시키겠습니다. 리스트에서 한개의 client 를 remove 할 수 있도록요. 이것을 하려면 리스트 아이템에 swipe movement (right)을 감지할 수 있도록 해야 할 겁니다. 오른쪽으로 문지르면 그 아이템이 리스트에서 지워질겁니다. 더불어서 데이터베이스에서도 그 정보가 지워질 거구요.


아래에 이를 위한 구문이 있습니다.


Allow the removal of an item in the list


$("#list").bind ("click", function (event)

{

  db.transaction (function (transaction) 

  {

    var sql = "SELECT * FROM customers";

    transaction.executeSql (sql, undefined, 

    function (transaction, result)

    {

      var html = "<ul>";

      if (result.rows.length)

      {

        for (var i = 0; i < result.rows.length; i++) 

        {

          var row = result.rows.item (i);

          var lname = row.lname;

          var fname = row.fname;

          var id = row.id;

          html += "<li data-icon=false " + "id=" + id + ">";

          html +=   "<a href=#>";

          html +=      lname + "&nbsp;" + fname; 

          html +=   "</a>"; 

          html += "</li>";

        }

      }

      else

      {

        html += "<li> No customer </li>";

      }

      

      html += "</ul>";

      

      $("#win2").unbind ().bind ("pagebeforeshow", function ()

      {

        var $content = $("#win2 div:jqmData(role=content)");

        $content.html (html);

        var $ul = $content.find ("ul");

        $ul.listview ();

        

        $("li").bind ("swiperight", function (event)

        {

          var id = $(this).attr ("id");

          if (!id) return;

          

          $(this).remove ();

          

          db.transaction (function (transaction) 

          {

            var sql = "DELETE FROM customers WHERE id=?";

            transaction.executeSql (sql, [id], function ()

            

              alert ("Customer deleted");

            }, error);

          });

        });        

      });

      

      $.mobile.changePage ($("#win2"));

      

    }, error);

  });

});


<li> list item 은 리스트 아이템에 <a> element 가 삽입되면서 높이가 더 커질 겁니다. 리스트 아이템의 id attribute 는 데이터베이스 안에 있는 client 의 identifier 입니다. 이것으로 해당 client 가 어느 리스트 아이템과 연관된 건지 알수 있습니다. 그래서 해당 리스트 아이템을 지울 때 데이터베이스의 해당 데이터도 지울 수 있는 거죠.


그리고 이제 각 리스트 아이템별로 swiperight event handler 를 연결 시킵니다. 이 이벤트가 발생하면 display 된 해당 리스트 아이템이 remove 될 겁니다. 그리고 나서 데이터베이스의 해당 id 를 가지고 있는 데이터가 지워질 겁니다.



반응형

툴바 만드는 예제들

2012. 12. 28. 05:33 | Posted by 솔웅


반응형
Examples of manipulation of toolbars



Manage a tab system in a navigation bar


navigation bar의 버튼을 클릭할 때마다 다른 content 를 보여주려고 합니다. 물론 page 이동 없이 각 버튼이 선택될 따마다 해당 page 에서 content 만 바꿔서 display 할 겁니다.


Manage tabs in the navigation bar


<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 

  

<body> 


<div data-role=page id=home>

  <div data-role=header data-position=fixed>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>

  </div>

  

  <div data-role=footer data-position=fixed>

    <div data-role=navbar>

      <ul>

        <li id=menu1><a href=#>Menu 1</a></li>

        <li id=menu2><a href=#>Menu 2</a></li>

        <li id=menu3><a href=#>Menu 3</a></li>

      </ul>

    </div>

  </div>

</div>


</body>

</html>


<script>


$("li").bind ("vclick", function (event)

{

  var id = this.id;

  if (id == "menu1") $("#home div:jqmData(role=content)")

                        .html ("<p> Content menu 1 </p>");

  else if (id == "menu2") $("#home div:jqmData(role=content)")

                        .html ("<p> Content menu 2 </p>");

  else if (id == "menu3") $("#home div:jqmData(role=content)")

                        .html ("<p> Content menu 3 </p>");

});


</script>

tistory570_01.html



navigation bar에 있는 버튼을 클릭할 때마다 화면의 contents 가 바뀝니다. 그리고 처음 화면이 뜰 때는 아무 버튼도 selected 돼 있지 않은 상태죠. 화면이 뜬 후 버튼을 클릭할 때마다 content를 바꾸는 로직이 실행 됩니다.


Simulate a click on the first button


$("div:jqmData(role=navbar)").bind ("navbarcreate", function (event)

{

  $("li#menu1 a.ui-btn").trigger ("vclick");

});


이 코드는 navigation bar 가 생성될 때  (navbarcreate event) 실행됩니다. 그 이전에는 ui-btn class의 <a> link는 존재하지가 않습니다. 왜냐하면 아직 jQuery Mobile 에 의해서 HTML 코드가 변환되지 않았으니까요.


Manage the content of the tabs by Ajax


HTML 에 있는 자바스크립트 코드로 tab들의 contents들을 수정하는 대신 Ajax를 통해서 서버로부터 HTML 코드를 받아 오는 것을 구현하겠습니다.


Retrieve the contents of the tabs by Ajax


<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 

  

<body> 


<div data-role=page id=home>

  <div data-role=header data-position=fixed>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>

  </div>

  

  <div data-role=footer data-position=fixed>

    <div data-role=navbar>

      <ul>

        <li id=menu1><a href=#>Menu 1</a></li>

        <li id=menu2><a href=#>Menu 2</a></li>

        <li id=menu3><a href=#>Menu 3</a></li>

      </ul>

    </div>

  </div>

</div>


</body>

</html>


<script>


$("#home").bind ("pagecreate", function (event)

{

  $("li#menu1 a.ui-btn").trigger ("vclick");

});


$("li").bind ("vclick", function (event)

{

  var id = this.id;

  $.ajax (

  

    url : "action.php", 

    data : { menu : id },

    complete : function (xhr, result)

    {

      if (result != "success") return;

      var response = xhr.responseText;

      $("#home div:jqmData(role=content)").html (response);

    }

  });  

});


</script>


action.php file


<?
$menu = $_REQUEST["menu"];

$html = "";
if ($menu == "menu1")
  $html .=   "<p> Content menu 1 </p>";
else if ($menu == "menu2")
  $html .=   "<p> Content menu 2 </p>";
else if ($menu == "menu3")
  $html .=   "<p> Content menu 3 </p>";
  
echo utf8_encode ($html);
?>

action30.php

tistory570_02.html




Methods managing fixed toolbars



data-position="fixed" attribute를 사용한 fixed type 의 toolbar 들을 관리하기 위해 jQuery Mobile은 아래 메소드들을 제공합니다.


Methods managing fixed toolbars


Method

Signification

$(selector)
.fixHeaderFooter ();

Search toolbars with the data-position = "fixed" attribute in the descendants of the elements represented by the specified selector, and transforms them into fixed toolbars. This allows to dynamically create these toolbars (see an earlier example in this chapter)

$.mobile
.fixedToolbars
.setTouchToggleEnabled (enable)

Enables (if enable is true) or disables (if enable is false) the ability to display and hide fixed toolbars by clicking in the window. By default, clicking in the window displays or hides fixed toolbars present in it. To disable this default, use $.mobile
.fixedToolbars
.setTouchToggleEnabled (false).

$.mobile
.fixedToolbars
.show (immediately)

Allows you to reposition the fixed toolbars in the window, if the modification of the contents of the window has changed their position. The immediately parameter indicates whether repositioning occurs immediately (if true) or if it is done by a fade effect (if false, the default).

$.mobile
.fixedToolbars
.hide ()

Allows to hide the fixed toolbars in the window. They are redisplayed at the next click in the window (unless this function has been disabled by $.mobile
.fixedToolbars
.setTouchToggleEnabled (false).





반응형

툴바 customize 하기

2012. 12. 27. 22:19 | Posted by 솔웅


반응형
Customize toolbars



이전 글에 있던 navigation bar 를 보죠. 우리는 단지 세개의 <li> elements만 사용해서 그 navigation bar 를 display 했었습니다. 그러면 jQuery Mobile 에 의해서 생성된 HTML 코드는 어떤지 Firebug를 통해서 볼까요?





각 <li> element이 정의된 테이블 안에 ui-navbar class가 생겼습니다.

<li> item에는 버튼에 해당하는 ui-btn class 를 가지고 있는 <a> link가 있구요. 이 링크는 클릭이 일어났을 때 ui-btn-active CSS class 를 갖게 될 겁니다. 그리고 다른 링크가 클릭되면 그 클래스는 없어집니다.


이 navigation bar를 우리 마음대로 꾸미기 위해서 이 CSS 클래스들을 이용할 수 있습니다.


Styling navigation bars


<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

  

  <style type=text/css>

    .ui-navbar a.ui-btn{

      font-size : 16px;

    }

    .ui-navbar a.ui-btn.ui-btn-active{

      font-style : italic;

      background : red;

    }

  </style>

</head> 

  

<body> 


<div data-role=page id=home>

  <div data-role=header data-position=fixed>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>

  </div>

  

  <div data-role=footer data-position=fixed>

    <div data-role=navbar>

      <ul>

        <li><a href=#>Menu 1</a></li>

        <li><a href=#>Menu 2</a></li>

        <li><a href=#>Menu 3</a></li>

      </ul>

    </div>

  </div>

</div>


</body>

</html>


tistory569_01.html







반응형

툴바에서 이벤트 다루기

2012. 12. 27. 18:36 | Posted by 솔웅


반응형
Manage events on toolbars



툴바는 일반적으로 어떤 action 을 취하기 위해 버튼 역할을 합니다. navigation bar navbar인 경우 <li> elements로 이뤄 집니다. 아이템을 클릭 했을 경우 이 클릭을 handle 하기 위해 click event (or the associated vclick virtual event)를 사용할 수 있습니다.


Use the click event in a navigation bar


<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 

  

<body> 


<div data-role=page id=home>

  <div data-role=header data-position=fixed>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <p> Window content </p>

  </div>

  

  <div data-role=footer data-position=fixed>

    <div data-role=navbar>

      <ul>

        <li><a href=#>Menu 1</a></li>

        <li><a href=#>Menu 2</a></li>

        <li><a href=#>Menu 3</a></li>

        <li><a href=#>Menu 4</a></li>

        <li><a href=#>Menu 5</a></li>

        <li><a href=#>Menu 6</a></li>

      </ul>

    </div>

  </div>

</div>


</body>

</html>


<script>


$("li").bind ("click", function (event)

{

  alert ($(this).find ("a").text ());

});

    

</script>


tistory568_01.html


navigation bar에서 두번째 버튼을 클릭하면 아래와 같이 될 겁니다.





반응형

Ajax 로 navigation bar 삽입하기

2012. 12. 26. 12:45 | Posted by 솔웅


반응형
Insert navigation bars by Ajax



footer toolbar 를 바꿔서 navigation bar (navbar) 를 넣어 보겠습니다.


Insert a navigation bar in the footer toolbar by Ajax


<!DOCTYPE html> 

<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

   <p> Window content </p>

  </div>

</div>


</body>

</html>


<script>


$.ajax (

  url : "action.php", 

  complete : function (xhr, result)

  {

    if (result != "success") return;

    var response = xhr.responseText;

    $("#home").append (response);

    

    $("#home").fixHeaderFooter ();

    $("#navbar").navbar ();

  }

}); 


</script>


이 소스코드는 이전 글의 소스 코드와 거의 같습니다. 단지 element 를 navigation bar 로 변환하기 위해 navbar () method 를 사용한 것만 다릅니다.


action.php file


<?
$html = "";
$html .= "<div id=footer class='ui-bar-a ui-footer' data-position=fixed>";
$html .=   "<h1 class=ui-title>Footer part</h1>";
$html .=   "<div id=navbar>";
$html .=     "<ul>";
$html .=       "<li><a href=# data-icon=refresh>Refresh</a></li>";
$html .=       "<li><a href=# data-icon=info>Help</a></li>";
$html .=       "<li><a href=# data-icon=delete>Close</a></li>";
$html .=     "</ul>";
$html .=   "</div>";

$html .= "</div>";
echo utf8_encode ($html);
?>


action29.php

tistory567_01.html


이 navigation bar 는 서버에 의해 return 된 HTML 에 전통적인 방법으로 간단하게 describe 돼 있습니다.





만약 여기서 navbar () method 를 없애면 HTML 은 jQuery Mobile 에 의해 변환되지 않게 됩니다. 그러면 아래와 같이 되죠.





반응형