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

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

jQuery Mobile and Dynamic Page Generation


jQuery Mobile은 default click hijacking behavior나 매뉴얼로 $.mobile.changePage()를 call 하는 것을 통해 다이나믹하게 DOM으로 page이 당겨져 올 수 있도록 해 줍니다. 이것은 서버사이드에서 HTML pages/fragments 를 generate 하는데 아주 좋습니다. 하지만 가끔 JSON이나 다른 포맷으로부터 클라이언트 사이드에서 page content를 다이나믹하게 generate 할 필요가 있습니다. 아마도 네트워크 광역폭이나 퍼포먼스적인 이유로 그런 일이 필요할 겁니다. 혹은 서버와 서로 소통하기 위해 서버가 선택할 데이터 포맷일 수도 있겠죠.


클라이언트 사이드에서 page markup을 generate 할 필요가 있는 어플리케이션을 위해 $.mobile.changePage() call 하는 동안 트리거되는 notification에 대해 이해하고 있는것이 중요합니다. 왜냐하면 해당 시간에 여러분의 content를 generate 할 수 있도록  navigation system 에 hook 하는것을 가능하게 해 주기 때문입니다. changePage()를 call 하게 되면 대개 아래와 같은 event notification이 trigger 됩니다.


  • pagebeforechange
    • Fired off before any page loading or transition.
    • NOTE: This event was formerly known as "beforechangepage".
  • pagechange
    • Fired off after all page loading and transitions.
    • NOTE: this event was formerly known as "changepage".
  • pagechangefailed
    • Fired off if an error has occurred while attempting to dynamically load a new page.


이런 notification들은 페이지의 parent container element(

$.mobile.pageContainer)에서 trigger 됩니다. 그리고 document element와 window에까지 계속 떠 다니게 될 겁니다. JSON이나 in-memory JS object 같은 non HTML data를 이용해서 어플리케이션에 page를 inject 하기를 원한다던가 아니면 빠르게 현재 존재하는 페이지의 내용을 modify 하기를 원한다면 pagebeforechange event 가 아주 유용할 겁니다. pagebeforechange event는 URL이나 page element들을 analyzing 하기위해 hook 할 수 있도록 해 줍니다.  어플리케이션은 load 하거나 switch 할거냐고 질문을 받게 되고 pagebeforechange event에서 preventDefault()를 call 함으로서 default changePage() behavior가 short-circuit 할지에 대해서도 질문을 받게 됩니다.




이 기술을 이용하기 위해 working sample을 한번 살펴 보시기 바랍니다. 이 샘플에서는 유저가 navigate 할 수 있는 카테고리 리스트로 메인페이지가 시작합니다. 각 카테고리의 실제 아이템들은 메모리의 javaScript object에 저장되어 있습니다. 이 데이터들은 어떤 곳에서든지 올 수가 있습니다.


var categoryData = {
	animals: {
	  name: "Animals",
	  description: "All your favorites from aardvarks to zebras.",
		items: [
			{
				name: "Pets"
			},
			{
				name: "Farm Animals"
			},
			{
				name: "Wild Animals"
			}
		]
	},
	colors: {
		name: "Colors",
		description: "Fresh colors from the magic rainbow.",
		items: [
			{
				name: "Blue"
			},
			{
				name: "Green"
			},
			{
				name: "Orange"
			},
			{
				name: "Purple"
			},
			{
				name: "Red"
			},
			{
				name: "Yellow"
			},
			{
				name: "Violet"
			}
		]
	},
	vehicles: {
		name: "Vehicles",
		description: "Everything from cars to planes.",
		items: [
			{
				name: "Cars"
			},
			{
				name: "Planes"
			},
			{
				name: "Construction"
			}
		]
	}
};


이 어플리케이션은 어플리케이션에게 어떤 카테고리 아이템이 display 되어야 하는지를 말해주는 hash를 포함한 url이 있는 링크를 사용합니다.



 <h2>Select a Category Below:</h2>
 <ul data-role="listview" data-inset="true">
    <li><a href="#category-items?category=animals">Animals</a></li>
    <li><a href="#category-items?category=colors">Colors</a></li>
    <li><a href="#category-items?category=vehicles">Vehicles</a></li>
 </ul>


내부적으로 이 링크 중 하나를 클릭하면 어플리케이션은 internal $.mobile.changePage() call을 intercept 합니다. 이 $.mobile.changePage() 는 프레임워크의 default link hijacking behavior에 의해 invoke 된 것이죠. 그러면 이제 로드되기 위해 페이지에 대한 URL을 analyze 하게 됩니다. 그리고 나서 이것이 로딩 자체만을 위한 것인지 아니면 일반적인 changePage() 코드로 처리해야 될 것인지에 대해 판단하게 되죠.

어플리케이션은 도큐먼트 레벨에서 pagebeforechange event로 binding 됨으로서 changePage() 로 그 자체를 insert 할 수 있게 됩니다.



// Listen for any attempts to call changePage().
$(document).bind( "pagebeforechange", function( e, data ) {

// We only want to handle changePage() calls where the caller is
// asking us to load a page by URL.
	if ( typeof data.toPage === "string" ) {

// We are being asked to load a page by URL, but we only
// want to handle URLs that request the data for a specific
// category.
		var u = $.mobile.path.parseUrl( data.toPage ),
			re = /^#category-item/;

		if ( u.hash.search(re) !== -1 ) {

// We're being asked to display the items for a specific category.
// Call our internal method that builds the content for the category
// on the fly based on our in-memory category data structure.
			showCategory( u, data.options );

// Make sure to tell changePage() we've handled this call so it doesn't
// have to do anything.
			e.preventDefault();
		}
	}
});



왜 도큐먼트 레벨에서 listen할까요? 간단히 말하면 deep-linking 때문입니다. 우리는 jQuery Mobile 프레임워크가 initialize 하기전에 active 되기위해 binding이 필요합니다. 그리고 어플리케이션을 invoke 한 initial URL을 어떻게 process 할지 결정하게 됩니다. pagebeforechange binding에 대한 callback이 invoke 됐을 때 callback에 대한 두번째 argument는 initial $.mobile.changePage() call에 pass 될 argument들을 포함한 data object가 될 겁니다. 이 object의 프로퍼티들은 아래와 같습니다.
  • toPage
    • transition 될 페이지를 포함한  jQuery collection object가 될 수도 있고 로드되거나 transition 될 페이지에 대한 URL reference가 될 수 있습니다.
  • options
    • $.mobile.changePage() function 함수의 caller에 의해 pass 된 옵션들을 포함한 Object
    • 옵션의 리스트는 여기에서 찾아 보실 수 있습니다.
우리의 샘플 어플리케이션에서는 URL들이 initial 하게 pass 된 changePage() calls 에 대해서만 관심이 있습니다. 그래서 우리의 callback이 하는 첫번째 일은 toPage의 type을 체크하는 겁니다 그 다음으로는 어떤 URL parsing 유틸리티의 도움을 받아서 우리가 스스로 handling 하기위해 관심을 가지고 있는 hash를 포함한 URL인가에 대해 체크를 합니다. 만약 그렇다면 showCategory()라는 어플리케이션 함수를 call 합니다. 이 함수는 URL hash에 의해 명시된 카테고리에 대한 content를 다이나믹하게 create 할 겁니다. 그리고 이벤트에서 preventDefault()를 call 할 겁니다. pagebeforechange event에서 preventDefault()를 call 하는 것은 다른 작업 없이 exit 하기 위해 $.mobile.changePage() call 을 유발하게 됩니다. 이 이벤트에서 preventDefault() method를 call 하는 것은 changePage() request를 여러분 스스로 핸들링하게되는 jQuery Mobile과 같다고 말할 수 있습니다.


preventDefault()가 call 되지 않는다면 changePage()는 평상시에 하던대로의 작업을 계속 이어나갈 겁니다. 우리의 callback에 pass 된 data object에 대해 짚고 넘어갈 부분은 여러분이 toPage 프로퍼티나 options 프로퍼티에 어떤 change를 했던지 간에 preventDefault()가 call 되지 않으면 changePage() processing에 영향을 줄 것이라는 겁니다. 예를 들어 다른 internal/external 페이지에 특정 URL을 redirect하거나 map 하고 싶다면 우리의 callback은 그 URL이나 redirect 될 페이지의 DOM 엘리먼트로 callback에 data.toPage 프로퍼티를 set 해야 합니다. 마찬가지로 우리는 우리 callback 안의 어떤 옵션에 대한 set이나 un-set을 할 수 있습니다. 그러면 changePage()는 새로운 세팅을 사용하게 될 겁니다.


이제 우리는 어떻게 changePage() call을 intercept 하는지 알게 됐습니다 이제 이 샘플 소스가 그 페이지에 대한 markup을 실제로 어떻게 generate 하는지 자세히 살펴 보겠습니다. 우리의 샘플 소스는 각 카테고리를 display 하기 위해 같은 페이지를 사용하거나 재 사용합니다. 우리의 special link 가 클릭 될 때마다 showCategory()가 invoke 됩니다.


// Load the data for a specific category, based on
// the URL passed in. Generate markup for the items in the
// category, inject it into an embedded page, and then make
// that page the current active page.
function showCategory( urlObj, options )
{
	var categoryName = urlObj.hash.replace( /.*category=/, "" ),

// Get the object that represents the category we
// are interested in. Note, that at this point we could
// instead fire off an ajax request to fetch the data, but
// for the purposes of this sample, it's already in memory.
		category = categoryData[ categoryName ],

// The pages we use to display our content are already in
// the DOM. The id of the page we are going to write our
// content into is specified in the hash before the '?'.
		pageSelector = urlObj.hash.replace( /\?.*$/, "" );

	if ( category ) {
// Get the page we are going to dump our content into.
		var $page = $( pageSelector ),

// Get the header for the page.
		$header = $page.children( ":jqmData(role=header)" ),

// Get the content area element for the page.
		$content = $page.children( ":jqmData(role=content)" ),

// The markup we are going to inject into the content
// area of the page.
		markup = "<p>" + category.description + 
"</p><ul data-role='listview' data-inset='true'>", // The array of items for this category. cItems = category.items, // The number of items in the category. numItems = cItems.length; // Generate a list item for each item in the category // and add it to our markup. for ( var i = 0; i < numItems; i++ ) { markup += "<li>" + cItems[i].name + "</li>"; } markup += "</ul>"; // Find the h1 element in our header and inject the name of // the category into it. $header.find( "h1" ).html( category.name ); // Inject the category items markup into the content element. $content.html( markup ); // Pages are lazily enhanced. We call page() on the page // element to make sure it is always enhanced before we // attempt to enhance the listview markup we just injected. // Subsequent calls to page() are ignored since a page/widget // can only be enhanced once. $page.page(); // Enhance the listview we just injected. $content.find( ":jqmData(role=listview)" ).listview(); // We don't want the data-url of the page we just modified // to be the url that shows up in the browser's location field, // so set the dataUrl option to the URL for the category // we just loaded. options.dataUrl = urlObj.href; // Now call changePage() and tell it to switch to // the page we just modified. $.mobile.changePage( $page, options ); } }


위 샘플에는 우리가 handle 하는 URL의 해쉬는 아래 두가지 부분을 포함하고 있습니다.


#category-items?category=vehicles

? 전에 있는 첫번째 부분은 content를 write할 page의 id입니다.  ? 다음 부분은 어떤 데이터가 사용되고 언제  페이지에 대한 markup을 generate 할지에 대해 알 수 있는 정보 입니다. showCategory()가 하는 첫번째 일은 이 content 를 write 할 페이지의 id를 추출하기 위해 hash를 deconstruct(해채) 하는 겁니다. 그리고 카테고리 이름은 우리의  in-memory JavaScript category object로부터 올바른 data 세트를 찾아올 때 사용됩니다. 어떤 카테고리 데이터를 사용할 지에 대한 작업이 끝난 이후 그 카테고리에 대한 markup을 generate 합니다. 그리고 그것을 그 페이지의 header와 content 부분에 inject 합니다. 그 element에 이전에 있었던 markup들은 모두 씻겨 나갑니다.


이 markup을 inject 한 이후에 막 inject 된 markup list를 잘 사용하기 위해 적당한 jQuery Mobile widget을 call 하게 됩니다. 이 과정은 styled listview에 list markup이 적용되는 일반적인 과정입니다.


이 작업이 일단 끝나면 $.mobile.changePage()를 call 합니다. 그리고 우리가 방금 modify 한 페이지의 DOM 엘리먼트를 pass 합니다. 이 페이지가 보여지기를 원한다고 프레임워크에게 말하기 위해서죠. 이제 이 부분에서 흥미로운 부분은 jQuery Mobile은 보여지는 페이지와 연관된 URL과 함께 브라우저의 location hash를 update 한다는 겁니다. 이러한 일이 일어 날 수 있는 이유는 우리가 각 카테고리에 대해 같은 페이지를 재사용했기 때문입니다. 이것은 이상적인 상황만은 아닙니다. 왜냐하면 그 페이지에 대한 URL은 그것과 관련된 특정 category 정보를 가지고 있지 않기 때문입니다. 이 문제를 해결하기 위해서는 showCategory()가 changePage()에 pass 한 options object에 대한 dataUrl 프로퍼티를 세팅해 주는 일입니다. 우리의 오리지날 URL 대신에 이것을 display 해 달라고 얘기하기 위해서죠.


여기까지가 샘플입니다. 이 샘플이 아주 좋은 예제는 아닙니다. 특히 grade가 낮아서 JavaScript가 turn off 됐을 때에는요. 이 의미는 C-Grade 브라우저에서는 제대로 작동하지 않을 거라는 겁니다. 이렇게 낮은 grade의 브라우저에서 어떻게 제대로 동작할 수 있도록 하는지에 대해서는 나중에 글을 올릴겁니다. 업데이트 된 내용을 보시려면 여기를 참조하세요.



반응형

How to Use Custom Events in Corona

2012. 6. 28. 02:46 | Posted by 솔웅


반응형

How to Use Custom Events in Corona

Posted on . Written by



1년 쯤 전에 (2011년 6월), Corona Event Model 에 대해서 다뤘었습니다. 거기서 코로나에서의 이벤트가 정확히 무엇인지 설명을 했었죠. 이벤트가 발생했을 때 어떻게 여러분이 hook 해서 코로나의 여러 기능들을 적용할수 있는지에 대해서도 다뤘었습니다.

하여간 지난번에는 코로나에서 제공하는 built-in 이벤트들에 대해서 그 API를 주로 다뤘었습니다. 그 때 제가 다루지 않았던 부분은 개발자가 스스로 custom 이벤트를 정의할 수 있다는 것입니다. 그리고 그 이벤트가 발생했을 때 listen 할 수 있다는 것하구요.(개발자 스스로 완벽하게 컨트롤 할 수가 있죠)


이 튜토리얼은 여러분만의 custom 이벤트를 어떻게 정의하고 dispatch 하는지에 대해 알려드릴겁니다.  여러분은 여러분의 게임이나 앱에 이 기능들을 적용할 수 있겠죠. 만약 여러분이 코로나 이벤트 모델에 대해서 그렇게 친숙하지 않다면 우선  The Corona Event Model Explained부분을 읽고 난 후 아래 부분을 읽기를 권장합니다.






The Scenario


이 튜토리얼의 시나리오를 한번 짜 보면 한개의 object와 하나의 player 가 있습니다. 여기에 그 건강상태와 관련된 많은 이벤트를 적용해 볼 겁니다. 우리는 이것을 health 이벤트라고 부르겠습니다. (이름은 여러분이 원하는대로 붙이시면 됩니다. 단지 다른 Corona event와 이름이 중복되거나 이미 있는 다른 custom event와 이름이 겹치지만 않으면 되요.)


Dispatching an Event


게임이 시작되면 어떻게 되는지 한번 얘기해 봐요. player의 건강은 75%일 겁니다. 그는 med pack을 집을거고 그러면 그의 건강의 100%가 될겁니다. 이 부분에서 우리는 health 이벤트를 dispatch 할 겁니다. event.type을 full로 할거구요. 여기서 여러분이 첫 번째로 할 일은 event table을 만드는 겁니다. 이 테이블은 listener 함수에 보낼 모든 데이터를 가지고 있게 될 겁니다. 일단 event table 셋업이 완료 되면 여러분은 object:dispatchEvent() 메소드를 call 할 수 있습니다.


local event = {
    name = "health",
    type = "full",
    healthPercent = 100
}
player:dispatchEvent( event )


event table에 있는 name 키는 object:dispatchEvent() 메소드에 전달될 건데요. 이게 유일하게 반드시 있어야 될 항목입니다. 나머지는 완벽하게 여러분 마음에 달려있습니다. 옵션이죠.

아래에 보면 health level이 low나 empty일 때 어떻게 health를 dispatch 하는지 보여 드립니다.


local event = {
    name = "health",
    type = "low",
    healthAmount = 10
}
player:dispatchEvent( event )
local event = {
    name = "health",
    type = "empty",
    healthAmount = 0
}
player:dispatchEvent( event )


Listening to Events


custom event에 object listen을 갖게 하는 방법은 코로나의 predefine된 이벤트에 listen을 다는 것과 똑 같이 하시면 됩니다. 간단하게 event name을 명시하고 (dispatch 했을 때 명시된 이벤트 이름이요) 그런 type의 event가 receive 됐을 때 그 함수가 call 되게 됩니다.

아래 예제는 player object가 dispatch 된 health 이벤트들에 어떻게 object listen 하게 되는지를 보여드리고 있습니다.


local function health_listener( event )
    if event.type == "full" then

        print( event.healthAmount )  -- 100
        turn_health_bar_green()    

    elseif event.type == "low" then

        print( event.healthAmount )  -- 10
        warn_player()
        turn_health_bar_red()

    elseif event.type == "empty" then

        print( event.healthAmount )  -- 0
        initiate_game_over()
    end
end
player:addEventListener( "health", health_listener )


table listener를 사용함으로서 self object로 그 object를 reference 할 수 있게 됩니다.


local function health_listener( self, event )
    if event.type == "full" then

        print( event.healthAmount )  -- 100
        turn_health_bar_green()    

    elseif event.type == "low" then

        print( event.healthAmount )  -- 10
        warn_player()
        turn_health_bar_red()

    elseif event.type == "empty" then

        print( event.healthAmount )  -- 0
        initiate_game_over()
    end
end
player.health = health_listener
player:addEventListener( "health", player )


어떻게 리스너 함수에서  healthAmount 변수가 접근 될 수 있는지 주목해 주세요. 이것이 Corona의 이벤트 모델이 진정 가치있는 부분입니다. 언제든지 이벤트의 특정 타입으로 object를 respond 하기를 원한다면 여러분은 object:addEventListener() method를 사용해서 그렇게 하실 수 있습니다. 역으로 object:removeEventListener() method를 사용해서 그 object의 listening을 stop 시킬수도 있습니다.


Things to Keep in Mind

믿으실지 모르겠지만 custom event의 dispatch와 listening 을 모두 끝냈습니다. 이제 여러분이 custom event를 사용하실 일 만 남았는데요. 몇가지 염두에 두셔야 할 것을들 정리했습니다.
  • 코로나에 이미 내장된 코로나 이벤트와 비교해서 살펴보면 custom event에서는 이벤트가 dispatch 될 때 반드시 여러분이 컨트롤 해야 합니다.
  • 코로나에 이미 내장된 코로나 이벤트와 마찬가지로 이벤트를 dispatch 되게 하기 위한 object listening을 하지 않으면 아무 일도 일어나지 않습니다.
  • object:dispatchEvent() method에 pass 된 이벤트 테이블은 name 키가 필요합니다. 그 나머지는 옵션입니다.


물론 여러분은 이벤트를 dispatching 하는 대신 direct로 함수를 call 하실 수 있습니다. 이벤트를 사용하는 가장 큰 이유는 여러분이 원하면 언제든지 그 이벤트에 대한 listening을 stop 시킬수 있다는 겁니다. (만들고 관리하고 함수를 call 할 때마다   Boolean 변수를 사용해서 항상 체크하고 하는것보다 훨씬 간편합니다.).

이벤트를 사용하는것은 또한 간단한 코딩을 지원합니다. 그러므로 유지보수를 더 수월하게 하죠. 어떤 종류의 custom 방식으로 코로나의 이벤트 모델을 사용하실건가요?




반응형


반응형

Data-url storage


navigation model은 모든 data-role="page" elements에서 data-url attribute를 maintain합니다. 이 data-url attribute는 page element의 근원을 track 하는데 사용됩니다. main application document에 embeded 된 페이지들은 모두 그들의 data-url 파라미터를 가지고 있습니다. 이것은 data-role="page"와 함께 그들의 ID로 세트 됩니다. 유일한 예외상황은 document의 첫번째 페이지에만 해당 됩니다 첫번째 페이지는 특별합니다. 왜냐하면 이 첫번째 페이지는 아이디를 가지고 있다면그 id로 addressed 되거나 document나 base URL (hash fragment가 없이)로 addressed 됩니다.

외부로 가는 페이지들은 ajax를 통해서 다이나믹하게 pull 됩니다. 그리고 그 data-url은 외부페이지와 연관된 경로로 세팅됩니다. 다른 도메인의 외부 페이지 로딩이 가능한 환경이라면 data-url은 absolute URL로 세팅 됩니다.



Auto-generated pages and sub-hash urls


어떤 플러그인들은 페이지 콘텐츠의 일부분을 deep link로 접근할 수 있는 별도의 navigable 페이지로 다이나믹하게 choose 하기도 합니다. 예를 들어 Listview 플러그인을 들 수 있습니다. 그것은 내부에 있는 UL (혹은 OL) 을 별도의 페이지로 분화합니다. 이것은 각각 data-url attribute 가 주어지게 되죠. 그래서 그것은 jQuery Mobile에서 다른 일반적인 페이지들처럼 링크가 걸릴 수 있습니다. 어쨌든 이 페이지들에 링크를 걸기 위해서는 첫번째로 서버로부터 request 되어야 합니다. 이렇게 하기 위해서 플러그인에 의해 자동 generate 되는 페이지들은 다음과 같은 특별한 data-url structure를 사용합니다.


<div data-url="page.html&subpageidentifier">


예를 들어 listview에 의해 generate 된 페이지는 다음과 같은 data-url을 가지게 될 겁니다.


 data-url="artists.html&ui-page=listview-1"


페이지가 request 되면은 jQuery Mobile은 ui-page에서 URL을 split 해야 된다는 것을 압니다. 그리고 그 key 전에 URL의 부분을 HTTP request 합니다. 위에 언급한 listview 예제의 경우 URL은 다음과 같을 겁니다. http://example.com/artists.html&ui-page=listview-1 ...

그리고 jQuery Mobile은 artists.html을 request 할 겁니다. 그 artists.html은 sub page들을 generate 하겠죠. data-url="artists.html&ui-page=listview-1" 와 함께 div도 생성할 겁니다. 그리고 나서 active page로 display 할 겁니다.

전체 URL path를  포함한 element의  data-url attribute 는 단지 &ui-page= 이후에 붙는 부분이라는 의미만이 아닙니다. 이로서 jQuery Mobile은  page data-url attributes와 매치되는 URL의 single consistent mechanism을 유지하게 되는 겁니다.


Cases when Ajax navigation will not be used


특정 상황에서 일반적인 http requests가 Ajax request 대신 사용될 겁니다. 이 경우는 external 웹사이트로 링크를 거는 경우에 해당 됩니다. 여러분은 다음과 같은 link attribute들을 통해 일반적인  http request를 사용하실 수 있습니다.

  • rel=external

  • target (with any value, such as "_blank")



Form submissions


Form submission도 navigation model을 통해서 자동적으로 처리 됩니다. 좀 더 자세한 정보는 forms section 를 참조하세요.


Using the Application Cache


jQuery Mobile에서 application cache를 사용할 때 고려해야할 사항이 있습니다. 어떤 브라우저에서는 cache에 request를 만들 때 성공하면 http status가 0를 report 할 겁니다. 이것은 에러 핸들러를 trigger하기 위해 jQuery Core의 $.ajax를 유발합니다. 이것을 해결하는 방법은 jQuery ajax pre-filter를 사용하는 겁니다. 아래와 같은 방식이 될 겁니다.(credit to jammus for the snippet):


$.ajaxPrefilter( function(options, originalOptions, jqXHR) {
  if ( applicationCache &&
       applicationCache.status != applicationCache.UNCACHED &&
       applicationCache.status != applicationCache.OBSOLETE ) {
       // the important bit
       options.isLocal = true;
  }
});



isLocal을 true로 해서 ajax request가 return 값이 0인 경우 다르게 처리하도록 jQuery Core에 alert 하게 합니다. Local request들은 비슷한 현상이 일어날 겁니다. (예: 0 status) 그리고 Core는 xhr responseText attribute의 content 에 근거해서 성공여부를 결정하기 위해 fall back 할 겁니다.


위와 관련해 한가지 알아두셔야할 점은  manifest 던지 아니던지 가리지 않고 ajax를 통해 만들어진 모든 request들에 대해 isLocal을 true로 세팅할 거라는 겁니다. 그렇게해서 cache가 valid 되는 겁니다. Core가 uncached result에 영향을 주지 않도록 status가 0 일 때 isLocal 값을 컨트롤하기 때문에 지금은 이렇게 작동을 합니다. 하지만 앞으로도 isLocal 이 0 status 값을 처리하기 위한 목적으로만 사용될 지는 보장할 수 없습니다. 만약 그 부분이 바뀌면 여러분의 어플리케이션은 문제를 일으킬 수 있습니다.



Known limitations


jQuery Mobile's page navigation model에 의해 생성된 non-standard environment는 페이지를 만들 때 주의해야 할 아래와 같은 상황들이 있습니다.


  • filename url 없이 디렉토리에 링크를 걸 때 (예를 들어 href="typesofcats/index.html 라고 하지 않고  href="typesofcats/라고 했을 때 ) 여러분은 반드시 trailing slash를 제공하셔야 합니다. 왜냐하면 jQuery Mobile은 url의 / 이후의 글자를 파일이름으로 생각하기 때문입니다. 그렇게 되면 / 이후의 부분은 나중에 참조할 때 사라지게 됩니다.

  • Ajax에 의해 로드된 document는 JQM 페이지 엘리먼트로서 로드 된 document의 DOM에 있는  첫번째 페이지가 select 될겁니다. 그래서 개발자는 로드된 페이지의 ID attribute와 child element를 잘 관리 해야 합니다.  그래야 DOM을 다룰 때 혼란스럽지 않습니다.

  • multipage document에 링크를 걸려면 그 링크에 반드시 data-ajax="false"를 하셔야 합니다. 이렇게 함으로서 Ajax request 에서 로드된 첫번째 페이지만 사용하는 제한을 벗어나서 full page를 사용하게 됩니다. 이 multi-page document를 로드할 수 있도록 하는 툴인 subpage plugin 이 있습니다.

  • jQuery Mobile-driven site에서 페이지에 의해 참조되는 unique assets는 page element 내부에 위치해 있어야 합니다. (page의 data-role attribute의 element). 예를 들어 별도의 페이지로 존재하는 styles와 scripts로의 링크 같은 경우 div 안에서 reference 될 수 있습니다. 어쨌든 바람직한 접근법은 특정 페이지가 로드될 때 특정 script를 실행하기 위해서 jQuery Mobile's page events를 사용하는 겁니다. NOTE : 이미 markup에서 특정된 data-url로 서버로부터 페이지를 return 받을 수 있습니다. 그리고 jQuery Mobile은 hash update를 할 겁니다. 이것은 여러분이 trailing slash로 directory path를 resolve 할 수 있도록 해 줍니다. 그래서 나중에 base url path가 사용될 수 있도록 합니다.

  • 역으로, non-unique assets (site 범위에서 사용되는)의 경우엔 HTML 도큐먼트의 <head> 섹션에서 reference 되어야 합니다. 적어도 page element의 밖에서 reference 되어야 합니다. 그래야지 그 script가 한번 이상 실행되는 것을 방지할 수 있습니다.

  • sub-hash url references에서 사용되는 "ui-page" key name은 여러분이 원하는대로 그 값을 세팅할 수 있습니다. 이 값은 jQuery.mobile.subPageUrlKey에 저장 됩니다.

  • push state plugin 이 enable 된 상태에서 내부나 외부 도큐먼트로부터 jQuery Mobile document로 back 될 때 어떤 브라우저는 잘못된 도큐먼트나 어떤 잘못된 원인이라고 해서 popstate 이벤트를 load하고 trigger 합니다. 여러분이 외부 document를 계속 링크를 걸어야 한다면 이 pushstate support를 disable 시키실 필요가 있습니다.

  • jQuery Mobile은 query parameter를 internal/embedded 페이지로 passing 하는 것을 지원하지 않습니다. 하지만 이 기능을 지원하도록 하는 두개의 플러그인이 있습니다. 가벼운 플러그인으로는 page params plugin이 있고 여러 기능을 제공하는 것으로는 jQuery Mobile router plugin이 있습니다. (이것은 backbone.js나 spine.js를 사용할 수 있도록 합니다.)

  • Back button behavior를 방지하기 위해 URL hash를 사용할 때 traditional anchor link(#foo)를 사용하는 것이 지원되지 않는 페이지를 jump down 하기 위해 page anchor를 사용합니다. scroll eventlistener trigger 하지 않고 특정 Y position을 scroll 하는 방법으로 silentScroll를 사용하는 방법이 있습니다.  yPos argument를 pass해서 그 Y location으로 scroll 할 수 있습니다.


반응형


반응형

jQuery Mobile's navigation model


jQuery Mobile 에서 page는 data-role 어트리뷰트를 page로 세팅한 엘리먼트(대개 div)로 구성됩니다. header,content,footer라는 role과 함께 div 엘리먼트를 주로 사용하게 되는데 일반적인 마크업이나 form 그리고 jQuery Mobile 위젯들을 포함하고 있습니다.


page 로딩의 기본적인 흐름은 아래와 같습니다.
첫째로 페이지는 일반적인 HTTP request 로 request 됩니다. 그리고 나서 그 다음 page들이 request 되고 page의 DOM으로 inject 됩니다. 그래서 DOM은 한번에 그 안에 여러개의 page들을 가지고 있게 됩니다. 그 페이지들은 data-url 어트리뷰트의 링크를 통해 re-visited 될 수 있습니다.


url이 initially request 됐을 때 그 response로 한개 이상의 page들이 있을 겁니다. 그 중에서 가장 첫번째 page가 보여집니다. 한개 이상의 페이지를 저장하는 것의 장점은 다시 방문할 가능성이 있는 page들에 대해 pre-fetch 할 수 있다는 것입니다.





Hash and Ajax driven page navigation


디폴트로 jQuery Mobile의 모든 navigation은 location.hash를 바꾸고 업데이트 하는 방법을 사용합니다. page change는 현재의 page와 다음 page 간의 부드러운 화면 전환을 할 수 있도록 해 줍니다. 그것이 DOM에 있는 페이지 이든 아니든 Ajax를 통해서 자동적으로 로드 됩니다.


jQuery Mobile에 의해 생성된 해쉬값들은 로드된 첫번째 실제 페이지의 URL과 연관된 full path를 사용합니다. 해쉬는 언제나 valid URL로서 유지가 됩니다. 그래서 jQuery Mobile의 어떤 페이지라도 즐겨찾기를 하거나 link로 연결할 수 있습니다. non-hash-based URL을 retrieve 하려면 간단하게 그 주세에서 #를 없애고 page를 refresh 하면 됩니다.


일반적으로 hash changes는 jQuery mobile에서 링크가 클릭 됐을 때마다 생성됩니다. 링크가 클릭되면 jQuery mobile은 그 링크가 local URL을 참조하고 있다는 것을 확인하고 만약 그렇다면 링크의 디폴트 click behavior를 Ajax를 통해서 url이 참조되도록하는 request나 상황이 일어나지 않도록 방지하게 도비니다 . 페이지가 성공적으로 return 되면 새 페이지의 relative url로 location.hash가 새로 세팅될겁니다.


click이외에 독립적으로 hash changes가 일어나는 경우, 예를 들어 유저가 back 버튼을 클릭했을 때라던지 할 때는 hashchange event에 의해 처리 됩니다. 이것은 Ben Alman의 hashchange special event plugin (jQuery Mobile에 include 돼 있음)를 사용해서 window object를 bound 합니다. hash change 가 일어나면 (혹은 첫번째 페이지가 로드될 때) hashchange event handler는 location.hase를 $.mobile.changePage() function으로 전달할 겁니다. $.mobile.changePage() function는 참조페이지를 로드하던가 reveal 하게 됩니다.


한번 그 참조 페이지가 DOM에 탑재되게 되면 $.mobile.changePage() function은 현재 active page와 새로운 페이지 사이에서 화면전환을 적용시키게 됩니다. Page transition은 CSS 애니메이션을 추가하거나 remove 함으로서 작동시키게 됩니다. 예를 들어 slide-left transition은 현재 페이지에는 "slideleft" 클래스를 적용하게 되고 그 다음에 "out" 하게 됩니다. 그리고 새로오는 페이지에는 slideleft 와 in 클래스가 적용 됩니다. 그리고 ui-page-active 도 새로 적용되서 새로운 페이지가 보여지도록 mark를 합니다. 이 애니메이션이 완료되면 in 과 out 클래스들은 remove 됩니다. 그리고 원래 있던 페이지는 ui-page-active 를 잃게 됩니다.


pushState plugin


이것은 옵션 기능인데요, 조금 전에 언급했던 hash-based URL 보다 긴 full document path를 다루고 URL structure에 Ajax tracking transparent를 만듭니다. 이것은 Ajax 링크에 대한 hash-based URL system 의 top에서 좀 더 enhance 된 기능을 제공하려고 만들어 졌습니다. 이름은 이렇지만 이 기능은 현재 버전에서는 기술적으로 history.replaceState (not history.pushState)을 사용해서 hash-based urls을 convert 한다는 것을 유념해 두세요. history.replaceState 를 지원하지 않는 브라우저나 이 기능이 가능하지 않은 경우에는 hash-based URL이 대신 사용될 겁니다.


DOM이 full 로드 됐을 때 플러그인이 initialize 되면 글로벌 configuration option$.mobile.pushStateEnabled 를 document가 준비되기 전에 언제든지 false로 세팅함으로서 이것을 enable 시키거나 disable 시킬 수 있습니다.



Important: rel="external" and $.mobile.ajaxEnabled=false


다양한 브라우저에서 replaceState API의 약간 다른 implementation은 특정 상황에서 이상하게 동작할 수도 있습니다. 예를 들어 어떤 브라우저(데스크탑 브라우저도 포함해서)의 implementation은 외부 링크일 경우나 링크가 이미 pushed/replaced 상태인 페이지로 move back 할 경우  popstate event 가 다르게 implement 됩니다. ajax navigation이 명시적으로 disable 된 jQuery Mobile 어플리케이션이 빌드 될 때 pushState feature 를 disable 시키라고 권고 합니다. 이는 hash based navigation의 좀 더 나은 consistent를 유지할 수 있도록 하기 위해서 입니다. - ajax navigation은 링크에 rel="external" 을 사용해서 disable 시킬수도 있고 $.mobile.ajaxEnabled=false 를 통해서 Ajax navigation을 완전히 disable 시킬 수도 있습니다. -



changePage


프레임워크에서 page changes는 - 페이지가 DOM에 이미 있던지 Ajax를 통해서 로드될 필요가 있던지 - $.mobile.changePage() 함수를 사용합니다. $.mobile.changePage() 에는 페이지를 transition 하는데 필요한 모든 로직이 있습니다. 그리고 page not found 같은 다양한 response 상태에 대해 어떻게 handle 할지에 대해서도 포함하고 있습니다.


$.mobile.changePage()는 externally call 될 수 있고 다음과 같은 argument들을 받을 수 있습니다. (to, transition, back, changeHash). to argument는 스트링(file url, local emdment의 ID 등), 배열(배열의 첫번째 아이템은 화면 전환할 from 페이지이고 두번째 아이템은 to 페이지 임) 혹은 객체(with expected properties: url, type ("get" or "post"), and data (for serialized parameters))를 받을 수 있습니다. 후자의 것은 form data이 경우에 유용하게 페이지를 로딩할 수 있습니다. transition argument는 slide 같이 transition 이름을 스트링으로 받습니다. 그리고 back argument는 transition이 순방향으로 진행할지 역방향으로 진행할지를 boolean을 통해서 지정할 수 있습니다. 마지막으로 changHash argument는 url이 성공적으로 페이지가 변환 된것에 따라 update 할지 여부에 대해 boolean을 사용해서 정합니다.


$.mobile.changePage() function은 jQuery Mobile에서 아주 많이 사용됩니다. 예를 들어 링크가 클릭 됐을 때 그것의 href attribute가 normalize 되고 나서 $.mobile.changePage() 이 나머지를 처리합니다. form 이 submit 됐을 때는 jQury Mobile은 아누 간단하게 몇개의 form의 attribute를 수집합니다. 그리고 그것을 serialize 하고 다시한번 $.mobile.changePage()이 submission과 response를 처리합니다. 또한 dialog를 생성하는 링크도 $.mobile.changePage() 를 사용해서 해당 페이지를 hash에 대한 update 없이 open 합니다. 이것은 history tracking 할 때 dialog를 제외시키는데 유용하게 사용됩니다.


Base element

jQuery Mobile's page navigation model의 또 다른 key point는 base element 입니다. 이것은 head에 삽입되고 모든 page change할 때 modify 됩니다. 이것의 역할은 모든 assets(이미지, CSS, JS 등) 이 정확한 경로를 통해 request 될 것인지에 대한 page 참조를 담당합니다. base emement에 대한 다이나믹 업데이트를 지원하지 않는 브라우저에서는 (파이어폭스 3.6 등) jQury Mobile은 base path를 기반으로 페이지와 prefix된 그들의 href 그리고 src sttribute 등의 assets를 참조해서 루프를 돕니다.


Developer explanation of base url management:

 jQuery Mobile은 generate된 절대 URL 경로와 generate된 <base> element의 href attribute 의 조합을 사용해서 http request를 관리합니다. 이 두 개의 조합은 로드되는 페이지의 full path를 포함하는 URL을 생성할 수 있도록 해 줍니다. base element는 이 로드된 페이지들에 의해 정확한 direct asset request를 만듭니다.


TODO: internal base와 urlHistory object의 decriptiond을 update 하세요.



반응형

iOS 웹클립에 관한 팁

2012. 6. 25. 21:51 | Posted by 솔웅


반응형

매니저인 Patrick이 휴가 가면서 웹사이트 링크를 메일로 보내주고 같습니다.
거기에는 iOS에서 사용되는 WebClip 에 대한 소개글이 있더라구요.

imore.com이라는 사이트인데 여러가지 개발 관련 팁 정보가 많이 있는 곳 같아요.


WebClip에 대한 내용은 이미 알고 있었지만 이렇게 따로 정리 해 두면 나중에 좀 더 도움이 될 수 있을 것 같아서 정리해 두기로 했어요.


그리고 외국 동료들이 알려주는 웹 싸이트는 네이버등 한국 검색엔진을 통해서 얻어지는 정보 이외에 추가적으로 정보를 얻을 수 있는 source가 될 수 있더라구요.


좀 더 풍부한 정보 소스를 확보 할 수 있는 잇점이 있어요.

(이 글을 읽는 분들에게도 도움이 되시길 바래요)


============== o ======= o =========


Ninja tip: How to create a custom iPhone/iPad home screen icon for your website

By , Friday, Nov 26, 2010 at 2:54 pm





Add to Homescreen 을 눌렀을 때 iPhone, iPod touch, iPad 에 웹사이트의 아이콘이 만들어서 보여지는데 관심 있으세요? 방문자들이 당신의 웹 사이트의 WebClip을 그들의 홈 스크린에 추가해서 볼 수가 있습니다. 그들은 그것을 친구들한테 보여 주겠죠? 그 친구들도 홈스크린에 웹 클릭을 추가할거고 여러분의 웹사이트는 구글 Page ranks에서 보여질 겁니다.

올해에 애플이 아이패드와 새로운 Retina Display 해상도를 선보였죠? 그러면 여러분은 더 큰 사이즈의 아이콘을 준비하셔야 할 겁니다.

• 120X120 사이즈의 아이콘이 iPad와 아이폰 4에 알맞는 아이콘 이미지 크기 입니다. 이 크기의 아이콘을 만드세요.
• 테두리에 둥근 처리 하는 것은 걱정하지 마세요. 애플이 자동적으로 해 줄겁니다. 그리고 손톱 모양의 shiny 효과도 자동적으로 해 줄거구요.


아이콘은 아래처럼 될 겁니다.



•  근사한 아이콘을 만들고 난 후 이것의 이름을 apple-touch-icon.png 로 명명하세요.
•  이제 이것을 여러분 웹사이트의 root 디렉토리에 업로드 하세요. 아마 아래와 같이 경로가 되겠죠.
http://www.yoursite.com/apple-touch-icon.png


이제 됐습니다. 아주 쉽죠?

이제 방문자가 아이폰이나 아이팟 터치 혹은 아이패드로 여러분의 사이트를 보다가 action 버튼(iOS 4.2 이하의 버전에서는  the "+" button 임)을 누르고 Add to Home Screen을 선택하게 될 겁니다. 그러면 방문자의 앱 목록에 여러분 사이트의 웹클립이 생성되겠죠. 이제 그 웹클립 아이콘만 누르면 한번에 여러분 사이트를 방문할 수 있습니다. 그러면 여러분 사이트는 더 많은 방문자를 기록하겠죠. 이 간단하고 소박한 기능을 절대 평가 절하하지 마세요. 





Bonus tip : 여러분 사이트에 custom icon을 생성하지 않으면 애플은 그 사이트의 페이지에 대한 screenshot으로 아이콘을 만들겁니다. 그 페이지는 Add to Home Screen을 할 때 오픈했던 페이지가 될겁니다.

UPDATE: Update : Marc EdwardsCampaign Monitor 에서 Jesse Dodd's article의 아티클에대해 다음단계로 웹 아이콘을 어떻게 생성하는지에 대해 알려 주었습니다.



나는 각 iOS 기계들의 해상도에 맞게 3개의 아이콘 이미지를 만들었습니다. iPhone 3G/3GS 에 대해서는 163dip를 iPad에 대해서는 132dpi를 그리고 iPhone4에 대해서는 326dpi 이미지를 만들었습니다.

<link rel="apple-touch-icon-precomposed" media="screen and (resolution: 163dpi)" href="/link/to/iOS-57px.png" />
<link rel="apple-touch-icon-precomposed" media="screen and (resolution: 132dpi)" href="/link/to/iOS-72px.png" />
<link rel="apple-touch-icon-precomposed" media="screen and (resolution: 326dpi)" href="/link/to/iOS-114px.png" />


위의 코드를 보시면 제가 apple-touch-icon-precomposed를 사용하신 것을 보실 수 있으실 거예요. -precomposed를 붙이면 iOS에서 자동적으로 만들어 지는 손톱모양의 shiny 효과와 코너 round 효과를 보여주지 않도록 할 겁니다. 만약 이 효과를 적용하고 싶으시면 이 부분을 빼면 됩니다. 그러면 여러분은 그냥 평면 이미지만 제공해도 iOS에서 자동적으로 처리를 해 주겠죠. 여러분이 직접 효과를 넣어서 더 예쁘게 하고 싶으시면 -precomposed 부분을 넣으시면 되구요.


더 자세한 것을 알고 싶으시면 전체 아티클을 읽어 보세요.

이제 방법을 아셨나요? 질문이 있으시면 댓글로 남겨 주세요. 만약 여러분 사이트에 훌륭한 새 아이콘이 생겼다면 저희에게 알려 주세요. 저희도 체크해 보게요.

Tips of the day 코너는 초보자부터 숙련자까지의 개발자들에게 도움이 되는 내용을 전해 드립니다. 이 팁을 이미 알고 계셨더면 다른 친구들에게 도움이 될 수 있도록 링크를 알려 주세요. 만약에 여러분만의 팁이 있으시다면 댓글로 알려주시거나 dailytips@tipb.com 으로 내용을 보내 주세요. (아주 훌륭하고 이전에 알려지지 않은 팁이라면 상품을 드립니다.)



반응형


반응형


Data Architect









Data Modeling Architect











반응형


반응형

phonegap-android-terminal-quickstart


이 글은 PhoneGap 0.9.2 와 0.9.3 시절의 튜토리얼 입니다. 지금은 폰갭 버전이 1.8.1이네요. 이점 감안하시고 보세요.

 

Requirements

 

이 글은 이미 안드로이드 SDK를 인스톨 했고 제대로 작동 되는 상황에서 직접 해 보실 수가 있습니다. 아직 안됐으면 먼저 Android SDK를 설치 하시고 진행하세요. 여기에서 다운로드 받으시면 됩니다. 그리고 최소한 한개 이상의 Android virtual device(AVD)를 생성해 놓으셔야 합니다. 안드로에드 에뮬레이터에서 여러분이 만든 프로젝트를 돌릴려면 AVD가 필요합니다. 그리고 여러분 system path에 Android tools와 android platform-tools 폴더 가 있어야 합니다. 이 두개의 폴더들은 여러분의 Android installation directory안에 있을 겁니다.


 

또한 폰갭도 필요하겠죠.

  • Download the latest copy of PhoneGap and extract its contents. 이글은 Android에 대한 튜토리얼이기 때문에 Android 디렉토리에 있는 내용이 중요합니다.
  • ant가 인스톨 돼 있어야 합니다. 필요하면 system path에 ant installation의 bin 폴더를 추가하셔야 합니다. 환경변수 ANT_HOME을 ant가 인스톨 된 폴더로 지정해 주세요.

 

 

Building The Sample Project

 

터미널에서 새로 다운로드 받은 폰갭을 찾아보세요. 그리고 android/sample 폴더로 가세요.

 

커맨드라인에서 android list targets를 타입해서 target 리스트를 보세요.

 

그리고 android update project -p . -t # 를 타입하세요. 그러면 필요한 파일들이 추가되거나 업데이터 될 겁니다. 위 명령어 중에서 # 는 ID로 바꿔주세요.




이제 에뮬레이터를 실행시키거나 device를 plug in  해 주세요. device를 plug in 하시는 편이 더 낫습니다. 그러면 아래 2 screen에 대한 과정은 넘어 가셔도 됩니다.

 

에뮬레이터는 Android AVD manager 와 함께 실행되고 커맨드라인에서 android라고 치면 됩니다.




원하는 virtual device를 선택하세요.



에뮬레이터가 다 로딩 될 때까지 기다리시고.

 그리고 build 하고 run  하시려면 터미널에 ant debug install을 타입하시면 됩니다.

  이제 여러분은 로드된 샘플 앱을 에뮬레이터를 통해 보실 수 있습니다.



Notes

 

가끔 and debug install이 실패할 수도 있습니다. 이럴 때는 터미널에 adb kill-server 를 하시고 adb start-server를 하세요. 그리고나서 adb-devices를 치시면 연결된 devices를 보실 수 있습니다.


샘플 프로젝트를 보실 수 있으시면 index.html을 마음대로 수정하시고 다시 실행 해 보세요.

 

안드로이드에서 디버그하기에 좋은 툴은 logcat 입니다. 이 logcat 을 사용하려면 터미널에서 adb logcat 을 치세요.


반응형

이클립스에 폰갭 설치하기

2012. 6. 22. 23:58 | Posted by 솔웅


반응형

phonegap-android-eclipse-quickstart


Requirements

 

이 글은 이미 안드로이드 SDK를 인스톨 했고 제대로 작동 되는 상황에서 직접 해 보실 수가 있습니다. 아직 안됐으면 먼저 Android SDK를 설치 하시고 진행하세요. 여기에서 다운로드 받으시면 됩니다. 그리고 최소한 한개 이상의 Android virtual device(AVD)를 생성해 놓으셔야 합니다. 안드로에드 에뮬레이터에서 여러분이 만든 프로젝트를 돌릴려면 AVD가 필요합니다.

 

You also need to: 또한 폰갭도 필요하겠죠.

 

이클립스에 이미 Android SDK 가 세팅 돼 있어야 겠죠. Window > Preferences > Android 를 여시고 아래와 같이 됐는지 확인해 보세요.




이제 여러분은 샘플 프로젝트를 빌드하시거나 새로운 프로젝트를 만드실 수 있습니다.

 

Building The Sample Project

 

File > New > Android Project

 

  • Create new project from existing source 를 선택하세요.
  •  Browse를 클릭하시고 다운로드 하신 폰갭에서 제공된 샘플 앱이 있는 곳을 찾아가세요.



오래된 안드로이드 버전을 사용하셔도 됩니다. 최신 버전의 SDK도 사용가능합니다. 어느것을 선택하시던 폰갭이 알아서 처리할 겁니다. 다만 이글을 쓰는 시점에 다운받은 폰갭 0.9.4 는 안드로이드 3.0과 문제가 있을 수 있으니 2.2나 2.3을 먼저 사용해 보세요.

 

(이 부분에서 이클립스가 phonegap.jar를 찾지 못하면 에러를 보실 수도 있습니다. 이런 경우 /libs 폴더에서 오른쪽 마우스를 누르시고 Build Paths/ > Configure Build Paths로 가 주세요. 그리고 나서 Libraries tab에서 phonegap.jar를 Project에 add 하세요. 이클립스가 제대로 표시하지 못한다면 여기서 refresh(F5)를 하시면 제대로 표시 할 겁니다.)

 

이제 여러분은 여러분의 프로젝트를 안드로이드 어플리케이션으로 돌릴 수 있습니다. 프로젝트에서 오른쪽 마우스를 누르시고 Run As 로 가셔서 Android Application 을 클릭하세요. 이클립스가 AVD를 선택하라고 할 수도 있습니다. 만약에 없으면 이때 create 하셔도 됩니다. 미리 생성해 놓으셨다면 선택하시고 진행하시면 됩니다.





Creating A New Project

 

File > New > Android Project




And give it some sensible defaults.




오래된 안드로이드 버전을 사용하셔도 됩니다. 최신 버전의 SDK도 사용가능합니다. 어느것을 선택하시던 폰갭이 알아서 처리할 겁니다.

 

여러분이 다운로드 받으신 폰갭에서 우리는 아래 두개의 파일이 필요합니다.

  1. Android/phonegap-1.0.0.jar
  2. Android/phonegap-1.0.0.js

 

이클립스에서 생성하신 프로젝트의 root 디렉토리에 아래 두개의 디렉토리를 생성하세요.

  1. /libs
  2. /assets /www

 

위 두 파일을 복사해 넣으세요.

  1. Android/phonegap-1.0.0.jar to /libs 
  2. Android/phonegap-1.0.0.js  to /assets/www

 

이클립스에서 Package Explorer에서 해당 프로젝트를 선택하신 후 refresh(F5)를 해 주세요. 복사해 넣은 두개의 파일이 보이실 거예요.

 

Now, create index.html in your www folder and add some code like so:

이제 www 폴더에 index.html을 생성하세요. 그리고 아래 코드를 복사해 넣으세요.


<!DOCTYPE HTML>
<html>

  <head>
    <title>PhoneGap</title>

  <script type="text/javascript" charset="utf-8" src="phonegap-1.0.0.js"></script>      

  <script type="text/javascript" charset="utf-8">

     function onLoad(){

          document.addEventListener("deviceready", onDeviceReady, true);

     }

     function onDeviceReady(){

          navigator.notification.alert("PhoneGap is working");

     }

  </script>

  </head>

  <body onload="onLoad();">
       <h1>Welcome to PhoneGap</h1>

       <h2>Edit assets/www/index.html</h2>

  </body>

</html>

 




이클립스의 src 폴더에 있는 main 자바 파일을 약간 수정해 주세요.

  1. 클래스의 extend를 Activity에서 DroidGap으로 바꿔주세요.
  2. Replace the setContentView() line 을 super.loadUrl("file:///android_asset/www/index.html"); 로 바꿔주세요.
  3. Add import com.phonegap.*;




(이 부분에서 이클립스가  phonegap-1.0.0.jar를 찾지 못하면 에러를 보실 수도 있습니다. 이런 경우 /libs 폴더에서 오른쪽 마우스를 누르시고 Build Paths/ > Configure Build Paths로 가 주세요. 그리고 나서 Libraries tab에서 phonegap-1.0.0.jar를 Project에 add 하세요. 이클립스가 제대로 표시하지 못한다면 여기서 refresh(F5)를 하시면 제대로 표시 할 겁니다.)

 

마지막으로 폰갭이 제대로 동작할 수 있도록 AndroidManifest.xml 파일에 몇개의 퍼미션을 추가하겠습니다.

여러분이 사용하시는 에디터로 매니페스트 파일을 열어 주세요. 그리고 versionName과 application 태그 사이에 아래 내용을 복사해서 넣어 주세요.


<supports-screens
        android:largeScreens="true"
        android:normalScreens="true"
        android:smallScreens="true"
        android:resizeable="true"
        android:anyDensity="true"
        />
        <uses-permission android:name="android.permission.CAMERA" />
        <uses-permission android:name="android.permission.VIBRATE" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
        <uses-permission android:name="android.permission.READ_PHONE_STATE" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.RECEIVE_SMS" />
        <uses-permission android:name="android.permission.RECORD_AUDIO" />
        <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
        <uses-permission android:name="android.permission.READ_CONTACTS" />
        <uses-permission android:name="android.permission.WRITE_CONTACTS" />   
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />   
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

 




AndroidManifest.xml에서 activity 태그에 아래 attribute 가 있어야 합니다.

 

    android:configChanges="orientation|keyboardHidden"

 

이건 뭘 말하냐 하면요. 안드로이드는 이런 이벤트들이 일어날 때 index.html을 reload 하지 않을거란 겁니다. phonegap이 이 이벤트들에 대해서 핸들링 할 겁니다.

 

마지막으로 다운로드 받으신 폰갭의 xml 폴더를 카피하셔서 여러분 프로젝트의 res 폴더에 넣으세요.

 

이제 여러분은 여러분의 프로젝트를 Android Application으로 실행하실 수 있습니다. 프로젝트에서 오른쪽 마우스를 클릭하신다음에 Run As -> Android Application을 선택하세요. 이클립스가 AVD를 선택하라고 물어볼 겁니다. AVD를 생성하지 않으셨으면 새로 생성하시고 이전에 생성하셨으면 그걸 선택해서 계속 진행합니다.

 

AVD가 적용되서 에뮬레이터가 뜨는데는 시간이 걸릴겁니다. 그리고 에뮬레이터가 뜬 후에도 조금 기다리시면 여러분이 만든 프로젝트가 화면에 실행 되는 걸 보실 수 있습니다.




 

 

Have fun!


반응형

Corona SDK: New public release

2012. 6. 22. 09:12 | Posted by 솔웅


반응형
Posted on . Written by


이번에 public release로 2012.840 이 릴리즈 됐습니다.

새로운 버전에는 아주 많은 기능들이 추가 됐고 버그들도 많이 수정됐습니다. 유료사용자분들은 이미 알고 계시겠지면 새로운 분들을 위해서 아래 주요한 내용들을 정리해 드리겠습니다.


  • In-app purchase on (Google Play/Android Marketplace)
  • Remote push notifications (iOS)
  • Game Center (iOS)
  • Facebook Single-sign on
  • Lua File System for creating, removing, getting contents of directories
  • Native video and web display objects (iOS)
  • And much more — you can read them all in the release notes.


저희는 지금 여러 기능들을 추가하고 고품질의 daily build를 제공하기 위해 새로운 지점에 와 있습니다.


다음주에 시작해서 최근에 말씀드린 첫번째 feature cycle을 시작할 겁니다. 바로 2-on-2 development의 일부분입니다. push 기능과 버그 수정입니다. 이 사이클이 끝날 즈음에는 여러분들이 이 기능을 앱 스토어 -iOS App Store, 구글 플레이, Nook Store, Amazon App Store- 에 출판할 수 있게 될 겁니다.


여러분들이 많이 원하시는 기능들에 대한 개선도 있습니다. 어느 정도 개발 이 완ㄹ 되면 daily build를 통해 여러분께 선보일 겁니다. 그리고 진짜 cool 한 SDK feature와 관련되서도 작업을 하고 있습니다. 여러분들께 말씀 드릴 수 있는 것은 저희 내부 적으로 부르는 이름인데요. Aloha 와 Flatland 입니다. 이게 공식적인 이름이 될지는 아직 모릅니다. 다만 daily build release에 이 기능이 추가 되서 언급이 되면 여러분들이 생소하지 않으시라고 이름을 알려 드립니다.




Posted on . Written by


Corona Labs Celebration Sweepstakes에 이미 참가하시고 새로운 페이스북 페이지에 support 해주신 많은 분들께 감사드립니다. 콘테스트가 아직 반도 안 왔습니다. 아직 여러분께 알려드릴 많은 상품들이 있습니다. 단지 여러분이 하실 일은 한번  enter 하세요 그리고 저희의 새로운 Corona Labs Facebook page 에 Like 를 남겨 주세요. 아주 쉽죠? 일찍 enter 하실 수록 상품을 탈 가능성이 점점 커집니다. 주저하지 마세요.


콘테스트를 실시한 이후로 3명의 당첨자가 나왔습니다. 깔끔한 Corona Swag Pack 을 받으신 Justin Giles 그리고 100불 상당의 아이튠즈 상품권을 받으신 Nick Anderson씨에게 축하드립니다. 그리고 조만간 Corona Book Collection 당첨자가 나올 겁니다.



What are the prizes and when will winners be announced?


이번 콘테스트에서 대상은 3천불 상당의 Corona Enterprise license입니다. 저희들은 매일 정오에 다른 상들에 대해 추첨을 할 겁니다. 그 스케줄은 아래와 같습니다.


Friday, June 22: 1 seat to a year-long Corona Levels subscription (currently in Beta)
Monday, June 25: 6 month Corona Pro subscription
Tuesday, June 26: 1 hour of Premium Support
Wednesday, June 27: 1 seat to a year-long Corona Enterprise license (worth $3,000!)



How can I enter the contest?


아주 간단합니다. form을 작성해 주시고 Facebook 의 Corona Labs에 Like를 남겨 주세요. 일찍 enter 할 수록 당첨될 확률이 더 높습니다. 마감은 6월 28일 정오까지 입니다. (미국 Pacific Time)


Thanks for entering and good luck!



Posted on . Written by




Roberto Ierusalimschy 씨가 Corona Labs의 가족이 되서 technical advisor and mentor 로 도움을 주시게 된 것을 진심으로 진심으로 환영합니다.  많은 분들이 아시듯이 Roberto는 Lua 의 핵심 architect 입니다. 코로나 앱이 이 언어를 사용하고 있고 gaming 부분에서는 표준으로 통하고 있죠.

저는 2010년에 Game Developer’s Conference (GDC SF)에서 Roberto를 처음 만났습니다. 그는 참 겸손했습니다. 올해 초 그는 스탠포드 대학교의 visiting professor로 초청됐습니다. 몇달 전 저녁식사 자리에서 스탠퍼드에서 연구한 결과에 대해서 아주 강조했던 것을 기억합니다. 그러면서도 자신의 공은 별로 없는 듯이 얘기 하더군요. 그래서 제가 농담 겸 해서 그와 그의 동료들이 있었기 때문에 GDC 가 존재할 수 있었다는 것을 다시 상기 시켜 줬습니다.  Roberto를 부끄러워하게 만들 수 있는 한가지 방법은 그를 과도하게 칭찬하는 겁니다.


Roberto와 그의 동료인 Luiz Henrique de Figueiredo 그리고 Waldemar Celes 의 업적에 의해 얼마나 많은 삶들이 영향을 받았는지 모릅니다. Lua는 embedded device에서 스마트폰 그리고 데스크탑 컴퓨터까지 애플리케이션을 만드는데 아주 광범위하게 사용되고 있습니다. 얼마나 많은 사람들이 Rovio의 앵그리 버드를 사용하는지를 한번 생각해 보세요. 얼마나 많은 사람들이 얼마나 오랫동안 World of Warcraft를 즐기는지를 생각해 보세요. 얼마나 많은 사람들이 Adobe Photoshop Lightroom으로 사진을 편집하나요.


Roberto는 분명히 이 우주에 그의 족적을 뚜렷이 남겼습니다. 우리의 목표를 향해 나아가는데 이 보다 더 좋은 멘토는 없을 겁니다.




반응형


반응형

Guided Tour of Corona’s API Reference

Posted on . Written by



이번주의 튜토리얼은 약간 다른겁니다. 코로나의 다른 기능들에 대해 다루기 보다는 어느 특정 기능보다도 더 중요하다고 할 수 있는 전체 코로나 개발에 대한 측면에서 바라볼 겁니다. 여러분이 오늘 배우실 것은 여러분이 코로나 프로젝트를 진행하면 반드시 사용하셔야 하는 분야 입니다. 바로 Corona SDK API Reference 이죠


Corona API Reference는 코로나의 특정 기능을 어떻게 사용하느냐에 대해서 배울 수 있는 문서 입니다. 특정 이벤트나 객체 타입에 대한 정보도 얻을 수 있고 항상 사용하셔야 할 자원입니다. 그러므로 이에 대한 튜토리얼을 소개하는 것은 당연하게 필요한 것이겠죠.


만약 여러분이 아직까지 API Reference를 충분히 활용하지 못하고 계신다면 처음에는 너무 많은 정보와 배울것들이 있다고 느낄겁니다. 오늘 제가 전반적인 내용을 훑어서 알려드리겠습니다. 그리고 이 Corona API reference가 더 좋아질 수 있도록 여러분이 도움을 주실 수 있는 방법도 알려드리겠습니다.


Interface Overview


코로나로 앱을 개발하기 위해 API를 많이 참조하시는 분은 지난주 이 API reference 웹 페이지가 새로 개편된 것을 보셨을 겁니다. 예전 페이지를 많이 참조하셨던 분들은 이번에 인터페이스가 완전히 바뀌어서 약간 불편해 하시는 분도 계실 수 있습니다. 하지만 조금 더 써보시면 훨씬 좋아졌다는 것을 느끼실 겁니다. 새 창이나 새 탭에 Corona API Reference를 띄우시고 아래 내용을 쭉 따라가 보세요.


Navigation and Sidebar


위쪽 sidebar에 있는 navigation bar는 보시면 아실 겁니다. 코로나의 전체 documentation을 크게 3부분으로 나눠서 각 section으로 갈 수 있도록 만들었습니다.

왼쪽은 각 세부 섹션들에 직접 갈 수 있는 링크들이 있습니다.  Jump to... 드롭 다운 메뉴도 이 좌측 링크들과 비슷한 역할을 합니다. 하지만 좌측 메뉴는 그 세부 섹션 페이지로 가는데 반해 이 드롭다운 메뉴는 현재 페이지 내에서 해당 항목으로 가는 겁니다. (페이지가 바뀌지는 않습니다.)





이 API Reference page는 코로나의 모든 함수, 이벤트, 프로퍼티, object methods 그리고 data type 들에 대한 리스트가 있는 index 입니다. 여러분이 무엇을 찾는지 확실하게 아신다면 ctrl+F 를 누르셔서 검색하는 게 가장 빠른 방법입니다. 또 다른 유용한 기능은 아래쪽에 있는 바로 breadcrumbs 라고 합니다. 이 하단의 바는 항상 있는데요. 여러분이 지금 어디에 있는지 알려주는 역할을 합니다.






API Reference Columns


API Reference index (home) page에 보면 3가지 주제로 나뉘어져 있는 걸 보실 겁니다. -Libraries, Events, Types -




Libraries  컬럼은 Corona에 내장된 함수의 리스트 입니다. (display.newImageRect()나  storyboard.gotoScene() 같은). Events 리스트는 다양한 이벤트의 종류를 열거했습니다. 그리고 각 이벤트들에 대한 연관된 프로퍼티들도 있구요.Types 는 코로나의 여러 데이터 타입들을 포함하고 있습니다. 그리고 Library 함수들에 의해 생성된 객체들하구요 그와 관련된 프로퍼티와 메소드들(특정 객체 타입에 attached 된 함수들)이 있습니다.


Reference Pages


각각의 API reference 페이지들은 특정 함수와 프로퍼티 등에 대해 여러분들이 알아야할 모든 정보가 있습니다. 만약 여러분이 이 library 함수에 대한 아무 페이지나 보시게 되면 -예를 들어 display.captureScreen() 같은 - 아래 이미지와 같은 내용을 보실 겁니다. 보시면 아시겠지만 이전의 API reference 보다 더 많은 정보들이 있습니다.


딱 보면 어떤 종류의 객체(혹은 데이터 타입)를 이 함수가 return 하는지 Revision (Build)이 뭔지, parent library 는 뭔지 그리고 관련된 키워드는 무엇이 있는지 그리고 연관된 링크(다른 API나 튜토리얼, 외부 웹페이지 등) 등을 보실 수 있습니다. 다른 타입의 API 페이지는 윗 부분에 다른 내용들이 있을 겁니다. 그건 그 타입에 걸맞는 내용들입니다.




좀 더 아래쪽에는 overview가 있습니다. 여기에는 일반적으로 조심해야 될 부분이나 헛갈리는 부분에 대한 설명이나 syntax structure, 관련된 함수 파라미터들 그리고 예제들이 있습니다.


Searching the Documentation


만약 여러분이 특정 API 페이지를 찾으셔야 한다면 home/index 페이지로 가세요. 그리고 브라우저에서 page search 를 하시던가 좌측 메뉴 링크를 이용하시던가 Jump To 드롭다운 메뉴를 이용하세요. 그런데 그 API의 정확한 이름을 모르신다면 전체 Corona Docs에서 키워드를 사용해 검색을 하실 수 있습니다. (구글에서 검색하시는 것처럼요). 검색 필드는 오른쪽 위에 있습니다. (아래 이미지를 참조하세요.)





검색 결과는 구글이 코로나 내의 블러그나 API reference page 들에서 검색한 내용입니다. images를 타입하시고 엔터키를 쳐 보세요. 그 정확도에 놀라실 겁니다.


Help Improve the API Reference


새로운 API reference는 이전 API reference 보다 많이 개선 되었습니다. 하지만 완벽한것은 아니라는 것을 저희들은 압니다. 우리가 중요한 것을 간과하거나 잊어버리고 만들었을 수도 있습니다.  (그것이 이전 API reference에 있었을 수도 있고 없었을 수도 있구요.)  어딘가 오탈자가 있을 수도있구요. 예제가 있어야 되는데 빠져 있을 수도 있구요.


코로나 API Reference 웹사이트는 계속 보완을 해 나갈 겁니다. 그리고 저희 스스로도 계속 보완할 내용을 찾는 작업을 할테고 여러분의 feedback 도 계속 받겠습니다. 특정 API 페이지에서 어떤 잘못 된 것을 발견하시거나 빠진것을 발견하시면 저희에게 알려 주세요. 그 방법은 아주 간단합니다. 각 API Reference Page의 아래쪽에 3개의 링크를 보실 수 있을 겁니다. 관련된 링크를 누르고 그 내용을 넣어 주시면 됩니다.




그러니까 API 에 관련해서 잘못 된 부분을 알려주시려면 이 블로그 글의 댓글을 달기 보다는 해당 API 페이지에 가셔서 밑에 있는 링크를 누르고 알려 주시면 감사하겠습니다. 그 링크를 누르시면 몇개의 checkbox들이 있을 겁니다. 그리고 comment 필드도 있구요. 관련 사항에 체크하시고 가급적이면 자세하게 코멘트를 달아 주세요.


여러분들 중에 이미 많은 분들이 이 feedback form을 사용해 보셨을 겁니다. 이 웹사이트를 지난주에 오픈했는데도 이미 많은 글들이 올라왔거든요. 저희들의 실수를 지적해 주신 모든 분들께 감사드립니다. 그리고 의견을 올려 주신분들도 감사드리구요. 여러분들 중에 몇분은 아주 잔인할 정도로 정직하시더라구요. 그게 바로 저희들이 원하는 겁니다. 계속 와 주세요. 지금 코로나의 함수들, 이벤트들 그리고 객체 프로퍼티와 메소드들에 대해 정통한 정보를 찾아서 사용 하세요.


Still confused?


만약 API Reference 페이지가 아직 헛갈리시면 그리고 어디서부터 시작해야 할 지 모르시면 우선 보실 필요가 있는 곳이 Guides 섹션 입니다. 여기에는 초보자 분들을 위한 Corona SDK Quick-Start 가 있습니다.



반응형