모바일 웹 디버깅 툴 - Weinre

국내 모바일 브라우저 시장 점유율은 2011년 12월 현재 Webkit 계열이 99% 이상의 점유율을 가지고 있다(Statcounter 기준, Android, iPhone, iPod Touch, Dolfin 을 합한 수치).

하지만 Webkit 계열의 브라우저로 천하통일되었더라도 모바일 사이트를 구축하는 것은 여전히 쉽지 않은 일이다.

단말기가 다양할 뿐 아니라 단말기마다 사용된 웹킷 브라우저 버전이 각각 다르고, 단말기에 적용된 OS 버전에 따라서도 다르다. 심지어는 제조사의 커스터마이징이 이루어진 경우도 심심치 않게 볼 수 있다. 같은 회사에서 나온 라인업(갤럭시 S, 갤럭시 K 등) 에서도 다르게 동작하는 경우마저 있다. 

일반적인 모바일 사이트를 개발은 사파리, 크롬과 같은 PC용 웹킷 브라우저에서 이루어지고, 이후 모바일 브라우저에서 확인과정을 거치는 경우가 많다.

하지만 모바일 브라우저에서 명백히 잘못된 작동을 하는 경우에도 Firebug나 Web Inspector 등 디버깅 툴을 내장하고 있지 않으므로 정상 동작하는 코드로 되돌려내는 것은 결국 삽질을 통할 수 밖에 없다. Developer Toolbar가 지원되지 않는 IE6 대응 사이트를 만드는 것과 별반 다르지 않다.

Weinre 는 내장 디버깅 툴이 없는 모바일 브라우저를 위한 원격 디버깅 툴이다. Webkit 계열의 개발자 도구인 Web Inspector 를 사용할 수 있도록 해준다.

Weinre Elements Panel

모바일에서도 위와 같은 디버깅이 가능해진다!

 

Weinre 개요

처음보면 어떻게 발음해야할지 갸우뚱한 이 프로그램은 포도주 양조장이라는 '와이너리'라 부른다. Patrick Mueller http://muellerware.org/ 가 만든 이 프로젝트는 웹킷의 원격 디버깅 프로토콜 http://www.webkit.org/blog/1620/webkit-remote-debugging/ 을 이용해 개발되었고 하이브리드 앱 개발 도구인 Apache Callback(Phonegap) 의 서브 프로젝트이다.

Weinre를 통한 디버깅은 세가지 파트로 나뉜다.

  • 서버(Server)
    • java기반(Jetty)의 http 서버이다.
  • 대상(Target)
    • 디버깅할 모바일 디바이스 브라우저. 웹킷 계열만 지원한다.
  • 클라이언트(Client)
    • Safari, Chrome 등에 내장된 Web Inspector와 비슷한 외관의 클라이언트 페이지. -webkit- prefix 를 통한 CSS3만 지원하므로 웹킷 브라우저가 필수.

 

설치 방법

서버

서버는 프로젝트 홈페이지에서 jar 파일을 다운로드 받아 실행한다.

$ java -jar weinre.jar

옵션설명

--help (or -? or -h)

이 도움말 화면을 보여줌.

 

--httpPort [포트번호]

HTTP 서버가 동작할 포트 번호.

기본값 : 8080

 

--boundHost [hostname | ip address | -all-]

서버에 바인딩할 아이피 주소

기본값 : localhost

 

기본값인 localhost 로는 다른 기기에서 접속할 수 없다. 따라서 다른 기기에서 접속하기 위해서는 다른 호스트네임이나 IP 주소를 바인딩해야한다. -all- 을 사용하면 이 기기로 연결가능한 모든 인터페이스를 사용할 수 있다.

 

맥이나 라눅스에서는 ifconfig 을 사용하고, 윈도우에서는 ipconfig 를 사용해 ip 주소를 얻어올 수 있다.

 

--verbose [true | false]

stdout 을 통해 소소한 것까지 출력함. 

기본값: false

 

--reuseAddr [true | false]

Jetty 의 reuseAddr 옵션을 설정함. 

기본값: false

 서버를 주기적으로 재시작할 때 필요할 수 있다.

 

--readTimeout [seconds]

기본값: 5 

--deathTimeout [seconds]

기본값: 3 * readTimeout

 

대상

대상은 디버깅용 JS파일을 임포트 한다. 이 디버깅용 파일은 HTML 소스에 고정적으로 로드하거나, 북마클릿을 통해 동적으로 로드할 수 있다.

<script src="http://a.b.c:8080/target/target-script-min.js#anonymous"></script>

* 여기서 a.b.c:8080 은 설치된 서버의 아이피/도메인을 의미함.

 

클라이언트

이제 사용할 준비가 완료 되었다. 브라우저를 통해 http://a.b.c:8080/client 에 접속하면 아래와 같은 Web Inspector를 볼 수 있다. 

Weinre Remote Debug Client

Weinre Elements Panel

 

활용

아이디를 이용한 여러 프로젝트 분기

스크립트 URL : http://a.b.c:8080/target/target-script-min.js#anonymous

클라이언트 접속 URL: http://a.b.c:8080/client/#anonymous

에서 마지막의 #anonymous 부분을 변경해 서버 하나에 프로젝트마다 또는 각 사용자마다 아이디를 줄 수 있다.

북마클릿의 활용

특히 긴급한 상황에서 북마클릿을 활용해 스크립트를 로딩하면 디버그가 가능하다. 


출처 - http://elegantcoder.com/weinre





하이브리드 앱 개발을 할때 UIWebView에서 Javascript 디버깅하는 방법과 Insepector 사용

2012/04/02 15:13



이전에는 Native 앱 (순수 Objective-C와 C 기반 라이브러리를 이용하여 만든 앱)을 주로 만들었다면, 최근 HTML5 앱 기술이 발달하고 자료가 많아지면서 Hybrid 앱 (웹 개발 기술과 클라이언트 개발 기술을 접목하여 개발하는 앱)이 큰 인기를 얻고 있다. 실제 앱을 개발하면서 느낀 것인데 각각의 장점을 충분히 살릴 수 있으면 어렵게 구현할수 밖에 없는 코드를 아주 효과적으로 개발할 수 있기도 한다. HTML은 Native 앱과 랄리 UIWebView 안에서 HTML, Javascript, CSS로 개발이 되어 렌더링되기 때문에 순수 Objective-C로 개발한 것 보다는 속도가 느리지만 유연하고 상대적으로 개발하기 편리한 언어로 C의 복잡함을 단순하게 구현할 수 있다. 또한 웹 언어로(HTML, Javascript, CSS)로 개발된 코드는 다른 디바이스에서 재사용성이 가능하기 때문에 이론적으로는 코드 재사용성의 장점도 가지고 있다. 왜 이론적이라고 이야기하냐면 사실 각각 디바이스마다 가지고 있는 내장 브라우저 앤진의 해석능력이 다르기 때문에 100% 호환된다고는 말할 수 없기 때문이다. 하지만 Objective-C를 Java로 구현하는 것 보다 상대적으로 매우 완벽하게 재사용성이 가능한것은 사실이다. 

웹언어는 표현력과 개발속도를 빠르게 할 수는 있을지 모르나 물리적인 제약이나 빠른 성능을 요구하는 연산에는 Native 코드보다 비교적 한계가 있기 때문에 그런 작업은 Native 코드에게 맡기기로 한다. 이러한 이유에서 순수 웹 기술로 개발하거나 클라이언트 개발 기술로 개발하는 것 보다 서로의 장점을 접목해서 개발하려는 시도가 많이 일어나고 있다. 이전에 소개한 아이폰 앱을 개발할 때  iPhone에서 하이브리드 앱 개발을 위해 Javascript와 Objective-C의 상호 호출하는 방법에 대한 글을 역시 그러한 방법중에 한가지로 사용이 된다.

그런데 실제 Hybrid 앱을 개발하려면 두가지 환경에서 개발을 해야한다. 하나는 웹기반이고 하나는 클라이언트 기반이다. 더 쉽게 말하면 하나는 웹브라우저에서 실행되는 결과를 확인해야하고 하나는 Xcode에서 결과를 확인해야한다는 이야기다. Xcode는 LLVM의 훌륭한 컴파일 때문에 에러라던지 디버깅을 매우 편리하게 할 수 있다. 하지만 UIWebView 안에 들어있는 코드들에 대한 디버깅은 전혀할 수 가 없다.

웹 프로그램을 개발할때 웹 개발자들은 웹 화면에 나타나는 코드를 분석하거나 브라우저 앤진에서 연산되는 코드들을 디버깅한다.  이 때 사용되는 대표적인 툴이 Firebug나 Webkit Inspector 가 있다. Firebug는 Firefox 브라우저에서 동작하는 웹 개발툴로 현재의 Firefox의 명성을 유지하는데 가장 큰 역활을한 플러그인이 아닌가 생각이 든다. 그리고 오픈소스 WebKit 기반의 브라우저는 Inspector라는 툴로 Firefox의 Firebug과 동일한 작업을 할 수 있다. 현재 구글의 Chrome과 애플의 Safari는 WebKit 기반의 브라우저로 개발되어있고 두 브라우저 모두 Inspector를 사용할 수 있다. 아래는 지금 글을 작성하는 이 화면을 Web Inspector의 화면으로 열어본 것이다. Eelements는 HTML의 DOM의 구조를 보여주고 Resources는 웹을 표현하는데 사용되는 리소스들을 보여준다. 그리고 Network는 리소스들이 사용자에게 표현되기 까지의 시간을 보여준다. Scripts는 javascript 코드를 보거나 디버깅(브레이크 포인트 등)을 할 수 있는 메뉴이다. 그리고 console은 Javascript가 동작하는 것을 확인하거나 변수의 내용을 출력시킬 수 있는 콘솔이다. (다른 메뉴들도 각각 기능이 있지만 이 포스트에서 소개는 하지 않겠다.)

이렇게 웹을 개발할때는 Web Inspector를 사용할 수 있으니가 UIWebView에 이것을 이용하면 될거라는 생각을 하고 찾아보기 시작했다. 하지만 UIWebView는 Safari 브라우저가 아니다. UIWebView는 iOS SDK의 UIKit에 포함된 웹뷰이기 때문에서 Web Inspector를 바로 실행시킬 수 없다. 더구나 Web Inspector는 Mac 에 포함된 기능이지 아이폰 자체에 포함된 기능은 아니기 때문이다. 그래서 조사하던 도중에 @kenu0000 @iolothebard 께서 조언을 해주신 weinre를 사용할 수 있게 되었다. (다시 한번 링크와 조언 감사드립니다) 아래는 slideshare에 좋은 자료가 있어서 첨부한다. 

weinre 의 사이트는 http://phonegap.github.com/weinre/ 이다. 그리고 다음 그림은 weinre 첫 화면에 나타내는 그림인데, 아이폰 시뮬레이터 속에 있는 웹페이지의 내용을 맥에 있는 Safari 브라우저에서 디버깅을 하는 화면이다. 다시 말하면 로컬 PC에 디버깅 서버를 동작시키고 그 서버에서 분석한 결과를 웹으로 확인하는 방법이다.

하지만 위에 슬라이드나 그림들은 모두 시뮬레이터의 브라우저에서 코드를 실행한 결과를 확인하는 것인다. 우리의 목적은 UIWebView 안에 Hybrid 앱을 만들기 위한 코드를 작성하면서 디버깅을 하고 싶은 것이다. 그래서 예제를 준비 했다. 

우선 weinre를 다운받는다. 맥 버전을 받아도 좋고 jar 버전을 받아도 괜찮다. 다음 링크로 가서 zip 파일을 다운 받아서 unzip을 한다.

https://github.com/callback/callback-weinre/archives/master 

맥 버전을 사용한다고 가정하고 weinre-mac을 다운받아서 실행한다. 실행하면 Safari에서 Web Inspector과 거의 동일한 메뉴들이 보일 것이다. 만약 jar 버전을 다운 받으면 아래 명령어로 실행하고 http://localhost:8080/client 로 브라우저를 열어서 확인할 수 있다. boundHosts 에는 자동으로 host가 탐색되는데 IP 정보가 나와서 잘라 내었다. 원래는 IP 주소 목록이 나온다.

java -jar weinre.jar --boundHost -all-




Single View Application을 하나 만들고 UIWebView를 추가하도록 하자. 그리고 Web 이라는 폴더 안에 index.html 파일을 만들고 프로젝트에 추가를 하는데 파을을 복사하지 않고 Xcode 프로젝트 내에서 참조만 할 수 있게 다음과 같이 설정한다.

index.html에는 다음과 같은 코드를 입력한다. weinre 서버가 디폴트로 8080 포트로 운영되기 때문에 localhost 의 8080 으로 접근해서 디버깅을 하기 위한 javascript를 받아온다. 그리고 우리가 테스트할 메소드를 하나 만들었다.

<!DOCTYPE html>

<html>

<head>

    <meta charset="utf-8"/>

    <title>UIWebView Debugging Tutotial</title>

    <meta name="viewport" content="initial-scale=1.0,user-scalable=no">

    

    <script src="http://localhost:8080/target/target-script-min.js"></script>

    <script type="text/javascript">

        function callPrint() {

            console.log('first');

            console.log('second');

        }

    </script>

</head>

<body>

    <button onclick="callPrint();">call print</button>

</body>

</html>



viewController에는 물러적으로 만든 index.html 파일을 가져오도록 다음 코드를 추가한다. 위에 것은 .h 파일이고 밑에 것은 .m 파일이다.

//  SFViewController.h

//  SaltfactoryiOSTutorial

//

//  Created by SungKwang Song on 4/2/12.

//  Copyright (c) 2012 saltfactory@gmail.com. All rights reserved.

//


#import <UIKit/UIKit.h>


@interface SFViewController : UIViewController


@property (strongnonatomicIBOutlet UIWebView *appWebView;

@end


//

//  SFViewController.m

//  SaltfactoryiOSTutorial

//

//  Created by SungKwang Song on 4/2/12.

//  Copyright (c) 2012 saltfactory@gmail.com. All rights reserved.

//


#import "SFViewController.h"


@interface SFViewController ()


@end


@implementation SFViewController

@synthesize appWebView;


- (NSString *) getFilePath

{

    return [[NSBundle mainBundlepathForResource:@"index" ofType:@"html" inDirectory:@"Web"];

}


- (void)viewDidLoad

{

    [super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

    NSURL *uri = [NSURL fileURLWithPath:[self getFilePath]];

    [appWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[[[uri absoluteStringstringByAppendingString@"?"]stringByAppendingString: [uri absoluteString]]]]];

}


- (void)viewDidUnload

{

    [self setAppWebView:nil];

    [super viewDidUnload];

    // Release any retained subviews of the main view.

}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

{

    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);

}


@end

실행시키면 간단한 버턴만 눈에 보일 뿐 아무러 동작을 하지 않는다.


우리는 프로젝트를 만들고 UIWebView를 추가하기 전에 UIWebView를 디버깅하기 위해서 weinre를 실행하였었다. 그 화면으로 돌아가보면 Targets에 시뮬레이터가 감지되고 번들 밑에 Web 폴더 안의 index.html을 타게팅하는 정보를 얻게 된다. 

Inspector의 Elements를 열어서 특정 DOM을 선택하면 UIWebView 안에서 해당되는 엘리먼트가 선택되는 것을 확인할 수도 있다.


그리고 버턴을 눌렀을때 console에 메세지를 출력하게 함수를 만들었는데 버턴을 눌러보면 콘솔에 로그가 찍히는 것을 확인할 수 있다.

뿐만아니라 만약에 Javascript 에서 에러가 발생하면 콘솔에서 에러 메세지를 확인할 수 있다. 에러를 발생시키기 위해서 일부러 console.log를 consol.log로 만들어서 테스트 하였다. Can't find variable: consol 이라는 에러가 나타난다.

자바스크립트 코드만 확인할 수 있는 것이 아니라 Elements 창에서 실시간으로 HTML 코드를 변경할 수 있고 CSS를 변경하여 확인할수도 있다. 아래는 버턴의 글자 크기를 Inspector에서 변경하여 바로 확인한 결과 이다.

이제 하이브리드 앱을 개발할 때 UIWebView 안에 HTML, CSS, Javascript의 값을 확인하거나 변경할 수 있게 되었다. 다만 개발자들에게 좀 아쉬운 부분은 javascript의 변수들이 어떻게 변화되는지를 console.log로 계속 확인해야한다면 약간 부담스럽다. 그래서 개발자들은 breakpoint 기능이 있기를 원한다. 하지만 아쉽게도 weinre에서는 Web Inspector에서 제공하는 Scripts 메뉴가 없어서 javasctipt 디버깅을 하기에 약간 아쉬운 감이 있다. 이럴 경우에는 애플에서만 사용하는 private API를 이용하여 아쉬운 부분을 해결할 수 있다. 하지만 지금 소개하는 것은 private API 이기 때문에 이 코드를 남겨두고 앱스토어에 등록하면 reject를 당하게 된다. 앱스토어에 등록할때는 반드시 이 코드를 제외시켜야 함을 기억하자.

AppDelegate.m 파일에서 앱이 구동되면 호출되는 application:didFinishLaunchingWithOptions: 메소드에 다음 코드를 추가하는 것이다.

[NSClassFromString(@"WebView") performSelector:@selector(_enableRemoteInspector)];

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

    [NSClassFromString(@"WebView"performSelector:@selector(_enableRemoteInspector)];

    

    self.window = [[UIWindow allocinitWithFrame:[[UIScreen mainScreenbounds]];

    // Override point for customization after application launch.

    self.viewController = [[SFViewController allocinitWithNibName:@"SFViewController" bundle:nil];

    self.window.rootViewController = self.viewController;

    [self.window makeKeyAndVisible];

    return YES;

}

Javascript의 변수의 값이 변화되는 것을 디버깅하기 위해서 index.html의 코드를 다음과 같이 변경한다.

<!DOCTYPE html>

<html>

<head>

    <meta charset="utf-8"/>

    <title>UIWebView Debugging Tutotial</title>

    <meta name="viewport" content="initial-scale=1.0,user-scalable=no">

    

    <script src="http://localhost:8080/target/target-script-min.js"></script>

    <script type="text/javascript">

        function callPrint(message) {

            console.log(message);

            console.log('second');

        }

    </script>

</head>

<body>

    <button onclick="callPrint('saltfactory');">call print</button>

</body>

</html>

이제 다시 Build & Run을 하여 시뮬레이터를 실행시킨다. 그리고 http://localhost:9999 로 Safari 브라우저에서 접속한다. weinre를 사용할 때와 비슷한 것이 나오며 디버깅이 시작된다. 


링크를 클릭해서 들어가서  Scripts 메뉴에서 breakpoint를 linenumber가 나오는 패널에다 추가할 수 있고 실행하여 breakpoint에 걸렸을 때 변수에 어떤 값이 들어있는지 변수 값의 변화를 확인할 수 있다.

Hybrid 앱을 개발하기 위해서는 UIWebView라는 객체의 사용은 필수조건이 된다. 물론 html 파일을 로컬 에디터에서 작성하고 Safari  브라우저에서 작업하여 최종 결과물을 Xcode 프로젝트에 넣어서 활용하기도 하지만 Safari 브라우저와 UIWebView가 100% 똑같이 해석되지 않는다. 더구나 Hybrid 앱을 작성하면 Native 코드와 데이터를 주고 받게 되는데 이것을 동작시키면서 디버깅하는 방법이 필요한데 이때 반드시 UIWebView 상에서 디버깅이 이루어져야한다. 이 때 weinre와 WebView의 private API가 디버깅을 하는데 많은 도움이 될거라 예상된다. 


참고

1. http://phonegap.github.com/weinre/Installing.html

2. http://atnan.com/blog/2011/11/17/enabling-remote-debugging-via-private-apis-in-mobile-safari/

3. @kenu0000 @iolothebard  조언 감사합니다.


출처 - http://blog.saltfactory.net/113




Posted by linuxism
,


자바스크립트 모바일 프레임웍 하면 가장 먼저 관심을 가지게되는 것은 무엇일까요? 대부분의 분들이 아마도 얼마나 멋지고 많은 UI를 제공하는지가 가장 관심의 대상일 것입니다. 이것은 매우 자연스러운 결과라고 생각되는데 가장 먼저 사람들에게 보여지는 부분이기 때문입니다. 일반적인 사용자는 내부 구조나 동작 방식에 대해서는 별 관심이 없고 관심 가질 이유도 없기 때문이겠죠. 얼마나 이쁘고 화려하고 멋진 UI 로 내가 원하는 컨텐츠를 제공하는가가 일반 사용자에게는 최고의 관심거리이고 사용자를 만족시켜야하는 개발자는 우선적으로 프레임웍을 바라볼 때 기본 제공되는 UI에 관심을 가질 수 밖에 없습니다.


이런 저런 이유로 UI 는 매우 중요하면서도 늘 이슈의 중심에 있습니다. 이번 강좌에서는 바로 jQueryMobile 이 기본 제공하는 UI 부분에 대해서 알아보도록 하겠습니다.


UI 는 다뤄야하는 분량이 매우 많기 때문에 하나의 강좌에서 모두 다루지 못하고 몇번에 걸쳐 나누어 연재될 예정입니다. 강좌를 올리는 기본 단위를 일주일로 하고있지만 UI 부분은 조금 더 자주 강좌를 올릴 생각입니다. 



ListView



화면의 크기가 제한적인 모바일 앱의 UI 에서 가장 많이 사용하는 UI 컨트롤은 ListView일 것입니다. 매우 일반적이고 중요한 컨트롤인 만큼 쓰임도 다양하고 구성 방법도 다양합니다. 먼저 가장 기본적인 형태부터 차근 차근 익혀나가보도록 하겠습니다.



ListView - 기본형 / Read-only list



listview_01.gif 



ListView 는 기본적으로 목록 컨텐츠 입니다. 그렇기 때문에 HTML 마크업중 목록을 표현하는 <UL> <OL> 태그를 사용합니다. 물론 data-role 속성을 지정해 줘야 jQueryMobile 이 지원하는 ListView 로 랜더링되어서 표시되겠지요? 


첫번째 예제를 보면 <UL> 태그에 data-role 속성을 listview로 지정한 것을 보실 수 있습니다. 사실 data-role="listview" 속성을 제외한다면 일반적인 <UL> 마크업과 완전히 100% 동일합니다. 결과적으로 오른쪽의 모양으로 랜더링되어 표시됩니다. 가장 간단한 형태의 ListView 이고 jQueryMobile 에서는 좀더 특별하게 클릭되어 동작되지 않는 ListView 라하여 Read-only list 라고 부릅니다.



ListView - Inset



listview_02.gif 


기본형 ListView 는 좌측 여백이 전혀 없이 표시됩니다. 하지만 우리가 일반적으로 봐왔던 ListView는 상하좌우에 약간의 여백이 존재하는 형태였습니다. 더불어 리스트목록 모서리느 둥근 모양을 취하고 있죠. 이런 모양은 어떻게 만들 수 있을까요? 


두번째 예제를 보시면 간단히 이런 형태를 만들 수 있습니다. <UL> 태그에 data-inset 속성을 추가해줌으로서 가능합니다. 지정하지 않았을 경우 기본값은 false 이고 위의 예제처럼 true 로 기본값을 바꿔주면 자주 접하던 모서리가 둥근 모양을하고 사방에 약간의 여백을 가진 ListView 가 만들어집니다. 




ListView - Sub header or Divider



listview_03.gif 


ListView 목록중 특정 항목은 대표성을 부여하고 다르게 표시하고 싶다면 어떻게 해야할까요? 대표적인 형태가 연락처 목록인데요 'ㄱ' 으로 시작하는 연락처, 'ㄴ' 으로 시작하는 연락처등으로 구분되는 형태입니다. 예제와 같이 'Apple' 항목은 푸른색으로 다르게 표시됩니다. 


지금까지 <UL> 태그에 속성을 부여했다면 이번에는 개별 항목별로 속성을 부여해야하기 때문에 <LI> 태그에 속성을 부여해야합니다. 예제와 같이 data-role 속성에 list-divider 값을 줌으로서 부타이틀 또는 분할자 (Divider) 아이템을 지정할 수 있습니다. 이 속성을 이용하면 연락처 같은 형태의 목록을 만들 수 도 있고 또는 많은 목록을 그룹화하여 그룹의 타이틀 역할로 만들 수 도 있습니다. 



ListView - Link


listview_04.gif 


지금까지의 예제 ListView 는 모두 Read-only 였습니다. 즉 클릭해도 아무런 변화가 없는 목록이었는데요 목록을 클릭해서 다음 화면으로 이동하려면 어떻게 하는지 알아보겠습니다. 


화면을 전환하기 위해서 사용하는 일반적인 방법으로 <A> 태그를 사용합니다. <LI> 태그 안쪽의 컨텐츠를 <A> 태그로 링크를 만들어주면 아주 간단하게 클릭되어 화면전환할 수 있는 ListView 가됩니다. 또한 이런 항목은 예제의 결과에서 보시는 것 처럼 오른쪽 끝단에 작은 화살표 아이콘이 표시되어 클릭되지 않는 항목과 구분해줍니다.


그리고 읽기전용과는 다르게 상하 여백이 생겨 약간 더 폭이 넓게 랜더링됩니다. 



ListView - 목록에 일련번호 넣기


listview_05.gif 


이번 예제는 잘 쓰이지는 않지만 그래도 간혹 필요한 경우가 있는 기능입니다. ListView 항목에 일련번호를 표시하려면 어떻게 해야할까요? jQueryMobile 은 아주 쉬운 방법을 제공해줍니다. 눈치 빠른 분이라면 벌써 아실텐데, ListView 를 구성하는 <UL> 태그와 <OL> 태그의 성격을 아신다면 쉽게 사용하실 수 있습니다.


<UL>은 순서없는 목록태그, <OL>은 순서있는 목록태그입니다. 즉 <UL> 을 <OL> 로 바꿔만주면 jQueryMobile 은 ListView 각 항목의 <LI> 항목에 예제 결과와 같이 일련 번호를 표시해줍니다. 


일련 번호를 표시하기 위해 컨텐츠 자체에 번호를 넣지 않아도됩니다.




ListView - Split


listview_06.gif 


이번에는 조금 더 복잡한 형태의 ListView 를 만들어보도록 하겠습니다. 복잡하다고 해도 구성 원리만 안다면 복잡한 구성도 간단하게 만들 수 있습니다. 예제 결과와 같은 ListView 는 어떤 원리로 만들어지는 것일까요? 먼저 항목의 구성 요소를 먼저 보도록 하겠습니다.


Google 내용을 표시하는 항목은 세개의 구성요소로 이루어져있습니다. Google 이라는 단어와 Google inc 라는 단어 그리고 별표 아이콘입니다. 마크업 코드를 보면 <LI> 태그에 모두 차례로 마크업되어있습니다. 


자 그럼 어떤 방식으로 각각 결과처럼 랜더링 될까요? 원리는 매우 간단합니다. <LI> 태그 내에는 두개의 <A> 태그가 올 수 있습니다. 그리고 각각 첫번째 나타는 <A> 태그는 왼쪽에 표시되고 - 결과화면의 Google - 두번째 <A> 태그는 오른쪽에 표시됩니다. 아주 간단하죠? 그리고 링크가 아닌 일반 텍스트는 첫번째 <A> 링크 아래에 줄바꿈 되어 표시됩니다. 예제에서는 <P> 태그내의 텍스트가 되겠습니다. 


그런데 이상한 점이 있습니다. 두번째 <A> 링크의 텍스트는 분명 Google 인데 결과 화면에는 별표 아이콘으로 표시되었습니다. 무슨 일이 벌어진걸까요? 해답은 <UL> 태그의 새로운 속성을 보면 알 수 있습니다.


<UL> 태그에는 두개의 속성이 추가되어있는데 각각 data-split-icon 속성과 data-split-theme 속성입니다. Split ListView 는 두번째 <A> 링크를 항상 아이콘으로 랜더링 하게 되어있습니다. 따라서 두번째  <A> 링크의 텍스트는 text-indent 속성에 마이너스 값이 지정되어 화면에 표시되지 않습니다. 대신 data-split-icon 에 지정된 아이콘이 표시됩니다. 아이콘 값은 jQueryMobile 이 기본 지원되는 많은 아이콘이 있는데 이는 테마 강좌를 할 때 자세히 설명하도록 하겠습니다. data-split-theme 는 테마를 지정합니다. 간단하게 a, b, c, d, e 다섯가지 테마를 지정할 수 있는데 각각 다른 컬러 값을 가집니다. 이 또한 테마 강좌에서 자세히 다뤄보도록 하겠습니다.



ListView - Count


listview_07.gif 


메일함을 보여주는 앱에서 흔히 볼 수 있는 숫자가 표시된 ListView를 만들어보도록 하겠습니다. 역시나 아주 간단하게 만들 수 있는데요 예제와 같이 <span> 태그를 추가하고 <span> 태그의 class 속성에 ui-li-count 를 지정해주면 됩니다. ui-li-count 스타일은 jQueryMobile 이 제공하는 스타일 입니다.



ListView - Aside text


listview_08.gif 


오른쪽에 부가정보를 표시해야할 때가 있습니다. 이 경우도 예제와 같이 간단하게 처리할 수 있습니다. class 속성에 ui-li-aside 를 지정해주면 됩니다. 그러면 예제 결과화면처럼 표시됩니다. 이때 주목해 봐야 할 것이 있는데 <LI> 태그 내의 컨텐츠가 각각 어느 위치에 랜더링 되는가 입니다. 지금까지 설명한 각 각의 항목들을 유심히 지켜보신 분들은 쉽게 아실 수 있으리라고 판단되어 자세한 설명은 하지 않도록 하겠습니다.



ListView - icon


listview_09.gif 


좀더 모양을 꾸미기위해 아이콘 같은 이미지를 삽입하려면 어떻게 해야할까요? 예제와 같이 <IMG> 태그를 삽입해서 아이콘을 삽입할 수 있습니다. 그런데 반드시 <IMG> 태그의 class 속성에 ui-li-icon 값을 지정해줘야합니다. 왜 그럴까요? 헤더 텍스트의 위치정렬 때문에 그렇습니다. 아이콘은 기본적으로 20픽셀 이하의 작은 크기인데 텍스트는 이보다 더 큰 경우가 많아서 정확히 한줄로 랜더링 되기 힘듭니다. 따라서 ui-li-icon 이라고 명시해 줌으로서 정렬을 보다 정교하게 할 수 있습니다.


이와는 반대로 아이콘이 아닌 섬네일 크기의 큰 이미지를 삽입할 경우는 ui-li-icon 속성을 주면 안됩니다. 이 경우는 그냥  <IMG> 태그만을 삽입해서 해결할 수 있습니다.


출처 - http://www.webdevmobile.com/xe/index.php?mid=lectureboard&page=2&document_srl=22972









Posted by linuxism
,


[HTML5] GEOLOCATION

POSTED IN 모바일, 그리고 웹(WEB)/HTML5 // POSTED AT 2010/08/09 15:36

HTML 5 는 위치 정보와 관련한 Geolocation 스펙을 포함하고 있다
(엄밀히 말하자면 이 스펙은 HTML Working Group 과 분리되어 있는  Geolocation Working Group
에 의해 표준화가 진행되고 있다고 한다)

Geolocatoin API를 이용하면 
현재 웹 페이지가 실행되는 단말의 위도, 경도와 같은 위치 정보를 얻어 올 수 있다

Geolocation 지원 브라우저 현황
현재 IE를 제외한 대부분의 최신 웹브라우저에서 Geolocation을 지원하고 있다
아래 표는 http://caniuse.com/ 에서 제공하는 브라우저(버전)별 Geolocation 지원 표이다
(데스크탑 용 브라우저 기준이다)

MS IE 9 가 unknown 이라고 되어 있지만 아마 지원하게 될 것이다.
MS 가 HTML 5 지원을 강력히 표명하고 있기 때문이다

 




그리고 아래는 http://diveintohtml5.org/geolocation.html  에서 발췌한 브라우저 지원현황이다
아래 표를 보면 아이폰이나 안드로이드와 같은 모바일 환경에서도Geolocation을 지원한다고 나와있다
Geolocation 자체가 장치의 위치정보를 이용하는 것이기에 모바일 장치의 지원은 더 자연스럽다
(참고: 오페라 10.6 이후 지원됨)




위치 정보는 사용자 동의가 있어야 한다
웹 응용프로그램이 나의 정보를 이렇게 쉽게 얻어 갈 수 있는 것인가?
만일 그렇다면 굉장한 사회적(?) 문제가 될 것이다
따라서 사용자의 위치 정보는 반드시 사용자의 허가를 받아서 수집할 수 있도록 되어있다

브라우저에서 Geolotion API를 이용해서 위치 정보를 액세스 하려고 하면,
아래 보는 바와같이 사전 동의를 구하게 된다.(파이어폭스 예) 
만일 동의를 하지 않게 되면 나의 위치정보를 웹 응용프로그램이 알 수 없게 되는 것이다




Geolocation 데모 만들어 보기
웹 페이지에서 Geolocation API 를 이용해 위치정보를 액세스 하는 것은 매우 쉽다
내부적으로 장치가 제공해 주는 위치정보를 어떤 식으로 액세스 하는지 전혀 몰라도
가져다 쓰는 것은 아주 쉽다

navigator 에 정의된 geolocatoin 객체의 getCurrentPosition 메서드를 이용하여
콜백 메서드만 정의하면 된다. 아래는 간단한 코드 샘플이다
(위치 정보 확인 작업은  비동기로 이루어진다)

<div id="msg"></div>

<script type="text/javascript">  
  if (!!navigator.geolocation) 
  {
    navigator.geolocation.getCurrentPosition(successCallback,errorCallback);  
  }
  else
  {
    alert("이 브라우저는 Geolocation를 지원하지 않습니다");
  }
    
  function successCallback(position)
  {
    var lat = position.coords.latitude;
    var lng = position.coords.longitude;
    
    document.getElementById("msg").innerHTML = "위도" + lat + ", 경도:"+lng
  }
  
  function errorCallback(error)
  {
    alert(error.message);
  }    
</script>



그리고 이 코드를 파이어폭스에서 실행한 결과 화면이다
(데스크탑 브라우저에서 테스트 해 봤는데, 구글 크롬과 사파리의 경우 지원은 되는데 위도,경도 
 정보가 불러와 지지가 않는다. 파이어폭스와 오페라, 아이폰 사파리에서 정상 동작 확인 함 )



예제를 보면 coords 로 부터 위치 정보를 읽어 들이는데 위도,경도 이외에도
표고, 위도, 경도의 오차, 디바이스 진행 속도, 진행 방향 등의 정보도 조회 가능하다
(다만 장치별 이용 가능 여부를 확인해야 함)

그리고 getCurrentPosition 은 위치 정보를 일회성으로 받아 올 때 사용하는 반면,
watchPosition 함수는 위치의 변경 정보를 계속해서 알고 싶을 경우 사용한다

즉 장치의 위치가 변경될 때 마다 계속 호출되므로 위치의 변화를 지속적으로 감지할 수 있게 된다
(역시 매 확인은 비동기로 이루어 진다) (관련 자료 참고 바람)

다음 사이트에서 Geolocation 관련 추가 학습과 데모를 확인해 보자
http://www.ibm.com/developerworks/kr/library/x-html5mobile1/
http://html5demos.com/geo
http://3liz.org/geolocation/


출처 - http://m.mkexdev.net/56





안녕하십니까? 

이번엔 Geolocation API 를 살펴보겠습니다.

Geolocation API 는 HTML 5 에 새롭게 추가된 사용자의 위치정보를 얻기위한 JavaScript API 입니다.
여러분들도 잘 아시겠지만 이젠 위치정보를 기반한 서비스가 우리 생활 곳곳에 퍼져있으며 많은 서비스들이 위치정보와 연동하여 사용자들에게 UX 의 편리함을 줄 것입니다.

Geolocation API 는 세개의 Method 로 이루어진 API 입니다.

그 전 먼저 알아야 할 점은 현재의 위치정보가 Network 정보로 부터 추측한 것인지 GPS 로 부터 얻은 것인지에 관한 자세한 내용은 알 수 없다는 것입니다. 단지 GPS 가 내장된 Smartphone 과 같은 Device 에서는 GPS 기능을 활용할 수있고 일반 PC 에서는 WiFi 같은 정보를 이용해서 현재 정보를 알아 낼 수 있습니다.
Geolocation 은 위치정보에 대한 정보를 GPS, WiFi IP Address, GSM/CDMA 망을 사용하는 휴대전화의 IDs 등에서 얻어옵니다. 다만 PC 에서는 한정된 정보만 제공하여 이용이 불가능한 경우가 있고 특히 Mobile Browser 에서 유용한 API 라고 할 수있습니다.


18-1. 사용법
Geolocation API 와 관련된 함수는 모두 window.navigator 객체에 정의되어 있습니다.
다음 Method를 사용하여 위치정보를 얻어 올수 있습니다.

현재 위치를 한번만 얻기 위한 함수입니다.
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);

다음 함수를 이용하여 위치정보를 계속 확인합니다.
var watchId = navigator.geolocation.watchPosition(successCallback, errorCallback, options);

성공시 호출되는 successCallback 함수에 전달되는 위치정보에는 다음과 같은 정보들이 포함됩니다.
위치정보 속성coords 속성설명
coordslatitude위도
longitude경도
altitude표고
accuracy위도, 경도의 오차 (단위와 오차)
altitudeAccuracy표고의 오차 (단위와 오차)
headingDevice 의 진행 방향. 북쪽을 기준으로 한 시계방향의 각도로 나타냄
speedDevice 의 진행 속도(미터/초). (이용할 수 없을 때는 null)
timestamp위치정보를 얻은 시각(1970년 1월 1일 부터의 milisecond)

Error 발생시 호출되는 errorCallback 함수에 전달되는 객체에 담겨져 있는 속성과 상수들입니다.
속성/상수설명
codeError Code
UNKNOWN_ERROR알수 없는 Error (Error code 값 : 0)
PERMISSION_DENIED권한 없음 Error (Error code 값 : 1)
POSITION_UNAVAILABLE위치정보를 얻을 수 없음 (Error code 값 : 2)
TIMEOUT시간제한 초과 (Error code 값 : 3)
messageError Message

위치정보를 조회시 입력하는 세번째 Parameter 인 option 에 지정할 수 있는 것들은 다음과 같습니다.
속성/상수설명
enableHighAccuracy정확도가 높은 위치 정보를 요청
timeout위치 정보 확인에 시간제한을 설정. 시간제한을 초과하면 TIMEOUT error 발생
maximumAge위치정보의 유효기간을 설정. 0 을 지정하면 항상 새로운 위치정보를 요청함

option 의 사용법은 아래와 같습니다.
내용을 보면 위치정보의 유효기간은 0 으로 항상 새로운 위치정보를 가져오며, 정확도 높은 위치정보를 요청합니다. 그리고 timeout 은 3초로 설정하고 있습니다.
navigator.geolocation.getCurrentPosition(successCallback, errorCallback,
{maximumAge: 0, enableHighAccuracy: true, timeout: 3000 }
);

18-2. Bing Map 사용하기
예제로 Bing Map 을 사용해 보려합니다.
Bing Map 을 사용하기위해서 사전에 사용자 등록을 하고 사용 Key 를 받아야 하는데요. 간단히 Key 를 받는 과정을 보도록 하겠습니다.

Site 주소는 http://www.microsoft.com/maps/developers/web.aspx 입니다.

geolocation_01.jpg

 

Get Account 를 클릭합니다.
Capture 가 안되었지만 Windows Live ID Passport 인증을 한번 묻습니다.
여러분들 모두 MSN Live Messenger 사용하시죠? 입력하시고 Login 이 완료되면 다음 화면으로 넘어갑니다.

geolocation_02.jpg

 

새롭게 받을 거니까요...
New User 쪽의 Create 를 클릭합니다.

geolocation_04.jpg

 

* 표시가 되어 있는 란에 간단하게 입력합니다.
 

geolocation_06.jpg

 

조금 기다리시면 Account ID 가 생성이 됩니다. 그럼 "Create or view Keys" 를 Click 합니다.

geolocation_08.jpg

 

* 표시가 되어 있는 란에 간단히 입력하시고요... "Submit" 버튼을 Click 합니다.
또 잠시 기다립니다.

geolocation_10.jpg

 

아랫쪽에 보시면 짜자잔.. Key 가 생성이 되었군요.
이 생성된 Key 를 다음에 진행될 Geolocation 예제 소스에 Key 를 입력하는 곳에 입력해 주십시요.

18-3. 예제.

예제를 살펴보겠습니다.
이 예제는 제 PC 에서 동작할 것입니다. 이전에 설명드렸듯이 PC 에서 진행하는 경우 아주 제한적입니다. 주로 서울시 시청이 많이 찍히는데요. 그 옆동네가 찍히기도 합니다. ^^;

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
    body {
        margin: 0;
        height: 100%;
    background-color: #404040;
    }
    #map { 
         position: absolute;
    top: 50%;
        left: 50%;
        width: 800px;
        height: 600px;
    margin-left: -400px;
        margin-top: -300px;
    }
</style> 

<script charset="UTF-8" type="text/javascript" src="
http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script
<script type="text/javascript">

        var _map;

        function GetMap() {
            // Create a Bing map
    _map = new Microsoft.Maps.Map(document.getElementById("map"), { credentials: "이곳에 Key를 넣습니다." });
            // Get the current position from the browser
            if (!navigator.geolocation)
                alert("This browser doesn't support geolocation");
            else
                navigator.geolocation.getCurrentPosition(onPositionReady, onError, { maximumAge: 0, timeout: 30000, enableHighAccuracy: true });
        };

        function onPositionReady(position) {
            // Apply the position to the map
            var location = new Microsoft.Maps.Location(position.coords.latitude, position.coords.longitude);
            _map.setView({ zoom: 18, center: location }); 
            // Add a pushpin to the map representing the current location
            var pin = new Microsoft.Maps.Pushpin(location);
            _map.entities.push(pin);
        }

        function onError(err) {
            switch (err.code) {
                case 0:
                    alert("Unknown error");
                    break;
                case 1:
                    alert("The user said no!");
                    break;
                case 2:
                    alert("Location data unavailable");
                    break;
                case 3:
                    alert("Location request timed out");
                    break;
            }

    }
</script>
</head>
<body onload="GetMap();">
<div id="map" />
</body>
</html>
(참조 : http://www.wintellect.com/CS/blogs/jprosise/archive/2011/03/27/making-web-apps-sizzle-with-bing-maps-and-html5-s-geolocation-api.aspx)

위 소스를 각 Browser 에서 실행시키면 먼저 사용자의 위치정보를 공유하겠느냐 라는 메세지 창을 띄워 Geolocation 사용에 대한 동의를 구한 후 화면을 띄우게 됩니다.

geolocation_11.jpg

 

같은 Page를 띄우긴 했지만 다른곳이 나오죠? ㅋㅋ 
PC 에서는 신경쓰지 마셔요...

Google Map 의 경우는 Bing Map 보다는 Key 를 입력할 필요없이 Test 가 가능하기때문에 조금은 쉬우리라 생각합니다. 구현방법은 약간 차이가 나겠지만요... 

간단하게라도 살펴보시니 어떠십니까? Geolocation 을 여러분의 Site 에 적용하고 싶은 생각이 드시나요?

회사 Web Site 에 살짜기? 몰래 올려서 테스트 해보시면 하루가 즐겁지 않을까효~~? 

위의 내용들은
혁명을 꿈꾸다 HTML5 & API 입문
앞서가는 디자이너와 퍼블리셔를 위한 HTML5 & CSS
을 참고 하였습니다.



HTML5 시리즈 강좌 리스트
[HTML5강좌] 1. HTML5 개요
[HTML5강좌] 2. HTML4 vs HTML5 (1)
[HTML5강좌] 3. HTML4 vs HTML5 (2)
[HTML5강좌] 4. Sementic Element (1)
[HTML5강좌] 5. Sementic Element (2)
[HTML5강좌] 6. Strong Web Form
[HTML5강좌] 7. Rich Text Edit API
[HTML5강좌] 8. Video Element
[HTML5강좌] 9. Audio Element
[HTML5강좌] 10. Canvas Element
[HTML5강좌] 11. Drag & Drop API
[HTML5강좌] 12. Offline Web Application
[HTML5강좌] 13. Communication API
[HTML5강좌] 14. Web Storage
[HTML5강좌] 15. Web SQL Database
[HTML5강좌] 16. Web Worker
[HTML5강좌] 17. Web Socket
[HTML5강좌] 18. Geolocation API
[HTML5강좌] 19. SVG
[HTML5강좌] 20. File API



HTML5 동영상 강좌 리스트
[HTML5 동영상 강좌] 1. HTML 5 개요
[HTML5 동영상 강좌] 2. HTML4 vs HTML5 (1)
[HTML5 동영상 강좌] 3. HTML4 vs HTML5 (2)
[HTML5 동영상 강좌] 4. Sementic Element (1)
[HTML5 동영상 강좌] 5. Sementic Element (2)
[HTML5 동영상 강좌] 6. Strong Web Form
[HTML5 동영상 강좌] 7. Rich Text Edit API
[HTML5 동영상 강좌] 8. Video Element
[HTML5 동영상 강좌] 9. Audio Element
[HTML5 동영상 강좌] 10. Canvas Element
[HTML5 동영상 강좌] 11. Drag & Drop API
[HTML5 동영상 강좌] 12. Offline Web Application
[HTML5 동영상 강좌] 13. Communication API
[HTML5 동영상 강좌] 14. Web Storage
[HTML5 동영상 강좌] 15. Web SQL Database
[HTML5 동영상 강좌] 16. Web Worker
[HTML5 동영상 강좌] 17. Web Socket
[HTML5 동영상 강좌] 18. Geolocation API
[HTML5 동영상 강좌] 19. SVG
[HTML5 동영상 강좌] 20. File API



행복한 고수되십시요.


출처 - http://www.sqler.com/400590


'Development > HTML' 카테고리의 다른 글

html - form의 target  (0) 2013.05.13
html - label과 placeholder 차이  (1) 2012.12.13
html - 조건부 주석  (0) 2012.09.11
html - HTML 특수문자코드표  (0) 2012.08.01
DIV, SPAN, FIELDSET 공통점  (0) 2012.06.26
Posted by linuxism
,