[Google Analytics] UTM Parameter를 달아 링크 유입 분석하기 (with google URL Builder, Bitly)

개요

페이스북, 혹은 배너 등에 링크를 공유할 때, ‘이 작업’을 해주신다면
  • 남자 여자 중 어떤 성별이 더 이 링크를 클릭했는지
  • 이 링크로 들어온 사람들의 구매율
  • 페이스북에 공유한 링크 중 어떤 것이 가장 클릭률이 높은지
  • 이 링크로 들어오자마자 재미없어서 나가버리는 확률은 얼마인지
등의 마법같은 통계를 Google Analytics에서 보실 수 있습니다.
‘이 작업’이란, url 뒤에 태그같은 것들을 붙이는 걸로 ‘UTM Parameter 달기‘라고 합니다.

작성 방법

  1. 구글 URL 작성 도구 로 접속합니다.
  2. 양식에 맞추어 URL을 작성해줍니다. (참고 링크1 참고링크2) (공동작업시엔 구글 스프레드시트를 하나 파놓고 쓰면 정리하기 편합니다)
    1. [필수] 웹사이트 URL: 공유할 링크를 적어줍니다. (ex. https://milooy.wordpress.com) (특수문자는 이스케이프 해주어야 합니다!)
    2. [필수] 캠페인 소스: ‘누가(who)’ 방문자를 보내주는가? 검색엔진, 사이트 이름 등 소스정보 (ex. google, naver, facebook, naver_clickchoice)
    3. [필수] 캠페인 매체: ‘어떻게(how)’ 방문자가 사이트를 찾게됬는가? 어떤 타입의 광고인지. (ex. cpc, display, social, email)
    4. [선택] 캠페인 키워드: 검색광고키워드.
    5. [선택] 캠페인 콘텐츠: 광고컨텐츠. A/B테스트 및 광고위치별 태깅에 사용. 특별히 진행하는 캠페인인가? (ex. spring_5per_off)
    6. [필수] 캠페인 이름: ‘무엇때문에(for what)’ 사이트를 방문하는가? 제품, 프로모션 코드 또는 슬로건. (ex. winter+sale, free+coupon)

3.bitly에 접속해 로그인하고 아까 얻은 URL을 붙여넣으면 짧은 URL이 나옵니다. 글을 공유할 땐 이 링크를 이용해줍니다 ^^! Bitly__The_power_of_the_link__및_새_글_—_WordPress_com

4.구글 애널리틱스의 획득>전체>소스/매체 로 접속해서 통계를 볼 수 있습니다. 우측 상단의 ‘날짜‘ 설정 잊지 마세요~

모든_트래픽_-_Google_Analytics

5.‘Facebook’수치만 보고 싶다면 어떻게 해야할까요? 아까 ‘캠페인 소스’를 ‘facebook’으로 해주었죠? 그것을 필터처럼 걸러서 보면 될거예요.

‘+세그먼트’버튼을 눌러 세그먼트를 추가해줍니다. 트래픽소스>소스 를 ‘facebook‘으로 ‘다음과 정확하게 일치함‘을 눌러줍니다.

모든_트래픽_-_Google_Analytics

6.그리고 그 세그먼트만 적용해주면 ‘소스 == facebook’인것들만 걸러서 보여집니다.

(Tip: 다른 세그먼트를 숨기고 싶을 땐 드래그앤드롭해서 치워줍니다. 괜히 ‘삭제’누르면 아예 삭제됩니다 ^^;; 전 처음에 그랬습니다)

모든_트래픽_-_Google_Analytics

7.원하는 소스를 걸러냈으면 ‘캠페인’명으로 확장시켜 보면 되겠죠?

두번째 측정기준을 ‘캠페인‘으로 잡아줍니다.

모든_트래픽_-_Google_Analytics

8.캠페인 명이 ‘revatoon-1’로 접속한 사람들이 가장 많은 것을 알 수 있습니다. 사스가 레바!

모든_트래픽_-_Google_Analytics

9.나중에 필요한 것들을 쉽게 모아보기 위해 대시보드에 추가해볼까요?

만들어둔 대시보드 ‘URL통한 행동분석‘에 원하는 위젯을 추가해줍니다.

‘타임라인’은 위에 있는 그래프고, ‘표’가 아래의 표 입니다.

모든_트래픽_-_Google_Analytics_및_네이버_뮤직____Old_Skool_Love__Feat__장효석_

10.대시보드 > URL통한 행동분석 에 들어가보면 내가 추가해둔 위젯들이 나옵니다.

세그먼트를 ‘Facebook소스‘ 로 해두고, 필요한 위젯들을 추가해줍니다.

전 마케터들이 보기 편하도록 이것 저것 위젯들을 추가하고 커스텀해두었습니다.

URL통한_행동분석_-_Google_Analytics

11.위젯 설정에 들어가면 옵션들이 많습니다.

저는 캠페인명으로 일차 정렬하게 하고, 그 다음은 세션이 큰 수대로 나오도록 해두었습니다.

그리고 소스가 facebook인것만 보여주도록 했습니다.

URL통한_행동분석_-_Google_Analytics

12.이렇게 분석한 데이터들로 더 똑똑한 사이트를 만들어보아요!

아기_토끼

~ 끝 ~

자바스크립트&제이쿼리 (존 두켓 지음, 제이펍 출판) – “세상에서 가장 아름다운 프로그래밍 서적”

진유림_-_휴대폰_업로드

4월 초, 페이스북을 뜨겁게 달군 한 책이 있다.

충격적인 카피 때문일 것이었다.

“지금 여러분은 세상에서 가장 아름다운 프로그래밍 서적을 보고 있습니다!”

라니. 자고로 프로그래밍 서적은 노란책이나 코뿔소책처럼 그림은 존재하지 않는 작은 텍스트 뿐인게 대부분 아닌가.

그러나 이 책은 조금 달랐다.

위 사진의 댓글 분들이 요구하신 것처럼(그리고 모종의 잿밥을 향하여), 간단한 서평을 써보겠다.

S__9166854

(외모가 많이 다르다. 위:자바스크립트 노란책)

이 책이 다른 책들과 다른 점은,

  1. 텍스트로만 이해하기 힘든 부분들은 잘 다듬어 비쥬얼라이제이션 해두었고(책 전체를 아울러서!)

  2. 왼쪽 페이지에 DOMNodeInserted와 같은 개념을 설명한 후엔, 오른쪽엔 그 개념들을 어울러 실용적인 예제들을 만들어둔게 참 좋았다.

그것이이 이해-습득의 작은 루틴을 만들어 공부에 리듬감을 주었다.

S__9166856

(이런 식. 예제는 ‘구매 물품 목록 만들기’의 변형본을 계속 사용하여 익숙한 느낌을 준다)

630페이지를 돌파하는 두꺼운 책이지만, 사실 처음에는 이틀이면 완독할 줄 알았었다.

참 많이 부족하긴 하지만, 그래도 프론트엔드 신입 개발자로 일하고 있는 나였고, 주 언어는 자바스크립트였으니까.

아는 부분은 슬렁 슬렁 넘어가야지 하며 가벼운 마음으로 읽기 시작했는데

얼마 지나지 않아 내가 모르는 부분들이 나오는 것에 당황스러워 하다가,

곧 자세잡고 정독&블로그정리 하며 읽었다.

이는 그 산출물들이다.

https://milooy.wordpress.com/2015/04/03/javascript-dom/

자바스크립트 & 제이쿼리 (jpub) – 6장 Javascript event

https://milooy.wordpress.com/2015/05/17/jquery/

처음에 자바스크립트를 학교에서 공부한 이후로는, 필요한 기능이 있을때마다 api문서나 스택오버플로우만 찾아보며 닥친 문제를 해결하곤 했는데, 이 책은 실용적인 기능들을 체계적으로 샅샅히 흝어가는 느낌이 참 좋았다.

나는 참 구멍뚫린 곳들이 많았구나….

S__9166851

(예를 들면 이런 것들. before()과 prepend()의 차이.)

자바스크립트나 제이쿼리를 처음 접하는 사람들에게,

아니면 배웠지만 나처럼 빵꾸가 많이 뚫려있는 사람에게,

혹은 유려한 편집디자인의 미를 느끼며 개괄적으로 흝고 싶은 사람에게 추천한다.

(나는 예쁜 것에도 민감하여, 이 책 한장 한장 디자인이 예뻐서 공부할 맛이 났다)

아, 그리고 위에 정리해둔 링크를 보면 알겠지만, 아직 읽어야 할 장들이 좀 남았는데 이는

8. Ajax와 JSON

9. API

10. 오류 처리와 디버깅

등등으로 더더욱 실무적인 내용이 있다. 취약했던 부분을 예쁜걸로 배운다니 마음이 꽁냥하다.

다른 직업도 마찬가지겠지만, 개발자는 정말 끊임없는 공부가 필요하다. 그리고 그것을 즐겨야 큰 개발자가 될 수 있다.

주변에 “아… 일시정지 누르고 ㅇㅇ(swift/go/polymer등등)좀 배우고 다시 일했으면 좋겠다 ㅠㅠ”라며

‘자신이 현재 하는 일 외의 개발’을 취미생활(혹은 사치생활!)로 여기며 배움에 대한 갈망을 내보이는 개발자들이 참 많다.

그런 사람들과 함께할때마다 배가 간질간질해지며 그들이 참 귀엽고 이런 개발자 세계가 좋다.

신기술은 끊임없이 나오고, 스피드웨건같은 블로거님들과 출판사님들 덕분에 참 개발공부하기 좋은 때이다.

이 시기와 환경을 십분 이용해먹어야지 슈퍼개발자가 되어야지 파워블로거도 되어야지 주짓수 챔피언이 되어야지


(p.s HTML CSS가 부족하다면 같은 저자가 집필한 이 책도 추천드려요)

책정보__HTML_CSS___네이버_책

자바스크립트 & 제이쿼리 (jpub) – 7장 jQuery

요소 탐색하기

  • 계층 탐색
    • ancestor descendant
    • p>c: 다른 요소의 하위 요소들
    • p+n: 직접적인 자식 요소들(모든 자식요소 하고싶다면 p>*)
    • p~s: 이전 요소의 모든 이웃 요소
  • 기본 필터
    • :not(selector): 셀렉터에 부합하는 요소를 제외한 나머지 요소들(div:not(‘#summary’))
    • :first: 선택된 요소 중 첫 번째 요소
    • :last, even, odd
    • :eq(index): 선택된 요소 중 매개변수로 지정된 인덱스 번호를 가진 요소
    • :gt(index), :lt(index)
    • :header, :animated, :focus
  • 콘텐츠 필터
    • :contains(‘text’): 매개변수로 지정된 텍스트를 가지고 있는 요소들
    • :empty: 자식 요소가 없는 모든 요소들
    • :parent: 위의 반대
    • :has(selector): 선택된 요소 중 매개변수에 지정된 셀렉터에 부합하는 요소를 최소한 하나 이상 가지고 있는 모든 요소 (ex. div:has(p) p요소를 가진 모든 div요소)
  • 가시성 필터
    • :hidden: 화면에서 숨겨진 모든 요소들
    • :visible: 페이지의 레이아웃에서 공간을 차지하고 있는 모든 요소들.
  • 자식 요소 필터
    • :nth-child(expr): 1부터 시작하는 해당 순번의 요소(ul li:nth-child(2)는 두번째 요소를 의미)
    • :first-child, :last-child, :only-child
  • 특성 필터
    • [attribute]: 지정된 특성 갖고있는 요소들
    • [attribute=’value’]
    • [attribute!=’value’]
    • [attribute^=’value’]: 특성값이 지정된 값으로 시작하는 요소들
    • [attribute$=’value’]: 특성값이 지정된 값으로 끝나는 요소들
    • [attribute*=’value’]: 특성값이 지정된 값으로 포함되는 요소들
    • [attribute][attribute2]: 지정된 특성 중 하나를 가진 모든 요소들
    • :input, :text, :password, :radio…
    • :image, :button
    • :selected: 드롭다운 리스트에서 선택된 모든 요소들
    • :enabled, :disabled, :checked(체크된 요소들을 리턴)

선택된 요소에 필요한 작업 수행

  • 콘텐츠 필터
    • 가져오기/수정하기
      • .html(): 첫 번째 요소들과 그 하위 노드들의 HTML코드를 얻음.
      • .text(): 객체집합 내 모든 요소의 텍스트와 그 하위 요소들의 텍스트 리턴.(input요소나 textarea요소에서 내용 가져오려면 .val()메서드 사용.)
      • .replaceWith(): 일치하는 모든 요소에 새로운 동일한 콘텐츠 추가하고 교체된 요소들을 모두 리턴
      • .remove(): 일치하는 모든 요소들을 제거
    • 요소
      • .before(): 선택한 요소 전에
      • .after(): 선택한 요소 다음에
      • prepend(): 선택한 요소의 여는 태그 다음에
        • a.prepend(b)는 a에 b를 추가한다 / a.prependTo(b)는 b에 a를 추가한다.
      • append(): 선택한 요소의 닫는 태그 다음에
      • remove
      • clone
      • unwrap
      • detach
      • empty
      • add: 매개변수로 지정된 셀렉터에 의해 선택된 요소들을 기존 객체집합에 추가
    • 특성
      • attr
        • 가져오기: $(‘li#one’).attr(‘id’);
        • 수정하기: $(‘li#one’).attr(‘id’, ‘hot’);
      • removeAttr
      • addClass
      • removeClass
      • css
        • 가져오기: bg = $(‘li’).class(‘background-color’);
        • 증감하기: $(‘li’).class(‘padding’, ‘+=20’);
        • 여러 속성: $(‘li’).css({‘color’: ‘#272727’, ‘font-family’: ‘Courier’});
    • 폼 값
      • val: input, select, textarea요소에 주로 사용.
      • isNumeric
  • 요소 탐색
    • 일반
      • find: 현재 객체집합에서 셀렉터와 일치하는 요소들 리턴
      • closest: 셀렉터와 일치하는 가장 근접한 상위요소(직계부모~최상위요소 모두)를 리턴
      • parent: 현재 객체집합의 직계부모요소 리턴
      • parents: 모든 부모요소
      • children: 모든 자식 요소
      • siblings: 모든 이웃 요소
      • next: 다음 이웃 요소
      • nextAll
      • prev
      • prevAll
    • 필터/테스트
      • filter: 두 번째 셀렉터를 이용하여 jQuery객체집합을 필터링
      • not
      • has
      • is: 폼요소가 선택 혹은 체크되어있는지 확인
      • :contains()
    • 객체집합 내 순서 평가
      • eq: 인덱스 번호에 해당하는 요소를 리턴
      • :lt
      • :gt
  • 크기/위치
    • 크기
      • height: 영역의 크기
      • with innerHeight(영역의 높이에 안쪽 여백 더한 값) / innerWidth / outerHeight/ outerWidth
      • $(document).height()
      • $(document).width()
      • $(document).height()
      • $(window).height()
      • $(window).width()
    • 위치
      • offset: document객체의 좌측 상단 모서리에서부터 요소까지의 좌표를 가져오거나 지정(offset().top 이런식으로 쓴다)
      • position: 상위 요소 중 기본 흐름 값을 가진 요소로부터 해당 요소까지의 좌표를 가져오거나 지정
      • scrollLeft
      • scrollTop
  • 효과/애니메이션
    • 기본
      • show: 선택된 아이템을 보이게
      • hide: 숨긴다
      • toggle
    • 흐림 효과
      • fadeIn
      • fadeOut
      • fadeTo: 선택된 요소의 불투명도 조절
      • fadeToggle
    • 슬라이딩 효과
      • slideDown
      • slideUp
      • slideToggle
    • 기타
      • delay: 큐 내의 다음 아이템의 실행을 잠시 지연
      • stop: 현재 실행중인 애니메이션 중단
      • animate: 새로운 임의의 애니메이션 생성
  • 이벤트
    • 문서/파일
      • ready
      • laod
    • 사용자 상호작용
      • on
      • (.click(), .hover(), submit()같은 메서드들도 보게 될것인데, 이벤트 처리를 위한 on()메서드가 나타나며 사라짐)

tips

정보

  • 획득
    • jquery객체집합에 둘 이상 요소 저장되어 있으면 ($(‘li’).html();) 첫번째 요소의 정보만 얻어옴.
    • 다른 요소 참조하려면 탐색메서드나 필터 메서드, 혹은 셀렉터 이용.
    • 모든 요소 콘텐츠 가져오려면 .each()메서드 사용.
  • 수정
    • 둘이상 요소 저장되어있고 수정하면 모든 요소 수정됨.

변수에 캐싱

  • 코드가 동일한 객체집합을 한번 이상 사용할 필요가 있다면 객체에 담아두는게 효과적.
  • $listItems = $(‘li’); 와 같이 변수에 jQuery객체를 저장할 때 이렇게 하면 다른 변수들과 구분하는데 도움된다.

체이닝

  • jQuery객체집합을 수정하기 위한 대부분의 메서드는 체이닝 가능
  • 그러나 DOM/브라우저에서 정보를 조회하는 메서드들은 체이닝으로 연결 불가.

페이지가 준비되었는지 확인

// 이 메서드 내부에 작성하면 코드가 페이지의 다른곳이나 다른 파일에 작성된 경우에도 의도대로 동작한다.
$(document).ready(function() {
    //bla bla
});

// 위 함수의 약식 표현
$(function() {
    //bla bla
});
  • .load()
    • load이벤트가 발생할 때 호출.
    • .on()메서드로 대체되었다.
    • 페이지와 나머지 모든 리소스(이미지, CSS, 스크립트)가 로드된 이후에 발생
    • 스크립트가 반드시 로드되어야 하는 리소스에 의존적일 때 사용.
      • ex. 스크립트가 이미지의 크기를 알아야 할 때
  • .ready()
    • 페이지가 빨리 로드된 것처럼 보이도록 브라우저에 DOM이 로드되자마자 실행.
    • 그러나 최신 브라우저들에서만 지원.(구버전: laod이벤트 되면 시작)

컨텐츠를 수정

현재 선택한 요소들의 콘텐츠를 사용하려는 동시에 수정하려면 함수에 매개변수를 전달하면 된다.

$('li.hot').html(function(){
    return '<em>' + $(this).text() + '</em>';
    })

.each()

$(function() {
    $('li').each(function() {
        var ids = this.id;  //$(this).attr('id')보다 이게 좋다.
        $(this).append('<span class="order">' + ids + '</span>');
    });
});

this

$(this)처럼 this키워드를 이용해 새로운 jQeury 객체집합을 만드는 경우도 볼 수 있는데,
이렇게 하면 현재 요소에 대해서도 jQuery메서드들을 사용할 수 있다.

.on()

  • 매개변수를 2개 받는다. 첫번째는 대응할 이벤트, 두번째는 함수(기명/익명)
  • (*친것들은 onready처럼 작업을 더 쉽게 만들어주는 추가 메서드 제공.)
  • focus, blur, change
  • input, keydown keyup, keypress
  • click, dblclick, mouseup, mousedown, mouseover, mousemove, mouseout, *hover
  • submit, select, change
  • *ready, load, *unload
  • error, resize, scroll
//모바일은 마우스오버가 없으니 클릭도 같이 지정.
$listItems.on('mouseover click', functionn(){
    //~~
});

event객체

$('li').on('click', function(e) {
    eventType = e.type;
});

속성

  • type: 이벤트 종류
  • which: 눌려진 버튼이나 키
  • data
  • target: 이벤트가 발생한 DOM요소
  • pageX, pageY
  • timeStamp
  • .preventDefault(): 기본 동작을 취소(ex. 폼 데이터 전송)
  • .stopPropagation(): 상위 객체로 이벤트가 버블링되는 것을 중단.

.animate()

.animate({
    //변경할 스타일들 나열
    }, [, speed][, easing][, complete]);
// speed: 진행될 시간의 길이 밀리초단위. low/fast도 가능
// easing: linear(일정속도) / swing(중간은 빨리 처음끝은 느리게)
// complete: 애니메이션이 종료시 호출될 함수(콜백함수)를 지정 위함

$(this).animate({
    opacity: 0.0,
    paddingLeft: '+=80'
    }, 500, function() {
        $(this).remove();
    });

오타

303p attribute$=’value’
322p $(‘li’).clss(‘~’)
322p ‘background-color’: ‘#272727’,

언니네 이발관, 아름다운 것

가사를 한 글자 한 글자 보아야 하는 노래.
쓰린 가사.
내가 이랬던 적과, 상대가 이랬던 적이 모두 생각나는
그래서 아픈 곡


그대의 익숙함이 항상 미쳐버릴 듯이 난 힘들어
당신은 내 귓가에 소근대길 멈추지 않지만
하고 싶은 말이 없어질때까지 난 기다려
그 어떤 말도 이젠 우릴 스쳐가

앞서간 나의 모습 뒤로 너는 미련 품고 서 있어
언젠가 내가 먼저 너의 맘 속에 들어가
하고 싶은 말이 없어지지 않을 거라 했지.
그랬던 내가 이젠 너를 잊어가.

사랑했다는 말 난 싫은데 아름다운 것을 버려야 하네
넌 말이 없었지마치 아무 일도 아닌 것처럼
슬픔이 나를 데려가 데려가

나는 너를 보고 서 있어 그 어떤 말도 내 귓가에
이젠 머물지 않지만
하고 싶은 말이 없어질 때까지만이라도
서로가 전부였던 그때로 돌아가
넌 믿지 않겠지만

사랑했다는 말 난 싫은데 아름다운 것을 버려야 하네
난 나를 지켰지 마치 아무 일도 아닌 것처럼
그동안의 진심 어디엔가 버려둔 채

사랑했었나요 살아 있나요 잊어버릴까 얼마만에
넌 말이 없는 나에게서 무엇을 더 바라는 가
슬픔이 나를 데려가 데려가

피터팬 컴플렉스, 사랑의 첫 단계

(아래 영상: 2012년 3월 10일 클럽 타에서 펼쳐진 피터팬컴플렉스의 ’10개의 방’ 단독 공연 중에서첼로와 피아노 만으로 편곡된 사랑의 첫단계.

처음에 나오는 노래는 미발표된 전지한의 솔로프로젝트 음악 제목은 아직 무제)

 

숨넘어갈듯한 보컬.

사랑을 처음 시작할때의 느낌-가사가 음에 실려 귀를 통해 배로 들어온다.

 

 


난 너를 바라보면 너에게서 나의 눈을

뗄 수 없어 이렇게 난
가끔씩 너의 눈과
나의 눈이 마주치면
내 심장은 이렇게 터질 듯 해
잠을 잘 수도 없어 네 생각에
아침에 눈을 떠도 널 생각해

사랑 인가봐 널 사랑하나봐
내 마음속은 너로 가득 차 미칠 것 같이
보고 싶어서 네가 보고 싶어서
난 아무것도 할 수가 없어
숨도 쉴 수가 없어
내 가슴은 터질 것 같아

저 멀리서 널 바라봐
나의 눈을 뗄 수 없어
너에게서 나의 눈을 뗄 수가 없어서
나는 용기를 내려 했어
하지만 다가 갈 수 없었어 너에게

사랑인가봐 널 사랑하나봐
내 마음속은 너로 가득차 미칠 것 같이
보고 싶어서 네가 보고 싶어서
난 아무것도 할 수가 없어 숨도 쉴 수가 없어
내 가슴은 터질 것 같아

사랑하는 그대여 나의 손을 잡아주오
나의 맘을 받아주오 내 사랑아 내 사랑아

J.D.샐린저, 호밀밭의 파수꾼

정말 좋아하는 사람이 빌려준 책.

난 책을 추천받는 것을 좋아한다. 그 사람이 느꼈던 것을 나도 느끼고 있을까 하는 또다른 설렘이 주어지니까.

엄마도 이 책을 굉장히 좋아하신다.

그만큼 기대하며 이 책을 읽기 시작하였다.

p. 134

서니가 떠나고 난 후, 난 의자에 앉아 담배를 몇 대 피웠다. 날이 점점 밝아오고 있었다. 비참한 기분이었다. 얼마나 우울했는지는 말로 다 할 수 없을 정도였다.

난 앨리에게 큰소리로 말을 걸었다. 가끔씩 너무나도  기분이 울적할 때면 이렇게 했다. 집에 가서 자전거를 가지고 와서, 보비 팰론의 집 앞에서 만나자고. 보비 팰론은 메인 주에 있을 때 바로 옆집에 살던 친구였다. 정말 오래전 일이다. 실제로 어느 날인가 나는 보비와 함께 자전거를 타고 세데리고 호수까지 가기로 했던 적이 있다. 도시락을 싸서, 공기총도 가지고서. 그때만 해도 우린 어렸고, 공기총으로도 뭔가 잡을 수 있을 거라고 생각하고 있었다. 우리가 하는 얘기를 앨리가 듣고는 자기도 같이 가고 싶다고 했다. 난 그때 앨리에게 너무 어리다면서 데리고 갈 수 없다고 말했었다. 그래서 지금처럼 기분이 많이 울적해질 때면 앨리에게 이렇게 중얼거리는 것이다. “좋아, 집에 가서 자전거를 가지고 보비 집 앞으로 와. 빨리 갔다 와. 어서” 그렇다고 그때 내가 앨리를 아무 데도 데리고 다니지 않았던 건 아니다. 도리어 늘 데리고 다녔었다. 그런데 그날만은 데리고 가지 않았따. 같이 가지 못했다고 앨리도 화를 내지는 않았다. 그 애는 어떤 일에도 화를 내는 법이라고는 없었으니까. 그런데도 이렇게 우울할 때면 그 생각이 나곤 하는 것이다.

나는 왜 이걸 다 쓰고 있었을까. 생각보다 많이 기네. 하지만 쓰고 싶었다.

은유의 종말

은유의 종말

2013/09/19 by wangsy | 5 Comments

내가 맥을 처음 접했을 때가 대략 89년쯤인데, 맥을 처음 키면, Macintosh Guide라는 애플리케이션이 실행되었다. 그리고 기본적인 개념을 가르쳐 주었는데, 가장 먼저 시작하는 것이 마우스 사용의 개념을 익히는 것이었다. 3가지 개념을 가르치는데, Point, Click, Drag & Drop 이다. 이것을 실습하기 위해서, 어항이 있는 책상을 보여주었다. 그리고 Point 를 통해서 마우스를 가져다 대면 반응을 하고, Click 을 통해서 선택을 하고, Drag & Drop 으로 하나의 대상을 다른 대상으로 이동을 하여 무언가 액션을 할 수 있는 것을 가르쳐 주었다.

여기서 파일, 폴더, 휴지통, 데스크탑으로 비유를 확장하고, Point, Click, Drag & Drop 의 사용자 액션을 통해서 사용자가 컴퓨터에 원하는 의도를 전달할 수 있는 형식이었다. 책상위에 있는 문서를 Drag & Drop 으로 책상 서랍의 폴더에 옮겨 넣는 연습을 한다. 완벽한 은유였다. 그리고 이 은유는 생각보다 넓게 확장되었다.

그리고, Macintosh Human Interface Guideline 을 보게 되었는데, 3가지를 가르쳤다. 직관성, 일관성,  허용성. 직관성은 은유를 통해서 배우지 않아도 맥을 사용할 수 있었고, 일관성은 한번 알게 된 내용은 항상 동일한 의미로 사용되기 때문에 매번 배우지 않고도 인지할 수 있게 한다. 그리고 허용성은  사용자는 맘 편하게, 직관적으로 사용해 볼 수 있고, 혹시 잘못 추측했더라도 다시 번복할 수 있도록 허용하는 것이다. 그를 통해서 더더욱 빠르게 배울 수 있게 된다. 나는 이 철학에 탄복하였고, 지금껏 살아오는 내내, 내가 무언가를 만든다고 할때 생각의 기본 틀로 사용하였다. (물론 남이 만든 것을 무시하는 도구로 더 많이 사용하였다)

그리고, iPhone 이 나왔다.

iPhone 을 처음 소개한 스티브잡스는, 음악 기능중 Cover Flow를 소개할 때, “You can touch your music” 이라고 설명 하였다. 음악을 만질 수 있어요. 음악이 추상적인 무언가가 아니라, 손끝으로 만지고 조작하고 느낄 수 있는 대상이라는 것, 그것이 iPhone 의 큰 매력이었다.

그리고, iPhone Human Interface Guideline 을 보게 되었는데, 다음과 같은 말이 나왔다. UI 를 만들 때에는 만질 수 있는 대상처럼 설계해야 한다. Direct Manipulation 라는 말이 나온다. 토글 버튼은 오른쪽 왼쪽으로 밀면 딸깍딸깍 바뀌고, 슬라이드는 죽 댕기면 따라 온다. 페이지는 밀면 넘어가고… 그렇다. 터치 인터페이스라는 것은 실제 실생활의 사물 같은 것은 화면상에 넣어놓으면 그걸 진짜 만지는 것처럼 사용하면 된다. 얼마나 직관적인가. 배울 필요가 없다.

스큐몰피즘이란 말이 나왔다. iOS 는 만질 수 있는 객체를 UI 화 하는 것의 극한으로 스큐몰피즘을 선택하였다. 최대한 실생활에 가까운 것을 화면어 넣어야지. 정말 똑같이 생기면 더더욱 실감날 것이야. 디테일의 끝은 어디일까 궁금할 정도로 가죽질감을 넣었고, 금속재질은 빛에 반사하는 느낌도 주었다.

iOS7 이 선보였다. 스큐몰피즘을 이끌었던, 스캇 포스톨이 쫒겨나고, 그 자리를 조니아이브가 꿰찾다. 마치 혁명에 승리한 권력자가 과거를 부정해 버리듯, 조니아이브가 선보인 iOS7 은 철저히 스큐몰피즘을 걷어 내었다. 최신 유행이라고 하는 플랫 디자인으로 바뀌었다. 그냥 세속적으로 보자면, 조니아이브는 참 치졸해 보인다.

은유는 어디로 갔을까? 은유를 통한 직관성은 어떻게 하나?

몇해전부터인가 작은 문제가 생겼다. 우리가 늘 사용하는 “저장”이라는 의미로 사용하는 플로피 디스크, 그냥 아무 생각없이 은유적으로 사용되어 왔었는데, 세월이 한참 지나다 보니, 이걸 모르는 사람이 더 많다는 것이다. 아마도 플로피(적어도 위 아이콘과 같은 3.5인치)를 앞서 도입한 것도 애플이었지만, 가장 먼저 퇴출시킨 것도 애플이었다. 아마 1998년 반투명 iMac 이 세상에 선보였을 즈음이다. 그 이후에 PC 를 처음 접한 사람은 플로피디스크에 저장해 본 경험이 없다. 15살쯤 처음 컴퓨터를 접한다면, 지금 30살 이전의 대부분의 사람들에게는 전혀 직관적이지 않은 은유가 되는 것이다.

좀 더 나가보자. 점점 더 많은 사람들이 아나로그 객체보다 디지털 객체를 더 먼저 접하게 된다. 진짜 라디오 버튼으로 라디오를 조작했던 사람들은 5,60대가 되었고, 진짜 라디오 버튼 보다 화면상의 라디오 버튼을 처음 접한 사람이 더 많은 시대가 되었다. 직관성을 위한 은유가 아닌 용어 자체의 어원으로써 의미 밖게 남지 않는다. 아날로그 객체를 디지털에서 형상화 하는 것은 옛날 사람의 고집인 것 뿐인 시대가 되었다. 그냥 과거의 향수 정도? 앞으로 점점더 많아지는 디지털로 시작하는 세대를 생각한다면 더더욱 그렇다.

화면에서 누를 수 있는 것은, 실생활에서 진짜 눌렀던 버튼들 모양을 가진 것 만은 아니다.

우리는 근래 20년동안 웹이란 것에 익숙해 져 왔다. 웹은 하이퍼텍스트로 시작했다. 화면상에서 밑줄이 쳐 있는 글자는 누르면, 관련된 다른 문서로 이동하였다. 여기서 발전해서 글과 그림이 섞여 있는 문서에서 무언가 다른 정보로 이동시킬 것 같은 텍스트 혹은 이미지 조각을 눌러보면, 더 많은 정보로 연결해 주었다. 우리는 웹을 은유의 도움이 아닌 정보의 문맥으로 웹을 사용해 왔다.

웹은 점점 발전하여 이메일을 작성해 보내는 용도로 쉽게 사용할 수 있었고, 쇼핑을 하기에도 충분하였다. 데스크탑 메타포어 같은 은유는 필요없이 문맥속의 정보만으로 충분히 사용성이 좋았다는 것을 알아버렸다.

iOS 가 시작되면서 가장 먼저 없어진 것이 파일과 폴더의 은유였다. 더이상 파일, 폴더에 대한 은유가 사라진 컴퓨팅 환경이었다. 옛날부터 컴퓨터를 사용한 사람은 혼란스러워 하지만, 머리를 깨끗히 비우고 보면, 더 쉬워진 것은 사실이다. 이제 iOS 7 이 되면서 아날로그에 대한 은유도 사라지려 한다. 옛날 사람들은 다시 또 당황하지만, 미래에서 본다면 자연스러울 수 있다고 본다.

이렇게 된 마당에 구닥다리 옛날 물건들을 최신 기기에 멋지게 옮겨 놓고 편하다라는 표현을 할 수 있을까?  이제는 정보의 문맥이 가장 직관적인 인터페이스가 되는 것인가? 물론 일관성과 허용성은 아직 유효하다. 은유가 아닌 문맥.

 

애플은 iTunes의 아이콘에서 CD 이미지를 제거했다. 더이상 CD가 음악을 상징하지 않는다. 아니 iTunes가 그렇게 만들었다.

좀 더 고민해 보자.

두려워 하지 말고.

꼭 은유가 없다고 직관적이지 않은 것은 아니다.

[일일코딩] 배너 뽑아내 정렬하기

Question

lc.Home.promotions 에 들어 있는 데이터 중 만화 홈 메인 배너들의 comicId를 알파벳 순서로 구하시오.
– 만화 홈 메인 배너는 slot == 'home_main' 조건
– jQuery 사용 금지
for, while 문 사용 금지

Answer

milooy

function compare(a, b){
if(a<b){
return -1;
} else if(a>b){
return 1;
} else {
return 0;
}
}

var hMain = lc.Home.promotions.filter(function(item) {
return (item.slot=='home_main');
});

hMain[0].items.map(function(item) {
return item.comicId;
}).sort(compare);

fallroot

이 문제를 낸 이유는 콘텐츠팀에서 입력한 데이터에 오류가 있어서 찾아야 할 때가 종종 있기 때문입니다. 그러면 홈페이지로 들어가 개발자 콘솔을 열고 현재 데이터를 찾을 때가 많은데 이 문제와 같은 검색을 할 경우가 잦아서 익숙해지시라 낸 문제입니다.

일단 compare 함수는 사용할 필요가 없어요. 만약 명시적으로 저렇게 비교하고 싶으면 아래와 같이 하면 되고요.

Array.sort(function(a, b) {
return a - b;
});

나머지는 잘 했네요. each, map, filter, reduce 등의 열거형 자료를 다루는 함수는 몸에 익숙해지는 게 좋아요.

lc.Home.promotions
.filter(function(p) {return p.slot == 'home_main'})[0]
.items.map(function(i) {return i.comicId})
.sort()
.toString()

추가로 Array#sort 함수의 기본 비교는 어떤 데이터형으로 하는 지 알아보세요. 문자열, 숫자를 비교할 때 각각 어떻게 해야 하는지도요.