2010년 6월 2일: 이 시리즈의 정보, 요약 및 참고자료 섹션에 이 시리즈의 Part 3에 대한 링크를 추가했다.
HTML 5는 매우 과대 포장된 기술이지만 그럴만한 충분한 이유가 있다. HTML 5는 데스크탑 애플리케이션 기능을 브라우저로 가져오는 기술적인 정점이 될 것이다. 기존의 브라우저에서도 전망이 밝지만 모바일 브라우저에서는 잠재력이 더 크다. 무엇보다도 가장 유명한 모바일 브라우저에서 HTML 5 스펙의 많은 중요 부분을 이미 채택하고 구현했다.
5편의 기사로 구성된 이 시리즈에서는 HTML 5의 일부이며 모바일 웹 애플리케이션 개발에 많은 영향을 미칠 수 있는 여러 새로운 기술에 대해 자세히 살펴본다. 각 부분에서는 iPhone 및 Android 기반 장치에 있는 것과 같은 최신 모바일 웹 브라우저에서 사용할 수 있는 HTML 5 기능을 소개하는 실용적인 모바일 웹 애플리케이션을 개발한다.
이 기사에서는 최신 웹 기술을 사용하여 웹 애플리케이션을 개발한다. 이 기사에 있는 코드는 대부분 웹 개발자들이 주로 사용하는 HTML, JavaScript 및 CSS로 구성되어 있다. 필요한 가장 중요한 항목은 테스트를 수행할 브라우저이다. 이 기사의 코드는 언급된 일부 예외를 제외하고는 대부분 최신 데스크탑 브라우저에서 실행된다. 물론 모바일 브라우저에서도 테스트해야 하며 최신 iPhone 및 Android SDK가 이러한 브라우저로 적합할 것이다. 이 기사에서는 iPhone SDK 3.1.3과 Android SDK 2.1이 사용되었다. 링크는 참고자료를 참조한다.
웹 개발자들은 오랫동안 클라이언트에 데이터를 저장하기 위해 고심해 왔다. HTTP 쿠키는 이러한 목적을 위해 혹사당해 왔다. 개발자들은 HTTP 스펙에 의해 할당된 4KB에 엄청난 양의 데이터를 우겨넣었다. 이유는 간단하다. 대화식 웹 애플리케이션은 다양한 이유로 데이터를 저장해야 하기 때문에 서버에 해당 데이터를 저장하는 데 충분하지 않거나 안전하지 않거나 적합하지 않은 경우가 자주 있다. 수년 동안 이러한 문제에 대한 여러가지 대안이 있었다. 다양한 브라우저에서 소유 스토리지 API를 소개했다. 또한 개발자들은 JavaScript를 통해 노출하여 Flash Player의 확장된 스토리지 기능을 활용했다. 이와 비슷하게 Google에서는 다양한 브라우저를 위해 Gears 플러그인을 작성했으며 여기에는 스토리지 API가 포함되어 있었다. 일부 JavaScript 라이브러리에서 이러한 차이점을 완화하기 위해 노력한 것은 놀랄만한 일이 아니다. 즉, 이러한 라이브러리에서는 단순한 API를 제공한 후 어떤 스토리지 기능이 존재하는지 확인한다(소유 브라우저 API이거나 플래시와 같은 플러그인이 될 수 있음).
웹 개발자들을 위해 다행히도 마침내 HTML 5 스펙에 광범위한 브라우저에서 구현되는 로컬 스토리지의 표준이 포함되어 있다. 사실 이 표준은 가장 신속하게 채택된 항목 중 하나였으며 Microsoft®, Internet Explorer®, Mozilla Firefox, Opera, Apple Safari 및 Google Chrome과 같은 모든 주요 브라우저의 최신 버전에서 지원된다. 모바일 개발자에게 특히 중요한 점은 iPhone과 Android(버전 2.0 이상)를 사용하는 전화에 있는 것과 같은 WebKit 기반 브라우저와 Mozilla의 Fennec과 같은 기타 모바일 브라우저에서 지원된다는 것이다. 이러한 내용을 염두에 두고 API에 대해 살펴보자.
localStorage API는 매우 단순하다. 실제로 HTML 5 스펙에 따라
DOM 스토리지 인터페이스를 구현한다. 이렇게 구별하는 이유는 HTML 5가 이 인터페이스를
구현하는 두 개의 구별되는 오브젝트(localStorage 및 sessionStorage)를
지정하기 때문이다. sessionStorage 오브젝트는 세션 중에 데이터만 저장하는 Storage 구현이다.
좀더 정확하게 말하면 sessionStorage에 액세스할 수 있는 실행 중인 스크립트가 없으면 브라우저가 여건이 될 때 sessionStorage 데이터를 삭제할 수 있다.
이는 여러 사용자 세션에 걸쳐 있는 localStorage와 대조적이다. 두 오브젝트는 동일한 API를 공유하기 때문에 필자는 localStorage에만 초점을 맞춘다.
Storage API는 전형적인 이름/값 쌍 데이터 구조이다. 사용하게 될
가장 일반적인 메소드는 getItem(name) 및 setItem(name, value)이다.
이러한 메소드는 정확히 예상한 대로 작동된다. getItem은
이름과 연관된 값을 리턴하거나 해당 항목이 없을 때는 널(null)을 리턴하지만 setItem은
이름/값 쌍을 localStorage에 추가하거나 기존 값을 대체한다.
이름이 암시하듯이 이름/값 쌍이 있을 경우 localStorage에서 이름/값 쌍을 제거하고
이름/값 쌍이 없으면 아무것도 수행하지 않는 removeItem(name)도 있다.
마지막으로 모든 이름/값 쌍에서 반복하는 데 필요한 두 가지 API가 있다. 하나는 저장 중인 이름/값 쌍의
총 수를 제공하는 길이 특성이다. 이에 맞추기 위해 key(index) 메소드는
스토리지에 사용된 모든 이름의 배열에서 이름을 리턴한다.
이러한 단순 API를 사용하여 많은 작업을 수행할 수 있다. 그 예로는 개인화 또는 사용자
동작 추적 등이 있다. 이러한 작업은 모바일 웹 개발자에게 중요한 유스 케이스가
될 수 있지만 캐싱이라는 더 중요한 항목이 있다. localStorage를
사용하면 클라이언트의 로컬 시스템에서 서버의 데이터를 쉽게 캐싱할 수 있다. 이를 통해
다시 서버로 전송되는 잠재적으로 느린 호출을 기다리지 않을 수 있고 서버에서 필요한
데이터의 양이 최소화된다. 이제 localStorage를 사용하여 이러한 유형의 캐싱을 수행하는
방법을 보여 주는 예제를 살펴보자.
이 예제는 이 시리즈의 Part 1에서 처음 개발을 시작한 예제 위에 빌드된다. 해당 예제에서는 위치표시(geolocation) API를 사용하여 사용자의 위치를 가져와서 Twitter의 로컬 검색을 수행하는 방법을 보여줬다. 해당 예제로 시작하여 해당 예제를 단순화한 후 성능을 향상시킨다. 시작하려면 위치표시(geolocation) 없는 Twitter 검색까지 예제를 파헤쳐 본다. Listing 1에서는 단순화된 Twitter 검색 애플리케이션을 보여 준다.
Listing 1. 가장 기본적인 Twitter 검색
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name = "viewport" content = "width = device-width"/>
<title>Basic Twitter Search</title>
<script type="text/javascript">
function searchTwitter(){
var query = "http://search.twitter.com/search.json?callback
=showResults&q=";
query += $("kwBox").value;
var script = document.createElement("script");
script.src = query;
document.getElementsByTagName("head")[0].appendChild(script);
}
// ui code deleted for brevity
function showResults(response){
var tweets = response.results;
tweets.forEach(function(tweet){
tweet.linkUrl = "http://twitter.com/" + tweet.from_user
+ "/status/" + tweet.id;
});
makeResultsTable(tweets);
}
</script>
<!-- CSS deleted for brevity -->
</head>
<body>
<div id="main">
<label for="kwBox">Search Twitter:</label>
<input type="text" id="kwBox"/>
<input type="button" value="Go!" onclick="searchTwitter()"/>
</div>
<div id="results">
</div>
</body>
</html>
|
이 애플리케이션에서는 JSONP에 대한 Twitter 검색 API의 지원을 사용한다. 사용자가 검색을
제출하면 페이지에 스크립트 태그를 동적으로 추가한 후 콜백 함수의 이름을 지정하여
API 호출이 작성된다. 이를 통해 웹 페이지로부터 상호 도메인 호출을 작성할 수 있다.
호출이 리턴되면 콜백 함수(showResults)가 호출된다.
Twitter에서 리턴하는 각각의 트윗에 링크 URL을 추가한 후 트윗을 표시하는 단순
테이블을 작성한다. 이러한 작업의 속도를 높이기 위해 검색 쿼리의 결과를 캐시한 후
사용자가 쿼리를 제출할 때마다 이러한 캐시된 결과를 사용한다. 먼저 localStorage를
사용하여 트윗을 로컬로 저장하는 방법에 대해 살펴본다.
기본 Twitter 검색에서는 Twitter 검색 API의 트윗 배열을 제공한다.
이러한 트윗을 로컬로 저장한 후 이러한 트윗을 생성한 키워드와 연관시킬 수 있으면 유용한 캐시가 있는 것이다.
트윗을 저장하려면 Twitter 검색 API에 대한 호출이 리턴될 때 호출되는 callback 함수를 수정하기만 하면 된다.
Listing 2에서는 수정된 함수를 보여 준다.
Listing 2. 검색 및 저장하기
function searchTwitter(){
var keyword = $("kwBox").value;
var query = "http://search.twitter.com/search.json?callback
=processResults&q=";
query += keyword;
var script = document.createElement("script");
script.src = query;
document.getElementsByTagName("head")[0].appendChild(script);
}
function processResults(response){
var keyword = $("kwBox").value;
var tweets = response.results;
tweets.forEach(function(tweet){
saveTweet(keyword, tweet);
tweet.linkUrl = "http://twitter.com/" + tweet.from_user + "/status/" + tweet.id;
});
makeResultsTable();
addTweetsToResultsTable(tweets);
}
function saveTweet(keyword, tweet){
// check if the browser supports localStorage
if (!window.localStorage){
return;
}
if (!localStorage.getItem("tweet" + tweet.id)){
localStorage.setItem("tweet" + tweet.id, JSON.stringify(tweet));
}
var index = localStorage.getItem("index::" + keyword);
if (index){
index = JSON.parse(index);
} else {
index = [];
}
if (!index.contains(tweet.id)){
index.push(tweet.id);
localStorage.setItem("index::"+keyword, JSON.stringify(index));
}
}
|
첫 번째 함수인 searchTwitter부터 시작한다. 이 함수는
사용자가 검색을 제출하면 호출된다. Listing 1과 비교하여 변경된
유일한 항목은 callback 함수이다. 트윗이 돌아올 때
트윗을 표시하기만 하는 대신 트윗을 처리(저장 및 표시)해야 한다. 따라서 새로운
callback 함수인 processResults를 지정한다.
각 트윗을 가져와서 saveTweet을 호출한다. 검색 결과를
생성하는 데 사용된 키워드도 전달한다. 왜냐하면 이러한 트윗을 해당 키워드와 연관시키려고
하기 때문이다.
saveTweet 함수에서 localStorage가
실제로 브라우저에서 지원되는지 확인하는 것으로 시작한다. 앞서 언급했듯이 localStorage는
데스크탑 및 모바일 브라우저에서 광범위하게 지원되지만 이 경우와 같이 새로운 기능
사용 시에는 항상 확인하는 것이 좋다. 지원되지 않는 경우에는 함수에서 다시 돌아오기만
한다. 명백하게 저장되는 내용은 없지만 오류는 발생하지 않는다. 이 경우 애플리케이션에는
캐시가 없을 뿐이다. localStorage가 지원되는 경우에는
먼저 트윗이 이미 저장되어 있는지 확인한다. 저장되어 있지 않으면 setItem을
사용하여 로컬로 저장한다. 다음으로 키워드에 해당하는 색인 오브젝트를 검색한다.
색인 오브젝트는 단순이 키워드와 연관된 트윗의 ID 배열이다. 트윗 ID가 아직 색인의
일부가 아닌 경우에는 트윗 ID를 추가한 후 색인을 업데이트한다.
Listing 3에서 JSON을 저장한 후 로드할 때 JSON.stringify 및
JSON.parse를 사용한 것에 유의한다. JSON 오브젝트(더 정확하게는
window.JSON)는 항상 존재하는 원시 오브젝트로서
HTML 5 스펙의 일부이다. JSON 오브젝트의 stringify 메소드는
JavaScript 오브젝트를 직렬화된 문자열로 변환하고 parse
메소드는 그 반대로 변환한다. JSON 오브젝트는 직렬화된 문자열 표시로부터 JavaScript
오브젝트를 복원한다. localStorage는 문자열만 저장하기 때문에
이 작업이 필요하다. 하지만 원시 JSON 오브젝트는 localStorage만큼
광범위하게 구현되지는 않는다. 예를 들어, iPhone의 최신 Mobile Safari 브라우저(이 기사
작성 시에는 버전 3.1.3)에는 없다. JSON 오브젝트는 최신 Android 브라우저에서 지원된다.
JSON 오브젝트가 있는지 쉽게 확인할 수 있으며 없는 경우에는 추가 JavaScript 파일을
로드할 수 있다. json.org 웹 사이트(참고자료 참조)로 이동하여
기본적으로 사용되는 동일한 JSON 오브젝트를 확보할 수 있다. 이러한 직렬화된 문자열이
로컬로 어떻게 표시되는지 확인하려면 지정된 사이트에서 localStorage에 저장되는 항목을
조사하는 데 필요한 다양한 브라우저 도구를 사용한다. 그림 1에서는
로컬로 저장되고 Chrome의 Developer Tools를 사용하여 표시되는 캐시된 트윗 중 일부를
보여 준다.
그림 1. 로컬로 캐시된 트윗
Chrome과 Safari에는 localStorage에 저장 중인 모든 데이터를
볼 수 있는 내장 개발자 도구가 있다. 이 도구는 localStorage를
사용하는 애플리케이션을 디버깅하는 데 매우 유용할 수 있다. 이 도구는 일반 텍스트로
로컬로 저장되는 키/값 쌍을 보여 준다. Twitter의 검색 API에서 제공되는 트윗을 캐시로
사용할 수 있도록 저장을 시작했으므로 localStorage에서 해당
트윗을 읽어오기만 하면 된다. 이제 트윗을 읽어오는 방법에 대해 살펴본다.
Listing 2에서 getItem 메소드를 사용하여 localStorage에서 읽어오는 일부 예제를 확인했다.
이제 사용자가 검색을 제출하면 캐시 히트를 확인하고 즉시 캐시된 결과를 로드할 수 있다. 물론 사용자들이 항상 트윗을 전송하고 검색 결과에 추가하기 때문에 여전히 Twitter 검색 API에 대해 쿼리를 수행한다.
하지만 이제는 아직 캐시에 없는 결과만 요청하여 더 효율적으로 쿼리를 수행할 수도 있다. Listing 3에서는 업데이트된 검색 코드를 보여 준다.
Listing 3. 로컬로 먼저 검색하기
function searchTwitter(){
if ($("resultsTable")){
$("resultsTable").innerHTML = ""; // clear results
}
makeResultsTable();
var keyword = $("kwBox").value;
var maxId = loadLocal(keyword);
var query = "http://search.twitter.com/search.json?callback=processResults&q=";
query += keyword;
if (maxId){
query += "&since_id=" + maxId;
}
var script = document.createElement("script");
script.src = query;
document.getElementsByTagName("head")[0].appendChild(script);
}
function loadLocal(keyword){
if (!window.localStorage){
return;
}
var index = localStorage.getItem("index::" + keyword);
var tweets = [];
var i = 0;
var tweet = {};
if (index){
index = JSON.parse(index);
for (i=0;i<index.length;i++){
tweet = localStorage.getItem("tweet"+index[i]);
if (tweet){
tweet = JSON.parse(tweet);
tweets.push(tweet);
}
}
}
if (tweets.length < 1){
return 0;
}
tweets.sort(function(a,b){
return a.id > b.id;
});
addTweetsToResultsTable(tweets);
return tweets[0].id;
}
|
먼저 눈에 띄는 점은 검색이 제출될 때 새 loadLocal 함수를 먼저
호출한다는 것이다. 이 함수는 캐시에 있는 최신 트윗의 ID인 정수를 리턴한다.
keyword는 localStorage에서
관련 트윗을 찾는 데 사용되기 때문에 loadLocal 함수는
keyword를 사용한다. maxId가
있는 경우에는 maxId를 사용하여 쿼리를 Twitter로 수정하고 since_id
매개변수를 추가한다. Twitter API에 이 매개변수에 제공된 ID보다 최신인 트윗만
리턴하도록 지시한다. 잠재적으로 이를 통해 Twitter에서 되돌아오는 결과 수를 줄일 수
있다. 모바일 웹 애플리케이션을 위해 서버 호출을 최적화할 수 있을 때마다 느린
모바일 네트워크에 대한 사용자 경험을 실제로 향상시킬 수 있다. 이제 loadLocal에
대해 자세히 살펴보자.
loadLocal 함수에서는 다시 Listing 2에
저장된 데이터 구조를 사용한다. 먼저 getItem 메소드를 사용하여
키워드와 연관된 색인을 로드한다. 색인이 없는 경우에는 캐시된 트윗도 없기 때문에
표시할 항목이 없으며 쿼리에 대해 최적화를 수행할 수 없다(이를 표시하기 위해 0 값을
리턴함). 색인이 있는 경우에는 색인에서 ID 목록을 가져온다. 이러한 트윗 각각은
로컬로 캐시되므로 다시 getItem 메소드를 사용하여 캐시에서
각각을 로드하기만 하면 된다. 그러면 로드되는 트윗이 정렬된다. addTweetsToResultsTable
함수를 사용하여 트윗을 표시한 후 최신 트윗의 ID를 리턴한다. 이 예제에서는 새 트윗을
가져오는 코드가 UI를 업데이트하는 데 필요한 함수를 직접 호출한다. processResults
함수 전체에서 트윗을 저장하고 검색하는 코드와 트윗을 표시하는 코드 사이의 결합을
작성하기 때문에 여기에 화가 날 수 있다. 스토리지 이벤트를 사용하면 결합이 적은 대체
접근 방식이 제공된다.
이제 예제 애플리케이션을 확장하여 가장 많이 캐시된 결과를 가진 검색 용어 중 상위 10개를 보여 준다. 이는 사용자가 가장 많이 제출하는 검색을 나타낼 수 있다. Listing 4에서는 이 상위 10개를 계산하여 표시하는 함수를 보여 준다.
Listing 4. 상위 10개의 검색 계산하기
function displayStats(){
if (!window.localStorage){ return; }
var i = 0;
var key = "";
var index = [];
var cachedSearches = [];
for (i=0;i<localStorage.length;i++){
key = localStorage.key(i);
if (key.indexOf("index::") == 0){
index = JSON.parse(localStorage.getItem(key));
cachedSearches.push ({keyword: key.slice(7), numResults: index.length});
}
}
cachedSearches.sort(function(a,b){
if (a.numResults == b.numResults){
if (a.keyword.toLowerCase() < b.keyword.toLowerCase()){
return -1;
} else if (a.keyword.toLowerCase() > b.keyword.toLowerCase()){
return 1;
}
return 0;
}
return b.numResults - a.numResults;
}).slice(0,10).forEach(function(search){
var li = document.createElement("li");
var txt = document.createTextNode(search.keyword + " : " + search.numResults);
li.appendChild(txt);
$("stats").appendChild(li);
});
}
|
이 함수는 localStorage API를 보여 준다. localStorage에
저장된 항목의 총 수를 확보한 후 반복하는 것으로 시작한다. 항목이 색인인 경우에는
오브젝트를 구문 분석하고 처리할 데이터(색인과 연관된 키워드와 색인에 있는 트윗의
수)를 표시하는 오브젝트를 작성한다. 이 데이터는 cachedSearches라는
배열에 저장된다. 다음으로 cachedSearches를 정렬하여 가장 많은
결과가 포함된 검색을 처음에 둔 후 두 검색에 있는 캐시된 결과의 수가 동일한 경우 대소문자를
구분하지 않는 영문자순 정렬을 사용한다. 그런 다음 상위 10개의 검색을 가져온 후 각 검색에 대해
HTML을 작성하여 정렬된 목록에 추가한다. Listing 5와 같이 페이지가
처음으로 로드될 때 이 함수를 호출하자.
Listing 5. 페이지 초기화하기
window.onload = function() {
displayStats();
document.body.setAttribute("onstorage", "handleOnStorage();");
}
|
첫 번째 행은 페이지가 로드될 때 Listing 4에 있는 함수를 호출한다.
두 번째 로드는 점점 더 흥미로워지는 부분이다. 여기서 onstorage
이벤트의 이벤트 처리기를 설정한다. 이 이벤트는 localStorage.setItem
함수가 실행을 완료할 때마다 발생한다. 이를 통해 상위 10개의 검색을 다시 계산할 수 있다.
Listing 6에서는 이 이벤트 처리기를 보여 준다.
Listing 6. 스토리지 이벤트 처리기
function handleOnStorage() {
if (window.event && window.event.key.indexOf("index::") == 0){
$("stats").innerHTML = "";
displayStats();
}
}
|
onstorage 이벤트가 창과 연관된다. 이 이벤트에는 key,
oldValue 및 newValue와 같은
유용한 특성이 여럿 있다. 이러한 자체 설명 특성 외에도 url(값을
변경한 페이지의 URL) 및 source(값을 변경한 스크립트가
포함된 창)도 포함되어 있다. 이러한 마지막 두 특성은 사용자에게 여러 창 또는
탭이 있거나 애플리케이션에 대한 iFrames가 여럿 있는 경우 더 유용하며 어느 것도
모바일 애플리케이션에서는 일반적이지 않다. Listing 6으로
돌아가 보면 실제로 필요한 유일한 특성은 key 특성이다.
이 특성을 사용하여 수정된 항목이 색인이었는지 확인한다. 색인인 경우에는 상위
10개의 목록을 다시 설정한 후 displayStats 함수를
다시 호출하여 다시 끌어온다. 이 기법을 사용하면 상위 10개의 목록은 자체적으로
포함되어 있기 때문에 다른 함수에서 이러한 상위 10개 목록에 대해 몰라도 된다는
장점이 있다.
필자는 일반적으로 DOM 스토리지(localStorage 및 sessionStorage 포함)는
광범위하게 채택된 HTML 5 기능이라고 앞서 언급했다.
하지만 스토리지 이벤트는 예외이다. 적어도 데스크탑 브라우저에서는 예외이다.
기사를 작성하는 현재 스토리지 이벤트를 지원하는 유일한 데스크탑 브라우저는 Safari 4+와
Internet Explorer 8+이다. Firefox, Chrome 또는 Opera에서는 지원되지 않는다. 하지만
모바일 환경에서는 상황이 조금 더 낫다. iPhone 및 Android 브라우저의 최신 버전은 스토리지
이벤트를 완전히 지원하며 여기에 제공된 모든 코드가 해당 브라우저에서 완벽하게 실행된다.
개발자는 클라이언트에 갑자기 엄청난 스토리지 공간이 생기면 해방감을 느낄 수 있다. 오랫동안 작업해 온 웹 개발자에게 이것은 수년 동안 바라왔지만 버그가 많은 방법에 의존하지 않는 적절한 방법이 없었던 작업에 대한 문을 여는 것이다. 모바일 개발자에게는 데이터의 로컬 캐싱을 실제로 가능하게 하기 때문에 더 흥미로운 것이다. 애플리케이션 성능의 극적인 향상 외에도 로컬 캐싱은 모바일 웹 애플리케이션의 흥미로운 또다른 새 기능인 오프라인 전환을 가능하게 하는 핵심이다. 이 시리즈의 다음 기사에서는 이 주제에 대해 다룬다.
| 설명 | 이름 | 크기 | 다운로드 방식 |
|---|---|---|---|
| Article source code | local.zip | 8KB | HTTP |
교육
- Creating mobile Web applications with HTML 5, Part 1: Combine HTML 5, geolocation APIs, and Web services to create mobile mashups(Michael Galpin, developerWorks, 2010년 5월): 다양한 웹 서비스에서 사용할 위치 좌표를 찾아서 추적해 보자. 유명한 웹 서비스와 HTML 5를 사용한 위치표시(geolocation) 표준의 다양한 측면을 사용하여 이 시리즈의 Part 1에서 흥미로운 모바일 매시업을 작성해 보자.
- Creating mobile Web applications with HTML 5, Part 3: Make mobile Web applications work offline with HTML 5(Michael Galpin, developerWorks, 2010년 6월): 인터넷 연결 여부와 관계없이 애플리케이션이 작동할 수 있도록 하고 애플리케이션이 온라인과 오프라인 사이에서 전환되는 시기를 발견하는 방법에 대해 살펴보자.
- 모바일 웹용 Ajax 애플리케이션 작성하기(Michael Galpin, developerWorks, 2010년 3월): 모바일 웹 애플리케이션의 주요 부분인 Ajax의 사용 방법에 대해 살펴보자.
- HTML 5에 추가된 새로운 요소 (한글)(Elliotte Rusty Harold, developerWorks, 2007년 8월): HTML 5는 단지 JavaScript에 관한 것이 아니다. HTML 5의 새로운 마크업 중 일부에 대해 읽어보자.
- Android와 iPhone의 브라우저 전쟁, Part 1: 새로운 돌파구, WebKit(Frank Ableson, developerWorks, 2009년 12월): HTML 5를 사용하여 모바일 웹 애플리케이션을 개발하는 것을 좋아하지만 개발한 애플리케이션이 여전히 iPhone 앱 스토어와 Android 마켓에 있기를 원하나요? 두 개의 기사로 구성된 이 시리즈의 Part 1에서는
이러한 두 가지 시장에서 살아남는 방법을 확인할 수 있다.
- Invisible Flash: Enhance Web applications by secretly using the Flash player(Michael Galpin, developerWorks, 2010년 2월): 수년 동안 많은 웹 개발자들이 비슷한 기능을 얻기 위해 플래시를 사용해 왔다. 이 기사에서 동일한 작업을 수행하는 방법에 대해 살펴보자.
- Dive Into HTML 5: 이 무료 서적에서 HTML 5 감지 기술과 HTML 5의 다양한 기능을 살펴볼 수 있다.
- Safari Reference Library: iPhone용 웹 애플리케이션을 개발하는 경우에는 이 참고자료를 가까운 곳에 두자.
- W3C HTML 5 스펙(Working Draft, 2010년 3월): HTML 5에 대한 이 명확한 소스를 살펴보자.
- 필자의 더 많은 기사(Michael Galpin, developerWorks, 2006년 4월 - 현재): XML, Eclipse, Apache Geronimo, Ajax, 추가 Google API 및 기타 기술에 대한 기사를 읽어보자.
- My developerWorks: developerWorks와 관련된 경험을 개인화할 수 있다.
- IBM XML 인증: XML 및 관련 기술에 대한 IBM 인증 개발자가 되는 방법을 찾아볼 수 있다.
- XML 기술 자료: developerWorks XML 영역에서 다양한 기술 관련 기사와 팁, 튜토리얼, 표준 및 IBM Redbook을 볼 수 있다.
- developerWorks 기술 행사 및 웹 캐스트: 이들 세션에 참가하여 최신 기술에 대한 정보를 얻을 수 있다.
- Twitter의 developerWorks 페이지: 오늘 가입하여 developerWorks 트윗을 팔로우하자.
- developerWorks
팟캐스트: 소프트웨어 개발자의 흥미로운 인터뷰와 토론을 확인할 수 있다.
제품 및 기술 얻기
- Modernizr 프로젝트: localStorage, Web Workers, applicationCache 등을 포함하여 HTML 5 기능을 확인할 수 있는 광범위한 유틸리티를 살펴보자.
- Android Developers 웹 사이트: Android SDK를 다운로드하고 API 참조에 액세스하고 Android에 관한 최신 뉴스를 읽어보자.
- iPhone SDK: 최신 iPhone SDK를 확보하여 iPad, iPhone 및 iPod Touch 애플리케이션을 개발해 보자.
- Android Open Source Project: Android 모바일 플랫폼의 오픈 소스 코드를 확보하자.
- Google App Engine SDK: Java™ 및 Python 도구를 다운로드하여 Google을 사용하여 확장 가능한 웹 애플리케이션을 빌드해 보자.
- json.org 웹 사이트의 JSON 오브젝트: 기본적으로 사용된 것과 동일한 JSON 오브젝트를 확보하자.
- IBM 제품 평가판: IBM SQA Sandbox의 온라인 시험판을 다운로드하거나 살펴보고 DB2®,
Lotus®, Rational®, Tivoli® 및
WebSphere®.
토론
- XML 영역 토론 포럼: 다양한 XML 관련 토론에 참여할 수 있다.
- developerWorks 포럼 & 블로그를 통해 developerWorks 커뮤니티에 참여하자.
