스토리 홈

인터뷰

피드

뉴스

조회수 1992

Circle CI에서 rbenv를 이용해서 Ruby 2.2와 CocoaPods 0.39 버전 사용하기

최근 Circle CI에서 Ruby 버전을 2.3으로, CocoaPods 버전을 1.0으로 업그레이드함에 따라 발생하는 빌드 문제를 rbenv를 이용해서 해결한 경험을 공유합니다. 최종적으로 완성된 Gemfile과 circle.yml 파일은 마지막 섹션에서 확인하실 수 있습니다.1. CocoaPods 1.0지난 2015년 12월에 CocoaPods 1.0.0 베타 버전이 처음 공개되었습니다. CocoaPods이 1.0 버전으로 업그레이드되면서 굉장히 많은 변화가 있었는데요. 가장 큰 변화는 DSL입니다. 추상 타겟Abstract Target과 타겟 상속Target Inheritance이 새롭게 소개되면서, 0.39 버전까지 자주 사용되던 link_with 및 :exclusive => true와 같은 구문이 제거되었습니다.이에 따라 기존에 사용하던 Podfile이 CocoaPods 1.0 버전과는 호환되지 않는 문제가 발생했습니다. 이를 해결하기 위한 가장 좋은 방법은 새로운 DSL을 사용하여 Podfile을 다시 작성하는 것이지만, 꽤 많은 서드파티 라이브러리를 사용하는 StyleShare의 경우 새로운 DSL을 적용하여 빌드하면 각종 문제로 인해 빌드가 정상적으로 이루어지지 않았습니다. 4년동안 유지되고 있는 프로젝트이다보니, 레거시 Objective-C 코드와 라이브러리, 그리고 새로운 Swift 코드와 라이브러리가 혼용되어 사용되는 것도 원인 중 하나일 것입니다.따라서 StyleShare에서는 CocoaPods 0.39 버전을 사용하기로 결정을 했습니다. 하지만 최근 Circle CI에서 CocoaPods 버전을 공식적으로 1.0 버전으로 업그레이드하면서 빌드가 깨지기 시작했습니다. Circle CI 환경에서 CocoaPods 0.39 버전을 사용하려면 어떻게 해야 할까요?▲ ㅠㅠ2. Bundler를 이용해서 Gem 관리하기Bundler는 Ruby로 작성된 라이브러리들의 버전을 관리해주는 강력한 도구입니다. CocoaPods에서 Podfile에 의존성을 기재하듯, Bundler에서는 Gemfile에 의존성을 기재합니다.source 'https://rubygems.org' gem 'cocoapods', '~> 0.39' $ gem install bundler 명령어를 사용하면 Gemfile에 기재된 의존성 라이브러리들을 설치해줍니다. 이렇게 설치된 CocoaPods을 사용할 때에는 $ pod COMMAND 대신 $ bundle exec pod COMMAND 명령어를 사용해야 합니다.$ gem install bundler $ bundle install --path vendor/bundle $ bundle exec pod --version 0.39.0 3. Ruby 2.3과 CocoaPods 0.39Bundler를 사용해서 CocoaPods 0.39 버전을 사용하기만 하면 모든 문제가 해결될 줄 알았습니다. 하지만 더 큰 삽질이 남아있었는데요. 바로 Ruby 2.3 버전이 CocoaPods 0.39 버전과 호환되지 않는 것이었습니다.$ bundle exec pod install Updating local specs repositories Analyzing dependencies 신나게 $ bundle exec pod install 명령어를 실행하니, 의존성을 분석하는 듯 싶다가 갑자기 에러를 주르륵 뱉습니다. 에러 로그의 #### Error 항목을 보면 에러 메시지가 나와있습니다.NoMethodError - undefined method `to_ary’ for #이 에러 메시지로 CocoaPods GitHub 저장소의 이슈를 검색해보면 꽤나 많은 이슈가 올라와 있습니다. 이 이슈들을 보면, 모두 Ruby 버전이 2.3이라는 공통점이 있습니다. Ruby 버전을 2.2로 내렸더니 문제가 해결됐다는 댓글들도 굉장히 많고요. Circle CI의 Ruby 버전을 2.2로 낮추면 문제가 해결될 것 같습니다.Circle CI 문서 내용에 따라 circle.yml에 Ruby 버전을 기재해봅시다.machine: ruby: version: 2.2.5 그러나 Circle CI의 OS X 컨테이너에서는 Ruby 버전 변경을 지원하지 않는다고 합니다.▲ ㅠㅠ (2)4. rbenv를 이용해서 Ruby 2.2 사용하기그러다가 알게된 것이 바로 rbenv입니다. rbenv를 사용하면 여러개의 Ruby 버전을 깔끔하게 관리할 수 있게 됩니다. rbenv는 Homebrew를 사용해서 쉽게 설치할 수 있습니다.$ brew install rbenv rbenv는 ~/.rbenv 디렉토리에 안에 여러 Ruby 버전을 설치하고 관리합니다. rbenv를 설치한 뒤 가장 먼저 할 일은 환경변수 $PATH를 설정해주는 것입니다. $PATH에는 $HOME/.rbenv/shims와 $HOME/.rbenv/bin 경로가 포함되어있어야 합니다.4.1 환경변수 설정하기Circle CI에서는 환경변수를 설정하는 편리한 인터페이스를 제공합니다. 하지만, Circle CI에서 실행되는 각 명령어는 별도의 쉘에서 실행됩니다. 그말인 즉슨, 각 명령어가 실행되기 직전에 새로운 쉘이 실행되고, $PATH 환경변수를 덮어쓰는 .bash_profile이 실행된 후 명령어가 실행된다는 뜻인데요. 이렇게 될 경우 $PATH 환경변수의 가장 우선순위는 항상 /usr/local/bin이 가지게 됩니다. 그리고 같은 이유로 $ export FOO=bar와 같은 명령어도 사용할 수 없게 됩니다.1고민을 하다가 생각해낸 방법은 바로 .bash_profile의 내용을 변경(!)하는 것입니다. 그렇게 되면 우리가 원하는 $PATH를 항상 우선순위로 둘 수 있게 됩니다. 아래와 같이 환경변수를 설정하는 명령어를 .bash_profile의 가장 아랫줄에 삽입하도록 설정했습니다.machine: pre: - echo "export PATH=\$HOME/.rbenv/shims:\$HOME/.rbenv/bin:\$PATH" >> .bash_profile - echo "export RBENV_SHELL=bash" >> .bash_profile 4.2 rbenv에 Ruby 2.2 설치하기그 다음으로 할 일은 원하는 Ruby 2.2 버전을 설치하는 것입니다. $ rbenv install -l을 사용해서 설치 가능한 모든 Ruby 버전을 조회할 수 있고, $ rbenv install 2.2.5 명령어를 사용해서 2.2.5 버전을 설치할 수 있습니다.$ rbenv install -l Available versions: 1.8.5-p113 1.8.5-p114 1.8.5-p115 1.8.5-p231 ... $ rbenv install 2.2.5 이렇게 설치된 버전은 두 가지 방법으로 사용될 수 있습니다. 한 가지 방법은 시스템 전체에서 사용하는 것이고, 다른 한 가지 방법은 프로젝트 단위로 사용하는 방법입니다. 시스템 전체에서 사용하려면 $ rbenv global 2.2.5 명령어를, 프로젝트 단위로 사용하려면 $ rbenv local 2.2.5명령어를 사용합니다.global 명령어를 사용해서 Ruby 버전을 선택하면 ~/.rbenv/version 파일에 선택된 버전이 기록됩니다.$ rbenv global 2.2.5 $ cat ~/.rbenv/version 2.2.5 local 명령어를 사용하면 현재 디렉토리의 .ruby-version 파일에 선택된 버전이 기록됩니다.$ rbenv local 2.2.5 $ cat .ruby-version 2.2.5 local 명령어로 선택된 Ruby 버전은 global 명령어로 선택된 Ruby 버전보다 우선순위가 높습니다. $ rbenv version 명령어를 사용하면 현재 선택된 버전을 확인할 수 있습니다.$ rbenv version 2.2.5 (set by /project/path/.ruby-version) Circle CI에서는 편의를 위해 global 명령어를 사용해서 Ruby 버전을 선택하도록 했습니다.dependencies: pre: - brew update - brew install rbenv - rbenv install 2.2.5 - rbenv global 2.2.5 4.3 Bundler 다시 설치하기rbenv를 사용해서 새로운 Ruby 버전을 설치했기 때문에, Circle CI 시스템에서 제공하는 Gem도 다시 설치해야 합니다. 우리는 Bundler로 Gem 의존성을 관리하기로 했으므로, Bundler만 재설치합니다.$ gem install bundler --no-ri --no-rdoc $ rbenv rehash $ gem install 명령어를 실행한 후에는 $ rbenv rehash 명령어를 실행해서 executable 경로들을 재설정해주어야 합니다.4.4 ~/.rbenv 경로 캐싱하기rbenv를 사용해서 Ruby를 설치하는 과정이 굉장히 오래 걸립니다. 이 경우, Circle CI에서 제공하는 캐싱 기능을 사용해서 이 과정을 한 번만 하고 건너뛸수 있게 됩니다.dependencies: cache_directories: - ~/.rbenv 위와 같이 circle.yml를 설정해주면 컨테이너 실행시 ~/.rbenv 디렉토리가 캐시로부터 설정됩니다. 캐싱된 디렉토리를 사용하는 경우 Ruby 버전이 미리 설치되어있기 때문에 $ rbenv install시에 --skip-existing 옵션을 추가해주어서 캐싱된 버전을 재설치하지 않도록 합니다.5. 마치며최종적으로 완성된 Gemfile과 circle.yml 파일은 다음과 같습니다.Gemfilesource 'https://rubygems.org' gem 'cocoapods', '~> 0.39' circle.ymlmachine: pre: - echo "export PATH=\$HOME/.rbenv/shims:\$HOME/.rbenv/bin:\$PATH" >> .bash_profile - echo "export RBENV_SHELL=bash" >> .bash_profile xcode: version: 7.3 dependencies: cache_directories: - ~/.rbenv pre: - brew update - brew install rbenv - rbenv install 2.2.5 --skip-existing - rbenv global 2.2.5 - gem install bundler --no-ri --no-rdoc - rbenv rehash - bundle install --path vendor/bundle override: - bundle exec pod --version - bundle exec pod install https://circleci.com/docs/environment-variables/#custom ↩#스타일쉐어 #개발 #개발자 #개발팀 #후기 #일지 #인사이트
조회수 8287

Node.js로 Amazon DynamoDB 사용하기

DynamoDB 로컬 설정 (다운로드 버전)실제 DynamoDB 웹 서비스에 액세스하지 않고 로컬에서 애플리케이션 작성 및 테스트를 할 수 있음1. 다운로드 링크에서 DynamoDB 무료 다운로드2. 압축 해제 후 해당 디렉터리에서 아래의 명령어로 실행java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb* Ctrl+C로 중지할 수 있고 중지하기 전까지 수신 요청을 처리함* 기본적으로 8000번 포트를 사용Node.js 용 AWS SDK 설치1. 설치npm install aws-sdk2. 실행// app.jsvar AWS = require("aws-sdk");var s3 = new AWS.S3();// 버킷 이름은 모든 S3 사용자에게 고유한 것이어야 합니다.var myBucket = "dynamodb.sample.wonny";var myKey = "myBucketKey";s3.createBucket({ Bucket: myBucket }, function(err, data) {  if (err) {    console.log(err);  } else {    params = { Bucket: myBucket, Key: myKey, Body: "Hello!" };    s3.putObject(params, function(err, data) {      if (err) {        console.log(err);      } else {        console.log("Successfully uploaded data to myBucket/myKey");      }    });  }});node app.js테이블 생성// CreateTable.jsvar AWS = require("aws-sdk");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var dynamodb = new AWS.DynamoDB();var params = {  TableName: "Movies",  KeySchema: [    { AttributeName: "year", KeyType: "HASH" }, // Partition key    { AttributeName: "title", KeyType: "RANGE" } // Sort key  ],  AttributeDefinitions: [    { AttributeName: "year", AttributeType: "N" },    { AttributeName: "title", AttributeType: "S" }  ],  // 다운로드 버전인 경우 아래 코드 무시  ProvisionedThroughput: {    ReadCapacityUnits: 10,    WriteCapacityUnits: 10  }};dynamodb.createTable(params, function(err, data) {  if (err) {    console.log(      "Unable to create table. Error JSON: ",      JSON.stringify(err, null, 2)    );  } else {    console.log(      "Created table. Table description JSON: ",      JSON.stringify(data, null, 2)    );  }});node CreateTable.js샘플 데이터 로드1. 이곳에서 샘플 데이터 파일 다운로드데이터 형태는 아래와 같음[    {        "year": 2013,        "title": "Rush",        "info": {            "directors": ["Ron Howard"],            "release_date": "2013-09-02T00:00:00Z",            "rating": 8.3,            "genres": [                "Action",                "Biography",                "Drama",                "Sport"            ],            "image_url": "http://ia.media-imdb.com/images/M/MV5BMTQyMDE0MTY0OV5BMl5BanBnXkFtZTcwMjI2OTI0OQ@@._V1_SX400_.jpg",            "plot": "A re-creation of the merciless 1970s rivalry between Formula One rivals James Hunt and Niki Lauda.",            "rank": 2,            "running_time_secs": 7380,            "actors": [                "Daniel Bruhl",                "Chris Hemsworth",                "Olivia Wilde"            ]        }    },    ...]- year 및 title을 Movies 테이블을 위한 기본 키 속성 값으로 사용- info의 나머지 값들은 info라는 단일 속성에 저장- JSON을 DynamoDB 속성에 저장2. 샘플 데이터 Movies 테이블에 로드// LoadData.jsvar AWS = require("aws-sdk");var fs = require("fs");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();console.log("Importing movies info DynamoDB. Please wait.");var allMovies = JSON.parse(fs.readFileSync("moviedata.json", "utf8"));allMovies.forEach(function(movie) {  var params = {    TableName: "Moves",    Item: {      year: movie.year,      title: movie.title,      info: movie.info    }  };  docClient.put(params, function(err, data) {    if (err) {      console.error(        "Unable to add movie",        movie.title,        ". Error JSON:",        JSON.stringify(err, null, 2)      );    } else {      console.log("PutItem succeeded:", movie.title);    }  });});node LoadData.js테이블에 항목 추가// PutItem.jsvar AWS = require("aws-sdk");var fs = require("fs");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var table = "Movies";var year = 2017;var title = "The Big Wonny";var params = {  TableName: table,  Item: {    year: year,    title: title,    info: {      plot: "Nothing happens at all.",      rating: 0    }  }};console.log("Adding a new item...");docClient.put(params, function(err, data) {  if (err) {    console.error(      "Unable to add item. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    console.log("Added item:", JSON.stringify(data, null, 2));  }});node PutItem.js- 기본 키가 필요하므로 기본 키 (year, title) 및 info 속성 추가항목 읽기// GetItem.jsvar AWS = require("aws-sdk");var fs = require("fs");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var table = "Movies";var year = 2017;var title = "The Big Wonny";var params = {  TableName: table,  Key: {    year: year,    title: title  }};docClient.get(params, function(err, data) {  if (err) {    console.error(      "Unable to read item. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    console.log("GetItem succeeded:", JSON.stringify(data, null, 2));  }});node GetItem.js항목 업데이트// UpdateItem.jsvar AWS = require("aws-sdk");var fs = require("fs");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var table = "Movies";var year = 2017;var title = "The Big Wonny";var params = {  TableName: table,  Key: {    year: year,    title: title  },  UpdateExpression: "set info.rating = :r, info.plot=:p, info.actors=:a",  ExpressionAttributeValues: {    ":r": 5.5,    ":p": "Everything happens all at once.",    ":a": ["Larry", "Moe", "Curly"]  },  ReturnValues: "UPDATED_NEW"};console.log("Updating the item...");docClient.update(params, function(err, data) {  if (err) {    console.error(      "Unable to update item. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2));  }});node UpdateItem.js- 지정된 항목에 대해 수행하고자 하는 모든 업데이트를 설명하기 위해 UpdateExpression을 사용- ReturnValues 파라미터는 DynamoDB에게 업데이트된 속성("UPDATED_NEW")만 반환하도록 지시원자성 카운터 증가시키기update 메서드를 사용하여 다른 쓰기 요청을 방해하지 않으면서 기존 속성의 값을 증가시키거나 감소시킬 수 있음 (모든 쓰기 요청은 수신된 순서대로 적용)실행 시 rating 속성이 1씩 증가하는 프로그램// Increment.jsvar AWS = require("aws-sdk");var fs = require("fs");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var table = "Movies";var year = 2017;var title = "The Big Wonny";// Increment an atomic countervar params = {  TableName: table,  Key: {    year: year,    title: title  },  UpdateExpression: "set info.rating = info.rating + :val",  ExpressionAttributeValues: {    ":val": 1  },  ReturnValues: "UPDATED_NEW"};console.log("Updating the item...");docClient.update(params, function(err, data) {  if (err) {    console.error(      "Unable to update item. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2));  }});node Increment.js항목 업데이트(조건부)UpdateItem을 조건과 함께 사용하는 방법조건이 true로 평가되면 업데이트가 성공하지만 그렇지 않으면 수행되지 않음// ConditionalUpdateItem.jsvar AWS = require("aws-sdk");var fs = require("fs");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var table = "Movies";var year = 2017;var title = "The Big Wonny";// Increment an atomic countervar params = {  TableName: table,  Key: {    year: year,    title: title  },   UpdateExpression: "remove info.actors[0]",  ConditionExpression: "size(info.actors) > :num",  ExpressionAttributeValues: {    ":num": 3  },  ReturnValues: "UPDATED_NEW"};console.log("Attempting a conditional update...");docClient.update(params, function(err, data) {  if (err) {    console.error(      "Unable to update item. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2));  }});node ConditionalUpdateItem.js다음과 같이 작성하면 아래와 같은 에러 메시지가 표시 됨The conditional request failed"영화에는 3명의 배우가 있는데 배우가 3명보다 많은지를 확인하고 있어 에러가 발생다음과 같이 수정하면 정상적으로 항목이 업데이트 됨ConditionExpression: "size(info.actors) >= :num",항목 삭제// DeleteItem.jsvar AWS = require("aws-sdk");var fs = require("fs");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var table = "Movies";var year = 2017;var title = "The Big Wonny";var params = {  TableName: table,  Key: {    year: year,    title: title  },  ConditionExpression: "info.rating <= :val",  ExpressionAttributeValues: {    ":val": 5.0  }};console.log("Attempting a conditional delete...");docClient.delete(params, function(err, data) {  if (err) {    console.error(      "Unable to update item. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));  }});node DeleteItem.js다음과 같이 작성하면 아래와 같은 에러 메시지가 표시 됨The conditional request failed특정 영화에 대한 평점이 5보다 크기 때문에 에러가 발생다음과 같이 수정하면 정상적으로 항목이 삭제 됨var params = {  TableName: table,  Key: {    year: year,    title: title  }};데이터 쿼리- 파티션 키 값을 지정해야 하며, 정렬 키는 선택 사항- 1년 동안 개봉한 모든 영화를 찾으려면 year만 지정, title을 입력하면 2014년 개봉된 "A"로 시작하는 영화를 검색하는 것과 같이 정렬 키에 대한 어떤 조건을 바탕으로 일부 영화를 검색할 수도 있음한 해 동안 개봉한 모든 영화// QueryYear.jsvar AWS = require("aws-sdk");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var params = {  TableName: "Movies",  KeyConditionExpression: "#yr = :yyyy",  ExpressionAttributeNames: {    "#yr": "year"  },  ExpressionAttributeValues: {    ":yyyy": 1985  }};docClient.query(params, function(err, data) {  if (err) {    console.error("Unable to query. Error JSON:", JSON.stringify(err, null, 2));  } else {    console.log("Query succeeded.");    data.Items.forEach(function(item) {      console.log(" -", item.year + ": " + item.title);    });  }});node QueryYear.jsExpressionAttributeNames는 이름을 교체함. 이를 사용하는 이유는 year가 DynamoDB에서 예약어이기 때문. KeyConditionExpression을 포함해 어떤 표현식에서도 사용할 수 없으므로 표현식 속성 이름인 #yr을 사용하여 이를 지칭ExpressionAttributeValues는 값을 교체함. 이를 사용하는 이유는 KeyConditionExpresssion을 포함해 어떤 표현식에서도 리터럴을 사용할 수 없기 때문. 표현식 속성 값인 :yyyy를 사용해 지칭* 위의 프로그램은 기본 키 속성으로 테이블을 쿼리하는 방법. DynamoDB에서 1개 이상의 보조 인덱스를 테이블에 생성하여 그 인덱스로 테이블을 쿼리하는 것과 동일한 방식으로 쿼리 작업 가능. 보조 인덱스는 키가 아닌 속성에 대한 쿼리를 허용하여 애플리케이션에 더 많은 유연성을 부여함한 해 동안 개봉한 모든ㄴ 영화 중에 특정 제목을 지닌 영화year 1992에 개봉한 영화 중에 title이 "A"부터 "L"까지의 알파벳으로 시작하는 영화를 모두 조회합니다.// QueryTitle.jsvar AWS = require("aws-sdk");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();console.log(  "Querying for movies from 1992 - titles A-L, with genres and lead actor");var params = {  TableName: "Movies",  ProjectionExpression: "#yr, title, info.genres, info.actors[0]",  KeyConditionExpression: "#yr = :yyyy and title between :letter1 and :letter2",  ExpressionAttributeNames: {    "#yr": "year"  },  ExpressionAttributeValues: {    ":yyyy": 1992,    ":letter1": "A",    ":letter2": "L"  }};docClient.query(params, function(err, data) {  if (err) {    console.error("Unable to query. Error JSON:", JSON.stringify(err, null, 2));  } else {    console.log("Query succeeded.");    data.Items.forEach(function(item) {      console.log(        " -",        item.year + ": " + item.title + " ... " + item.info.genres + " ... ",        item.info.actors[0]      );    });  }});node QueryTtiel.js스캔테이블의 모든 항목을 읽고 테이블의 모든 데이터를 반환선택 사항인 filter_expression을 제공할 수 있으며 그 결과 기준이 일치하는 항목만 반환하지만 필터는 테이블 전체를 스캔한 후에만 적용됨// Scan.jsvar AWS = require("aws-sdk");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var docClient = new AWS.DynamoDB.DocumentClient();var params = {  TableName: "Movies",  ProjectionExpression: "#yr, title, info.rating",  FilterExpression: "#yr between :start_yr and :end_yr",  ExpressionAttributeNames: {    "#yr": "year"  },  ExpressionAttributeValues: {    ":start_yr": 1950,    ":end_yr": 1959  }};console.log("Scanning Movies table.");docClient.scan(params, onScan);function onScan(err, data) {  if (err) {    console.error(      "Unable to scan the table. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    // print all the movies    console.log("Scan succeeded.");    data.Items.forEach(function(movie) {      console.log(        movie.year + ": ",        movie.title,        "- rating:",        movie.info.rating      );    });    // continue scanning if we have more movies, because    // scan can retrieve a maximum of 1MB of data    if (typeof data.LastEvaluatedKey != "undefined") {      console.log("Scanning for more...");      params.ExclusiveStartKey = data.LastEvaluatedKey;      docClient.scan(params, onScan);    }  }}node Scan.jsProjectionExpression은 스캔 결과에서 원하는 속성만 지정FilterExpression은 조건을 만족하는 항목만 반환하도록 조건을 지정. 다른 항목들은 모두 무시됨테이블 삭제// DeleteTable.jsvar AWS = require("aws-sdk");AWS.config.update({  region: "us-west-2",  endpoint: "http://localhost:8000"});var dynamodb = new AWS.DynamoDB();var params = {  TableName: "Movies"};dynamodb.deleteTable(params, function(err, data) {  if (err) {    console.error(      "Unable to delete table. Error JSON:",      JSON.stringify(err, null, 2)    );  } else {    console.log(      "Deleted table. Table description JSON:",      JSON.stringify(data, null, 2)    );  }});node DeleteTable.js#트레바리 #개발자 #안드로이드 #앱개발 #Node.js #백엔드 #인사이트 #경험공유 #데이터베이스 #DB #개발 #AWS #아마존 #NoSQL 
조회수 1090

꿈에 대한 이야기

꿈꾸는 사람이 아름답다는 말에프로불편러, 참견쟁이로 한 마디 하자면,아름답기만 하지 뭐~!그래서 뭐!진짜 아름다움은 꿈을 가진게 아니라꿈을 만들어가는 과정과꿈을 현실화 한 사람이 아닐까?문득 꿈에 대한 글을 쓰고 싶어서괜스레 딴죽걸어봤다.이번에는 내가 생각하는 꿈에 대한 이야기다.1. 꿈은 명사가 아니라 동사다.(이건 어떤 강연에서 감명 깊게 듣고 마음에 새긴 말이다)무엇이 되겠다 것은 꿈이 아니라 직업을 이야기 하는 것일 뿐.무엇이 되어 어떻게 하겠다가 중요하다.이해를 쉽게하기 위해서 예를들자면,단지 회사를 설립해서 CEO가 되겠다는 직업이다.세계 어느 매장에서든 구매할 수 있는 제품을 만들어내는 CEO가 꿈이다.의사가 되겠다는 직업에 대한 희망사항이고,의료혜택을 못 받은 환자들을 찾아가는 활동을 하는 의사가 꿈이다.법의 테두리 안에서 보호 받지 못하는 사람들을 찾아가는 변호사,헐리우드 배우들이 입고 싶어 줄을 서는 옷을 디자인하는 디자이너,범죄를 죄다 소탕하기 위해 불철주야 현장을 뛰는 정의의 형사...꿈이라는 것은 마치 생명체와 같아서움직이고, 변화하고, 진화한다.돈을 많이 버는 것은 꿈이 아니라 수단이다.많이 돈을 벌어서 어떻게 하겠다는 것이 꿈이다.2. 꿈에도 사이즈가 있다.나 혼자 꿈의 영향을 받는 사이즈와지인정도 영향력을 미치는 사이즈,나를 모르는 사람들까지 확장되는 사이즈,전 지구적인 스케일의 꿈도 있다.물론 무엇이 더 낫다라는 일차원적인 비교평가는 무의미하다.알아두어야 할 것은 꿈의 사이즈가 클 수록거기에 수반되는 자원(시간,돈,노력, 인력 등)도사이즈가 크다.계획의 정밀도와 실행의 완성도도 높아야 한다.연 매출 100억짜리 회사 사이즈를 상정한다면,무엇이 필요할 것이고,얼마나 투여될 것이고,어떻게 달성할 것인가에 대한 세부적인 명세가 있어야 한다.연 매출 10억짜리 회사 사이즈와 비교 하였을때,그 사이즈는 많은 부분에서 확연하게 다르다.100억짜리 회사 매출 사이즈에서 내가 달성한 것이 70%라면,70억짜리 회사 매출 사이즈에 도달하는 것이다.10억짜리 회사 매출 사이즈에서 동일하게 70% 달성하면,7억짜리 회사 매출 사이즈를 기대할 수 있다.무조건 큰 사이즈의 꿈을 고려하라는 것은 아니지만,한계를 너무 미리, 성급하게, 작게 설정하면,그만큼 확장성이 떨어진다는 점은 분명하다.3. 꿈이 있다고 만족하지 말 것.꿈이 없는 것보다는 있는게 더 낫다고 하지만,꿈이 있다고 만족하지 마라.꿈에 계획이 없으면, 개꿈이다.꿈에 실행의지가 없으면, 공상이다.꿈에 참여자가 없으면, 망상이다.꿈이 없는 사람들과꿈이 있는 사람들의 차이점을 분별하기는 어렵지만,꿈을 구현하고 있는 사람들은확연하게 구분이 간다.청소년기에 꿈을 가져라라는 말을귀에 못 박히도록 들어왔다.청년기에는 꿈을 키워라라는 물음을 자주 접하게 되었다.그리고 지금은 꿈에 대한 이야기보다꿈을 이루기 위해 무얼 하고 있니에 대한질문을 받기 시작했다.어서 빨리 우리의 꿈을고객들에게 나누고, 보여주고 싶다.훗날에는 그 꿈에 얼마나 가까워졌는지를 묻겠지?우리가 꿈을 꾸는 시간은 언제일까?밤에 잠들어버리고?아니다.우리들은 낮에도 꿈을 꾸는 사람들이다.밤이고, 낮이고항상 꿈을 떠올리는 사람들이다.그리고 그 꿈을 되씹고, 즐기고, 맛보면서더 크게 꿈을 만들어가는 사람들이다.때로는창업자에게 꿈이란 것이일장춘몽과 같이 하룻밤의 꿈이 되어 날아가버릴 수도 있다.(그만큼 항상 리스키하게 살아간다)그래도 우리는 지금 이순간꿈에 기대어 살아가고 있다.
조회수 836

마케터를 위한 딥 링크 만들기

더 나은 사용자 경험 딥 링크(Deep Linking)는 사용자를 최종 목적지로 곧장 연결시켜 줍니다. 따라서 즉각적인(On-demand) 해결이 필요한 니즈를 가진 사용자일수록 딥 링크를 통해 복잡한 이동 과정을 생략할 수 있으며, 이는 더 나은 사용자 경험으로 이어집니다.광고에서 매력적인 상품을 발견한 사용자는 광고 클릭, 앱 설치, 앱 실행의 과정을 거치게 됩니다. 해당 상품에 대한 실제 정보는 앱 초기화면에서 검색을 거친 후에나 확인 가능합니다. 하지만 광고에 딥 링크가 적용되어 있으면 사용자는 앱 실행 후 곧바로 광고에서 봤던 상품으로 이동합니다. 따라서 딥 링크는 마케팅 메시지와 랜딩 페이지 사이의 일관성을 유지시키는 역할을 합니다.(딥 링크를 적용하여 마케팅 메시지와 랜딩 페이지의 일관성이 유지되며 최종 페이지로의 이동단계는 축소됩니다. 이를 통해 사용자 경험을 높일 수 있습니다.)딥 링크 찾기이 딥 링크 활용이 쉽지 않은 이유는 딥 링크를 어디에서 찾아야 할 지 알 수 없기 때문입니다. 딥 링크는 웹사이트 URL처럼 쉽게 확인할 수 없으며, 앱을 만들면서 자동으로 생성되지 않습니다. 그렇다면 딥 링크는 어떻게 만드는 것일까요?딥 링크 생성 프로세스를 단순화하면 다음과 같이 표현할 수 있습니다.마케터가 딥 링크 요청 -> 개발자가 딥 링크 생성 -> 마케터가 딥 링크 적용마케터는 앱 빌드를 하지 않기 때문에 딥 링크를 직접 만들기 어렵습니다. 결국 개발자의 도움이 필요합니다. 따라서 이 부분에선 두 번째 단계인 딥 링크 생성을 마케터가 알기 쉽게 설명하려고 합니다. 생성 작업을 알게 되면 개발자와 원활하게 커뮤니케이션 할 수 있고, 이를 통해 작업의 효율성도 높아질 것이라 기대합니다.딥 링크 만들기마케터의 요청을 받은 개발자가 딥 링크를 생성하기 위해 어떤 작업을 하게 되는지 작업 순서대로 설명 하겠습니다. 이해를 돕기 위해 안드로이드 기준으로 말씀 드리겠습니다.(1) 안드로이드 매니페스트와 액티비티“이 화면으로 연결되는 딥 링크를 만들어 주세요”라고 요청이 왔다고 가정하겠습니다. 개발자는 그 화면에 해당하는 액티비티(Activity)를 안드로이드 매니페스트(Android Manifest) 파일에서 찾습니다.안드로이드 매니페스트 파일은 앱의 모든 구성요소가 설명되어 있는 명세서라고 이해하시면 좋습니다. 앱에 어떤 기능을 만들어 놓았더라도, 안드로이드 매니페스트에 그 기능이 기술되어 있지 않다면 그 기능은 존재하지 않는 것과 마찬가지입니다. 따라서 딥 링크로 연결할 화면 역시 안드로이드 매니페스트에 존재하고 있으며, 개발자는 이 액티비티에 딥 링크를 지정하기 위해 안드로이드 매니페스트를 수정하게 됩니다.(2) 인텐트 필터 추가앱 입장에서 생각해 보면 인텐트 필터(Intent-filter)를 쉽게 이해할 수 있습니다. 가만히 있던 앱은 갑작스럽게 딥 링크를 통해서 앱의 특정 액티비티를 열어달라는 호출을 받게 됩니다. 호출 받은 입장에서는 어떤 의도(Intent)로 호출을 했는지 요약된(filter) 설명을 들을 수 있으면 좋겠지요. 인텐트 필터는 위와 같이 액티비티를 호출하기 위한 목적과 방법을 앱에 알려주는 역할을 합니다.개발자는 안드로이드 매니페스트에서 딥 링크로 연결될 액티비티를 찾은 뒤, 특정 딥 링크에서 호출이 오면 이 액티비티를 열면 된다는 명령을 미리 기술하게 됩니다. 위의 설명이 실제로 어떻게 구현되는지 예제를 보면서 확인하겠습니다.123456789101112131415161718192021222324<!-- 딥 링크로 호출할 액티비티 입니다 -->    android:name="com.example.android.GizmosActivity"    android:label="@string/title_gizmos" >    <!-- 인텐트 필터가 추가되었습니다 -->                                    <!-- "http://www.example.com/gizmos”라는 URI를 허용합니다 -->                     android:host="www.example.com"              android:pathPrefix="/gizmos" />        <!-- note that the leading "/" is required for pathPrefix-->                                       <!-- "example://gizmos”라는 URI를 허용합니다 -->                     android:host="gizmos" />   (Source: 구글 개발자 사이트)“com.example.android.GizmosActivity”라는 액티비티를 호출하기 위해 를 추가한 코드입니다.  항목은 화면 조회를,  항목은 브라우저에서 앱을 호출할 수 있도록 하는 역할을 하며, 딥 링크 구현을 위해서 기본적으로 포함되어야 하는 항목입니다.(3) 딥 링크 주소 생성 하위에  항목에서 딥 링크 주소를 ‘지정’할 수 있습니다. 없던 주소를 새로 만드는 것이기 때문에 주소에 어떤 문자열을 사용할지 지정해줘야 합니다. 일반적으로 개발팀 내부 규칙을 따르게 됩니다.딥 링크 주소는 보통 커스텀 URI, 커스텀 스킴 등으로 부릅니다. 예제에서 두번째  항복을 보면 scheme으로 example을, host로 gizmos를 지정하고 있습니다. 스킴과 호스트를 조합한 것이 딥 링크 주소로 사용됩니다. 예제의 경우엔 example://gizmos가 딥 링크 주소가 됩니다. 결과적으로 사용자가 example://gizmos URI가 적용된 광고를 클릭하면 “com.example.android.GizmosActivity” 화면이 호출되며 앱이 실행됩니다.보완책: DEFERRED DEEP LINK딥 링크는 앱의 특정 화면을 호출합니다. 하지만 앱이 없는 사용자가 광고를 클릭한다면 어떻게 될까요? 아무런 동작도 일어나지 않을 것이고 어렵게 확보한 클릭을 잃게 되는 결과로 이어질 것입니다. 이런 경우의 보완책으로 와이즈트래커는 지연된 딥 링크(Deferred Deep Link)를 채택하고 있습니다.위 그림에서 볼 수 있듯이, 앱을 설치한 사용자가 광고를 클릭하면 특정 화면이 호출된 상태로 앱이 실행됩니다. 앱을 설치하지 않은 사용자가 광고를 클릭하면 우선 앱 마켓으로 이동하게 되며, 사용자가 앱을 설치한 후 최초 실행시 딥 링크가 호출하려던 화면이 나타나게 됩니다.만약 지연된 딥 링크가 없다면 사용자 경험을 설계하는데 상당히 많은 경우의 수가 생깁니다. 당연히 캠페인 기획, 실행, 운영 시에 고려할 사항도 크게 늘어나게 됩니다. 따라서 딥 링크를 사용하기로 결정 했다면 와이즈트래커와 같은 3rd Party를 통해 더욱 고도화된 기능의 장점을 충분히 활용하시면 좋겠습니다.
조회수 1417

세상에 정답은 없다

2016년 4월 18일자 이코노미스트 칼럼에 기고가 되었던 글을 다시 올립니다."중앙시사매거진 (이코노미스트): 세상에 정답은 없다"최근 회사에서 신입사원 면접을 보는 자리에서 면접자가 나에게 이렇게 물었다. “왜대표님은 좋은 학교를 졸업하고 좋은 커리어를 가지고 있으면서 왜 안정적인 대기업에 취직하지 않고 창업을 하셨나요?”사실 이런 질문은 언론 인터뷰 때나 대학생들을 위한 강연자리에서 종종 받는 질문이다. 난내가 하고 싶은 일을 하면서 행복하게 사는 삶을 선택하는 자연스러운 선택을 했지만, 이런 질문을 받을때마다 나의 선택이 우리 사회가 가지고 있는 일반적인 정답에는 벗어난 선택이라는 것을 깨닫게 된다.한국 사회의 일반적인 정답은 이렇다. 좋은 학교를 가기 위해 열심히공부하고, 좋은 학교를 나온 이후에는 안정적이고 돈 많이 버는 직업을 찾아서 전문직, 공무원, 대기업 순으로 직업을 선택하고 남자는 30대 중반, 여자는 30대초반에는 결혼을 하고 아이를 가져야 한다. 이 범주에서 벗어나면 좀 이상한 사람이고 주위에서 걱정을하기 시작한다. 이렇게 다양성을 인정하지 않는 사고체계의 원인은 여러 가지가 있을 수 있지만 난 가장큰 원인을 한국의 교육 시스템으로부터 온다고 생각한다. 토론이 없는 수업, 하나의 정답을 가진 시험, 모두가 똑같은 옷을 입고, 심지어 같은 헤어스타일을 강요하기도 한다. 이러한 교육을 통해서우리는 다양성의 인정보다는 획일성과 하나의 정답에 익숙해진다.한국 사회에는 학문이나 삶에서나 모두 하나의 정답을 추구한다. 그렇기때문에 본인이 생각하는 정답과 다른 정답을 가진 사람들을 인정하지 않는다. 토론을 하는 것도 내가 가진정답을 다름 사람에게 설득시키는 것이 목적이지 공동의 해결책을 찾기 위한 토론이 아니다. 이러한 현상은사회, 정치, 경제 모든 분야에 있어 나타나고 있다. 제자들은 감히 스승이 세운 이론에 반박하지 못하고, 부하직원은 감히상사의 의견에 반대하지 못한다. 그리고 자식들은 부모가 제시하는 삶의 방향을 벗어나지 못한다.미국 MBA 유학시절 토론 수업 뒤에 도저히 수업의 결론이 무엇인지이해가 가지 않아서 수업이 끝나고 교수에게 물어 본적이 있다. “도대체 정답이 뭔가요?” 교수는 나를 의아한 눈으로 쳐다보면서 수업시간에 나왔던 모든 답들이 정답이라고 대답해주었다. 그리고 우리는 답을 찾는 것이 아니라 각자의 답을 찾은 방법을 훈련하는 것이라는 이야기도 해주었다.현대 사회는 정보화 시대를 넘어서 인공 지능 혁명의 시대로 넘어가고 있다. 우리는최신 지식을 쉽고 빠르게 얻을 수 있고, 패턴화된 답을 쉽게 찾아낼 수 있는 시대에 살고 있다. 지식의 양과 정해진 정답을 빠르게 찾아내는 능력은 이제 인간의 경쟁력이 될 수 없다. 정해진 정답을 빠르게 찾는 훈련보다는 적절한 질문을 통해서 나만의 새로운 답을 만들어 낼 수 있는 능력을 길러야한다. 인류가 인공지능을 능가할 수 있는 가장 큰 무기는 호기심이다.호기심을 통해 문제를 발견하는 능력, 그리고 기존의 정답에 반기를 들고 창조적인 새로운답을 찾아내는 능력을 길러내기 위해서는 다양성을 인정하고 끊임없이 호기심을 자극하는 교육이 되어야 한다. 이것이우리 다음 세대를 새로운 인공지능 혁명시대에 준비시키는 방법이다. 하루 10시간씩 책상에 앉아서 교과서와 참고서를 외우고 선생님의 수업을 무비판적으로 수용하는 교육으로는 우리는 다음 세대를 준비할 수 없다. 그래서 난 정답 없는 사회를 꿈꾼다.#NEOFECT #스타트업 #스타트업창업 #창업자 #스타트업CEO #CEO가하는일
조회수 627

개선은 혁신이 아니다

매일 혁신을 얘기하는 나라유럽에서 온 한 외국인 임원이 한국의 조직에서 의아한 경험을 하고 있다고 들었다.매일 매일 어떤 미팅에 들어가더라도 '혁신'이라는 말이 끊이지 않고, 모두가 '혁신'을 얘기하고 있다는 것이다.'혁신'을 하자라는 것이 잘 못되었다고 생각한 것은 아닐 것이다. '혁신'이 중요하다는 것을 공감하지 못하는 것도 아닐테니까 말이다. 아마도 아무나, 그리고 너무나 혁신을 남발하기 때문에, 누구도 진지하게 혁신을 고민하지 않는다는 생각이 들었기 때문일 것이다.맞다.이젠 '혁신'이라는 말이 지긋지긋할 정도다.매년 끊이지 않고 혁신을 얘기하지만, 정작 혁신은 쉽게 찾아볼 수 없으니 말이다.어디 기업뿐이겠는가, 정치나 정부도 개혁과 혁신을 얘기하지만, 개혁은 개뿔~, 매번 후퇴의 연속이니 말이다.개선도 의미는 있다오히려, 거창한 혁신이 아니더라도, 소소한 개선들이 모여서 기업이나 또는 상품, 서비스가 점차 나아지게 하는 것이 훨씬 현실적이고 실용적일 수 있다.하지만, 치열한 경쟁 사회에서 '결정적 한방'을 꿈꾸는 이들에게 작은 개선으로는 성에 차지 않은가보다. 작은 여러차례의 잽보다는 결정적 어퍼커트 한방을 노리는 이들이 많은게 현실이다.문제는 잽과 어퍼커트를 구분하지 못한다는 것이다.몇 가지 제도의 변화를 만들어놓았으니 이제 새로운 조직, 새로운 시대가 열릴 것이라는 둥, 이만큼 서비스를 좋게 만들었으니 이제 대박이 날 것이라는 헛된 희망을 꿈꾸는 어리석음을 어렵지 않게 발견할 수 있다. 차라리 묵묵히 자기 분야에서 부족한 부분을 보완하고 꾸준히 개선하면, 이것들이 모여서 소리없이 긍정적인 효과를 만들어내는 것이 차라리 생산적이다.좋은 것들만 모아놓은게 혁신이 아니다사실, 혁신은 목표가 아니다. 혁신은 치열한 경쟁에서 살아남기 위한 도구이고, 지지부진한 변화를 벗어나기 근본적인 고민의 방식이다. 하지만, 혁신에 접근하는 방식을 살펴보면, 전혀 혁신적이지 않은 경우가 대부분이다.'난 이런 것이 필요하니까, 이 부분을 충족시켜주자', '난 이게 불편했는데, 이것을 좀더 편리하게 바꿔보자', '미흡했던 부분을 보완해보면, 사용자가 만족하지 않을까?' 류의 접근 방식이다.문제를 진단하고, 해결책을 모색하는 것은 너무나 당연한 프로세스이다. 다만, 대부분이 표면적인 현상의 문제에 국한하고 있다는 것이다.뿐만 아니라, 이것도 개선하고, 저것도 충족시켜주면 마치 모든 문제가 해결될 것이라는 생각, 그러면 정말 좋은 상품, 성공하는 서비스가 될 것이라는 착각에 빠지게 된다.하지만 이러한 방식은 이도 저도 아닌 결과를 만드는 전형적인 접근 방식이다. 의미가 없다는 것이 아니라, 혁신이 아니라는 것이다.One Clear Benefit혁신의 대상이 상품이라면, 그리고 경쟁에서 소비자에게 각인시키기 위해서는 '단 하나'의 명확한 차별화 요소가 있어야 한다.작은 여러 번의 잽이 아니라, 누구에게도 제공받지 못했던 결정적 한방, 너무나도 명확한 '그 하나'가 있어야 한다. 다른 것을 다 포기하더라도 단 하나 남겨놓을 수 있는 '그것'에 집중해야 한다. 그렇지 않다면, 레드오션의 늪에서 One of them이 될 가능성이 매우 높다.하지만, '그 하나'를 찾는 것은 보통 어려운 일이 아니다. 누구나 할 수 있다고 생각하지도 않는다.예를 들어보자...패러다임 체인저서양 미술사를 살펴보면, 명작을 남긴 훌륭한 화가들이 많이 존재하지만, 결정적으로 새로운 사조를 만들어내는 게임 체이저들은 따로 존재한다. 근현대 미술사에서 잘 알려져있는 인상주의 화가였던 클로드 모네는 자연을 하나의 색채 현상으로 보고, 빛과 함께 변화하는 색채의 미묘함을 묘사하는 방식으로 이전의 사실주의 작가들이 세상을 표현하는 방식과는 전혀 다른 형태로 그림을 바꾸었으며, 20세기 입체파의 대표적인 파블로 피카소는 사물이 보여지는 그대로가 아니라, 다양한 각도에서 바라보는 관점으로 사물을 해체하여 다시 조화롭게 접합하는 방식으로 새로운 미술사조를 이끌어갔다.기존의 패러다임을 바꾼다는 것은 쉬운 일이 아니다.모두가 합의하고 있는 생각을 틀을 깰 수 있어야 하고, '그림'이라는 본질로 돌아가서 무엇을 어떻게 표현해야 할지를 근본적으로 다시 재정의해야 하는 일이다. 스타일의 문제가 아니라, 그림을 바라보는 관점 자체를 바꿔야 가능한 일인 것이다.발상의 전환혁신을 얘기할 때, 근본으로 돌아가라, 본질을 파악하라라는 말을 많이 하지만, 어떻게 해야할지 모르는 사람들이 많다.사람들에게 의자를 그려보라고 하면, 다리가 4개이고, 엉덩이와 등을 받칠 수 있는 부분을 전형적인 의자의 모습을 대부분 그린다. 그리고 의자를 다시 디자인하라고 하면, 다리의 형태나 등받침의 높이나 형태를 변형하거나 새로운 재료로 바꾸는 등의 접근을 하기 마련이다. 하지만, 본래 '앉는다는 것'에 대한 행위와 목적으로 돌아가서 다시 생각해보면, 머리속에 그려져있는 통상적인 형태에서 벗어날 수 있게 된다. 다리와 등받침의 구분이 없는 전혀 새로운 방식으로 전혀 다른 의자가 나올 수도 있으며, 앉기 위한 도구가 아니라, 쉴수 있는 도구로 얼마든지 변형될 수도 있다는 것이다.다루고 있는 대상이 무엇이건 사람들이 그것을 필요로 하는 근본적인 이유와 애초의 본질로 다시 들어가서 생각해보면, 당장 보이지 않던 것이 보이기도 하고, 당장 문제로 인식하지 않았던 새로운 문제가 나타나게 된다. 그리고는 거기에서 부터 다시 고민을 시작해야 한다. 아직까지 눈에 보여지는 현상에 집착하고 있다면, 한 템포 쉬면서 근본으로 다시 돌아가라는 얘기이다.대전제를 재정의하라DESIGN이라는 말은 De + Sign의 조합된 표현이다. De는 Destruct (파괴하다), Sign은 Signature (상징)를 의미하는 것으로, 기존의 합의된 상징을 파괴하여, 새롭게 다시 생각하다라는 의미가 담겨있다고 한다. 통념을 깨고 다시 정의하는 작업, 모두가 당연하다고 생각하는 것을 다른 관점으로 보려는 노력이 혁신의 출발점이어야 한다.Design = Destruct + Signature요즘 기업들에서는 호칭을 변경하는 작업들이 유행처럼 번지고 있다. 직급을 부르는 대신, '님'이라는 호칭을 붙인다거나, 리더를 제외한 모든 사람들을 수평적으로 대하도록 인사제도를 변경하는 경우가 많아지고 있다. 상명하복의 의사결정 구조에서는 더이상 혁신이 나오기 어렵기 때문에, 조직에 변화를 주어 다양한 생각들이 존중받고 토론될 수 있게 하기위한 취지일 것이다. 선후배가 계급장 떼고 맞먹자는 것이 아니라, 누구든 관행과 관성에서 벗어나 본질에 대한 질문을 던지고, 다시 생각해볼 수 있는 기회를 확대하기 위한 것이다. 계급장 뗀다고, 혈기 왕성하다고 모두 혁신을 만들 수 있는 것은 아니다.누구든 대전제에 대한 문제제기를 할 수 있고, 백지에서 다시 시작할 수 있어야 혁신이 시작될 수 있다는 것이다.참으로 어려운 일이다.의식하지 못했던 가치를 인식하게 하는 것혁신하는 기업과 상품들을 자세히 살펴보면, 늘 비슷하게 느끼는 '충격'이 있다. 우리가 뒷통수 얻어맞았다고 표현하는 그런 감정 말이다.왜 우린 미처 생각하지 못했을까?대게 사람들은 모두가 중요하다고 생각하는 가치에 집중하면서, 그 가치를 더 빛나게 하려는 방식으로 접근하려는 경향이 있다.어쩌면 너무나 당연한 방식이고, 가장 확률이 높은 접근법이다. 누구도 부정하지 않을뿐만 아니라, 가장 안정적이기 때문이다.하지만, 누구나 아는 가치라면, 누구라도 비슷한 고민을 할 수 밖에 없다. 결국 같은 파이를 두고 싸우는 형태라는 것이다. 진짜 강자는 아무도 쳐다보지 않았던 영역에서 가치를 발굴해내는 연금술사 같은 존재들이다.사람들이 인식하지 못하는 가치를 찾는 일이기 때문에, 이런 일은 소비자 조사 따위로는 찾기 어렵다. 소비자가 표현할 수 있는 것은 현재 인식하고 있는 가치 수준에 머물러 있기 때문이다.인식하지 못하고 있는 가치를 찾는 방법이 필요하다.그렇다고 마냥, 억지를 부리라는게 아니라, 중요하지 않았던 가치를 중요하게 느끼게끔 만들어주는 실력이 필요하다.열심히 한다고 되는 것은 아니다과거의 생산성은 '성실'과 '효율성'에 기초를 두고 발전해 왔다. '창의'가 중요해지는 시대에는 '시간'이 중요한 것이 아니라, 다른 무언가가 필요하다.그냥 열심히 해본다고 되는 것이 아니다. 린스타트업 방식처럼 빨리 해보고, 빨리 검증해보고, 빨리 피보팅하는 것도 중요하지만, 무작정 빨리 몇 사이클을 돈다고 새로운 가치를 찾을 수 있는 것은 아니다.훈련해야 한다.'생각'하는 훈련을 해야 한다.당연한 것을 의심하는 훈련을 해야 하고, 항상 '왜'라는 질문을 머리속에 가지고 있어야 한다.가장 쉽지만 가장 어려운 일이다.사람은 쉽게 변하지 않는다. 이 말은 사람들의 '생각의 프레임'을 쉽게 바꾸기 어렵다는 것이다. 제도를 바꾼다고, 혁신을 강요한다고 혁신이 나오지 않는 것은 이 때문이다.현실에서 작동하게 하는 것이 진짜 혁신하지만 진짜 혁신의 반전은 '생각의 혁신'이 혁신을 만들어주는 것이 아니라, 이것을 '실행'할 수 있는 실력이 진짜 혁신이라는 것이다.훌륭한 컨설턴트가 반드시 훌륭한 경영자가 되는 것이 사실이 아니듯이, 혁신적인 생각과 혁신을 실천하는 것은 별개이다. 필요조건은 될 수있지만, 충분조건은 아니다.혁신적인 생각을 실제 일상에서 만들어내는 일이 진짜 혁신이다. 행동하는 혁신이 진짜이다.그래서, 정말 정말 혁신이 어려운 것이다.그래도 무엇부터 시작해야 하는지는 분명하다.생각하자.생각을 바꾸는 일부터 시작하자.생각하지 않으면, 아무것도 아니다.
조회수 1074

핀다 웹디자인! 2017 한국 디자인연감에 수록되다.

안녕하세요? 핀다입니다.국내에서 발행되는 디자인 전문지 중 가장 공신력있는 월간 <디자인>은 매년 12월호에 그해 국내에서 이뤄진 주요 디자인 프로젝트를 한데 모아 ‘한국 디자인 연감’에서 소개하고 있는데요. 아이덴티티, 프로덕트, 리빙, 그래픽, 디지털 미디어, 공간, 총 6개 부문으로 나누어 매년 우수한 디자인 프로젝트를 선별하여 수록하고 있습니다.월간 <디자인> 12월호2017년 올해 저희 핀다의 웹사이트 디자인이 그 우수성을 인정받아 디지털 미디어 부문을 장식하게 되어서 여러분들께 자랑하려고 합니다. ^^이번 연감의 디지털 미디어 부문에서 네이버와 삼성SDS와 함께 총 23개의 수준높은 프로젝트가 함께 수록됐는데요. 수 많은 금융권 서비스 중 유일하게 기라성같은 기업들과 어깨를 나란히 한 디자인, 궁금하지 않으신가요?짜쟌! 글자가 잘 안보이시는 분들을 위해 아래에 따로 써놨습니다!자! 어떠신가요? 저희 홈페이지 궁금하지 않으신가요??그럼 저희 핀다 온라인서비스가 어떤 곳인지 직접 체험해보시면 되죠!! 클릭클릭핀다(Finda)당신에게 맞는 금융상품을 1분 만에 추천해드립니다.www.finda.co.kr#핀다 #디자인 #디자이너 #성과 #돌아보기 #후기 #일지
조회수 2011

2년 전, 비캔버스 초기 개발 가이드

이 자료는 2014년 7월, 지금으로부터 2년 4개월 전, 비캔버스를 개발하기 시작할 때 작성했던 문서다.본래 내부적으로 공유하고자 하는 목적으로 작성됐지만, 시간이 흘러 내용의 상당수가 변화하였고 제품 개발에 대한 비밀적인 자료보다 제품 철학, 디자인 철학에 대한 부분이 많아 공개하기로 하였다. 2년 전 자료인데다, 내부적으로 공유하고자 하는 목적에서 작성됐기 때문에 글이 컴팩트하지 않고, 내용의 전문성이 조금 떨어 질 지도 모르지만, 충분히 참고할 만한 자료로써 가치가 있다.이는 제품 개발뿐 아니라 사업 운영에 있어 과도하게 시간을 잡아먹는 단순 비판성 회의나, 대안 없는 불평을 해소하기 위한 목적도 있었다. 당시에는 제품 개발보다 중요한 것이 하나의 목적을 모든 팀원이 명확히 인지하고 일관된 움직임을 갖추게 만드는 것이라고 생각했다. 제품에서 드러나는 느낌, 마케팅 문구, 디자인, 기능 하나하나 매우 일관된 목소리를 갖추게 만드는 것이 이 당시의 목표였다.이 자료를 통해, 서비스를 처음 개발하고자 하는 팀, 회사가 조금이라도 도움이 되길 바라며 비캔버스를 사용하고 있는 사용자들은 비캔버스가 어떤 철학과 믿음을 토대로 세밀하게 설계됐는지 알 수 있는 자료가 될 것이다. 회사 이름이 지금과 다른데, 당시의 회사 이름은 오시리스시스템즈가 아닌 '조커팩' 이었다.본래, 외부에는 비공개되는 자료였다.                       사용자 중심(User-Centered) 제품에 대하여 사용자 중심 제품은 전적으로 사용자의 경험의 질을 향상시켜주는 것을 그 목적으로 한다. 가령,기존 제품이나 행동양식이 사용자에게 만족스러운 경험을 주었다면, 사용자 중심 제품은 사용자로 하여금 단편적 좋은 경험의 세계를 넘어선 초월적 경험 세계를 느끼게 해주는 데 있다. 좋은 제품을 넘어선 위대한 제품들은 이러한 초월적 시험 세계가 느끼게 해주는 실험적 낯섦을 사용자에게 주었기에 처음엔 바보 취급을 받았지만, 시간이 지나면서 경험의 표준양식으로 자리매김했다. 이렇게, 치밀하게 설계된 사용자 중심 제품을 사용하는 사용자는 제품을 경험하는 시간을 더욱 의미 있게 느끼게 되며, 경험의 시간을 길게 가져간다. 그제야 디자이너와 개발자가 설계한 UX 디자인이 효과를 발휘할 수 있다. 흔히들 착각하는 것이 UXD가 User Experience Design이기 때문에 이를 통해 사용자의 경험을 의미 있게 만들 수 있다는 것이다. 그러나, 초월적 경험은 단순한 UXD를 통해 발현되는 것이 아닌, 사용자 중심으로 설계된 제품 자체를 통해 발현된다고 본다. UXD는 이러한 사용자 중심 제품의 일부 과정이 되어야 하며, UXD에 대한 방향이 사용자 중심 제품을 만드는 데 선행되어선 안된다. UXD는 사용자가 경험의 시간을 길게 가져가지 않는다면 무용지물이다. 디자인 자체보다, 사용자에게 어떠한 실험적 세계를 보여줘서 경험을 초월시킬 것인가에 대한 고민이 중요하다. 비캔버스는 Whiteboard & Diagramming이라는 정해진 영역에 있는 소프트웨어다. 그러나, 기존 제품들이 제공하는 기능을 넘어서서 새로운 차원의 경험을 만들어내기 위해 설계되었다. 이는 단순한 기능의 추가로 인해 만들어지는 것이 아닌 브랜드 아이덴티티, 사회 연결망, 마케팅 믹스, 포지셔닝 등 복합적인 경험의 시스템적 강화로 만들어진다. 그리고 이는 세밀한 설계를 바탕으로 한 명확한 의도 아래 구성된다.‘비캔버스를 어떻게 만들고 어떤 기능을 어떻게 개발할 것인가?’에 대한 고민을 하면 결코 위대한 제품이 될 수 없다. ‘처음 비캔버스를 접한 사용자에게 어떻게 느껴질 것이며 어떠한 가치를 주어 초월적이고 낯선 경험을 하게 만들 것인가’에 대한 답을 내놓기 위해 모든 개발, 디자인 프로세스가 설계되어야 할 것이다. 이러한 개념은 흔히 알려진 사용자 경험과 UXD에 반하는 개념이다. 그러나, 위대한 제품을 만든 인물들은 이론적으로 만들어진 영혼을 제품 속에 불어넣지 않았다. 그들은 합리적이고 논리적인 이성과 추상적이고 표현 불가능한 직관을 결합시킨 새로운 차원의 영혼을 제품 속에 불어넣었다. 위대한 제품은 만들어진 이유에 대해 설명이 불가능하며, 사용자 또한 왜 제품을 사랑하는지 설명 불가능하다. 그것은 매우 낯설고 기이한 경험(사실은 치밀하게 설계된)에 의한 것이기 때문이다. 우리는 사용자 경험에 대한 새로운 시각을 가지고 개발에 임해야 할 것이다.     아이디어를 필터링하는 11가지 질문들                 모든 개발, 디자인에 대한 사항은 아래와 같은 기본적 필터링을 거쳐야 한다. 앞서 언급했던 여러가지 제품 개발 철학들이 이 필터에 포함되며, 이러한 필터링을 거치지 않은 개발, 디자인 관련 아이디어들은 기본적으로 무시된다. 이 필터는 우리의 제품 개발 방향을 크게 선회하여 철학 전체가 흔들리지 않는 이상 유효하다. - Collect & Share anything 의 정신에 위배되지 않는가?- 극도의 사용성과 경험을 해치지 않는가? 가령, 크게 필요하지 않은 장식적 기능이 아닌가?- 직관의 근거가 있거나 데이터 기반의 논리적 근거를 가지고 있는가? - 해당 기능, 디자인이 자신이 만들고 싶은 세계를 만들어 나가는 데 필요한 것인가?- 해당 기능, 디자인을 접했을 때 기이하고 낯설은가? 그 낯섦이 초월적 경험을 줄 것 같은가?- BeeCanvas의 전체적인 시각적, 기능적 통일성(Unity)을 해치지 않는가?- 이 기능, 디자인이 고객에게 제공할 가치에 대해 충분히 고민했는가? 쉽게 떠올릴 수 있는가?- 경쟁사는 이 기능, 디자인을 제공하고 있지 않은가? 쉽게 따라오기 힘든 것인가? - 이와 비슷한 경험을 접한 적이 있는가? 즉, 메타포를 가지고 있는가?- 적어도 자신이라도 정말로 쓰고 싶은 기능, 디자인인가?- BeeCanvas가 만들어갈 세상과 아이디어를 정교하게 연결시킬 수 있는 인과를 준비했는가? 이 11가지 필터링에도 통과한 아이디어라면 충분한 회의를 통해 관철되어야 할 것이다. 경험과 가치에 대한 확신이 충분한 아이디어는 존중받아야 하며, 이는 아이디어를 고려하는 시간을 의미 있게 만들어줄 것이다. 그러나, 이러한 필터링을 전혀 통과하지 못하는 아이디어는 팀원들의 시간만 축낼 것이다. 끔찍한 아이디어는 전반적인 팀원들의 사고의 틀을 더욱 하향 평준화시킨다. 위대한 아이디어들이 만연할 때, 팀은 가장 강력하고 활기를 띤다고 본다. 사람들이 원하는 기능에 대한 고민은 지속적으로 이뤄져야 할 부분이다. 위와 같은 프레임 내에서 충분하고 의미 있게 고민된 아이디어를 통해 비캔버스가 만들어갈 세상을 구체화시켜 나가야 한다.                         비캔버스에서의 인간-컴퓨터 상호작용(HCI) 요소 인간-컴퓨터 상호작용(HCI)에서 가장 중요한 것은 인간이다. 인간은 컴퓨터를 통해 현실 문제를해결하려 한다. 컴퓨팅 파워가 점점 더 강해 짐에 따라, 단순히 문제를 해결하는 솔루션을 넘어선 효과적인 상호작용을 통해 더욱 초월적 경험을 하는 데 의미가 있어졌다. 이러한 흐름에 답하는 것이 HCI다. HCI는 특정 경험 시간(Iteration)에 대해 컴퓨터가 제공하는 어떠한 경험적 상호작용을 통해 이뤄지는 것이다. 이 상호작용은 ‘벽’으로 정의할 수 있다.                         위와 같이 인간과 시간이 제품과 만났을 때 실현되는 무언가(things)가 초월적 경험을 이끌어내는 비밀이다. 그 비밀이 비캔버스가 마땅히 가져야 할 제품 철학이라고 본다면, 이 제품이 어떤 존재여야 하는가에 대한 고민이 중요하다. 어차피 제품을 접한 사용자는 필연적으로 시간을 투여하게 돼있기 때문이다. 이러한 설계가 얼마나 치열하고 견고하게 설계됐는지에 따라 사용자가 제품에 투입하는 시간의 양도 더욱 커지며, 그에 따라 제품이 제공하는 가치의 합도 커진다.  비캔버스가 제공하는 원론적인 가치는 무엇일까? 그것은 '기록과 표현의 자율성'이다.                       우리는 위의 '텍스트 입력 대기' 마우스 포인터가 가진 한계를 넘어서고자 한다. 인간은 종이에서 자유로웠고 효과적으로 생각을 정리하고 공유했지만, 컴퓨터를 통해 한계를 가진 document를 수없이 양산해왔다. 결과적으로 인간은 인터넷이 가진 특성으로 인해 공유의 속도를 넓혀 사회관계망을 더욱 확장시켰음에도 불구하고 생각의 흐름은 더욱 후퇴했다. 비캔버스는 이러한 사고의 한계를 무너뜨리고 더욱 자유로운 Document sharing, Knowledge sharing이 가능한 화이트보드를 제공한다. 이를 통해 사용자는 자신도 인지하지 못하는 사이에 더욱 효과적으로 생각을 정리할 수 있게 된다.아주 미묘한 Interaction의 변화로 탁월한 성과가 만들어질 수 있는 것이다. 이러한 경험을 한 사용자는 자연스럽게 비 캔버스에 Lock-In 될 수밖에 없다.                     우리가 지향하는 마우스 포인터는 위와 같은 형태다. 이것이 컴퓨터의 미래가 될 것이다. 생각의 틀을 가둔 채로 생산성을 기대하긴 힘들다. 둘째로, 폐쇄적 인터랙션 대신 개방적 인터랙션이 가능하다. 월드와이드 웹은 분명하게 열려있는데, 늘 소프트웨어를 사용할 땐 가입을 하거나, 학습을 하는 등 장애물(Huddle)이 존재한다. 이 때문에 과거 소프트웨어가 효율성이 떨어짐에도 답습하는 경우가 많다. 진정한 월드와이드 웹의 산물은 자율성이 높고 개방적 인터랙션이 가능해야만 한다. 우리는 Sharing 한 보드를 접근함에 있어 어떠한 제약도 갖지 않는다. 가입도 필요 없고 학습도 필요 없다. 직관적으로 사용하면 된다. 그제품이 가치 있는지, 그 경험이 초월적이었는지 사용자가 결정하는 것은 그다음 문제다. 셋째로, 현실 오브제의 메타포를 활용한다. 가령, 포스트잇에 우리는 많은 글을 쓰지 않는다. 그럼에도 불구하고 많은 소프트웨어들이 포스트잇 형태의 메모장을 제공한다. 또한, 현실에서는 사진과 포스트잇을 함께 붙일 경우 반드시 사진 위에 포스트잇이 덮는 형태다. 그러나, 많은 소프트웨어들이 사진이 ‘가장 앞으로 오게 배치’ 할 수 있는 기능을 제공한다. 현실의 메타포를 무시하면 인류의 DNA에 내포된 휴리스틱(Heuristic)과 심성 모형(Mental model)을 파괴하여 혼란스러운 인터랙션을 만들어낸다. 비캔버스는 현실 오브제의 메타포를 충실히 적용해야 한다. 마지막으로, 손에 집혀야 한다. 에버노트, 트렐로 등 유익한 소프트웨어가 많지만, 정작 많은 사용자들이 실제 노트를 손에 잡는 경우가 많다. 컴퓨터에 있는 소프트웨어는 손에 쉽게 잡히지 않는 법이다. 이를 막기 위해 사용자들이 업무상 반드시 접속해야 하는 ‘이메일’, ‘구글 닥스’, ‘브라우저’ 등에서 비캔버스로 바로 접근할 수 있어야 한다. 비캔버스를 이용하기 위해 비캔버스에 접속하는 것을 막는 것이 가장 중요하다. 인간은 의도를 가지고 행동하는 존재가 아니다. 이를 중심으로 효과적인 인터랙션을 설계해 나갈 것이다. 이 네 가지 요소에 충실하게 개발한다면, 인류에게 더 높은 차원의 가치를 선보일 수 있을 것이다. 아주 단순한 소프트웨어지만 삶에서 결코 떨어질 수 없는 Daily 소프트웨어가 되어야만 한다. 이를 위해, 끊임없이 인류에 대해 고민하고, 탐구하고, 관찰해야 한다.                   정보구조 (Information Architecture)비캔버스의 정보구조는 굉장히 단순하다. 깊이(Depth)가 낮으면서도 선택권이 다양하지도 않아효과적이다. 이러한 정보구조가 가능한 이유는 Canvas.html이 내적으로 순환(circulation)하는 구조적 특징을 갖기 때문이다. 즉, 실제 페이지는 훨씬 더 많아질 수 있지만 모든 페이지는 canvas.html으로 생성되고 관리된다. 이 수많은 페이지들은 canvas.html 내에서 인덱싱 되고 접근할 수 있다. 이로 인해, 사용자들은 매우 편리하고 쉽게 비캔버스를 이용할 수 있다. 초기 페이지에서 클릭 가능한 버튼이 적은 것도 큰 장점이다. 정보구조가 단순하다는 것을 사용자에게 어필하고 그에 따라 심리적 접근 장벽을 허물 수 있다. promotion 페이지는 사용자가 로그인을 하게 되면 더 이상 보이지 않는다. 이는 조금이라도 더 적은 클릭 이벤트로 서비스 이용의 목적을 달성 (canvas.html 진입)할 수 있게 하기 위함이다. 사용자는 이러한 간결한 정보구조를 손쉽게 탐험할 수 있고, 내비게이션 메뉴에 대한 학습이 필요 없는 손쉬운 웹서비스를 접할 수 있다. 가입자로부터 board를 Sharing 받은 Guest 사용자의 경우 canvas.html 상위에 존재하는 모든 구조가 무시되니 더욱더 쉽고 편리하게 접근할 수 있다.               JOKERPACK 개발 철학 기본적으로 JOKERPACK은 현재의 패러다임이 파괴될 수 있다고 믿는다. 당연시되는 많은 것들에 대해 의심하고 탐구하지 않는다면, 의미 있고 위대한 결과물을 세상에 내놓을 수 없다. ‘개선’이 아닌 ‘혁명’을 위하여 제한된 시간을 투입할 것이다. JOKERPACK이 믿는 것은 초월적이고 실험적인 세상의 창조가 인류의 진화를 가져온다는 것이다. 따라서, 우리의 사업제안에 대해 다수가 동의하거나 인정한다면, 이는 우리가 원하는 길이 아니다. 새로운 세계를 접한다는 것은 낯설어야만 한다. 때로는 무섭고, 불쾌하고 거부하고 싶기도 해야만 한다. 그 세계가 온전히 자리매김하기 전까지 우리의 제품은 절대로 인정받아선 안된다. 우리가 할 일은 그 기간을 단축시키는 것이다. 이를 위해선 빠른 개발이 선행돼야 한다. 빠르게 개발하여 선구적인 사용자들에게 새로운 세계에 대해 접하게 해준다. 그들이 완전히 이러한 낯섦을 수용할 때, 대중들 또한 우리 제품에 사로잡힐 것이다. “더 빠르게 개발하고, 더욱 저렴하게 내놓는다”시장에서 가장 중요한 것은 제품이며 그다음은 가격이다. 가격은 사용자의 진입장벽을 허물고 더욱 광범위 한 시장 확산을 가능하게 만든다. 브랜드와 마케팅은 그다음이다. 과거에는 마케팅이 제품보다, 가격보다 중요했다. 그러나, 이제 소비자들은 현명해졌고 제품이 제공하는 가격에 비해 터무니없는 품질을 제공한다는 것을 소름 끼치도록 빠르게 깨우친다. 사용자들은 무엇을 원하는지, 무엇이 잘못되었는 지를 명확하게 설명할 수 없을지라도, 무언가가 잘못되고 있다는 것은 반드시 알아차린다. 브랜드는 우리가 이러한 세계를 표준화시켰을 때 비로소 생겨난다. 브랜딩은 마케팅 프로세스에서 발생하는 것이 아닌, 제품 개발에 따른 모든 체인들이 유기적으로 결합됐을 때 결과적으로 만들어지는 것이라 믿는다. 인위적으로 설계한 브랜드는 절대로 사용자로부터 인정받는 브랜드가 될 수없다.  이것이 우리가 JOKERPACK에 모인 이유이며, 개발을 위해 한 줄 한 줄 코딩을 이어나가고 있는 이유다. 우리는 내면의 소리에 귀를 기울인다. 우리의 신념이 비록 틀렸을 지라도, 다른 이의 신념에 기대어 제품을 개발하는 것보단 우리 내면의 소리에 의해 실패하는 것이 더욱 행복하다는 것을 믿는다.                   제품 선언문 실패할 것이 두려웠으면 시작도 안 했다. 우리는 우리가 지향하는 세상을 만들기 위해서라면 어떠한 일도 해낼 수 있다. 우리는 현재 당연시되는 Document sharing 프로세스를 뒤엎고 더 나은 인터넷 세상을 만들기 위해 BeeCanvas를 내놓을 것이다. “BeeCanvas는 마땅히 이래야만 한다” - 너무나도 쉽고 직관적이어서 그것이 마치 원래 존재했어야 하는 제품으로 여겨져야만 한다.- 손에 잡히는 곳에 있어서, 매일매일 빠짐없이 BeeCanvas가 이용되어야만 한다. - BeeCanvas를 쓰는 평범한 팀이 위대한 성과를 낼 수 있어야만 한다.- 너무나도 센세이션하고 파격적이어서, 그것이 형편없더라도 주목이 되어야만 한다.- 일관성 있는 디자인으로, BeeCanvas의 디자인적 아이덴티티가 명백해야만 한다.- 사용자들의 사회관계망을 확장시키고, 그 관계를 의미 있게 만들어 내야만 한다. - 어떠한 장벽 없이 빠르게 접근할 수 있어야만 한다. 필요 없는 절차는 모두 제외한다.- 무엇을 넣을 지보다 무엇을 뺄 지에 대해 고민한다. 그를 위한 ‘중심’을 모든 팀원이 인지한다. - 자유도가 높아서 다양한 방법으로 사용 시나리오(Use case)를 확장시킬 수 있어야 한다.- 수단과 방법을 가리지 않고 BeeCanvas를 처음 접하는 사용자들이 ‘와~’하도록 만든다.- 돈을 벌 특별한 방법을 찾기보다, 가치를 제공해줄 특별한 방법에 대해 고민한다.- 적어도 개발자인 우리들이라도 BeeCanvas가 없다면 살 수 없도록, 의존성을 창출한다.- 내면의 소리가 거부하면 즉시, 개발을 멈추고, 그 근거를 명확하게 머릿속으로 그려본다.- 뛰어난 Look&Feel을 가져야만 하며, Look과 Feel에는 명확한 근거가 있어야 한다.                   전체적인 디자인 철학과 Look & Feel 비캔버스의 디자인의 중심은 사용성(Usability)과 미니멀리즘이다. 사물은 표현되지 않았을 때가장 아름답다. 비캔버스는 더욱이 캔버스가 중요하기 때문에 개별 요소들은 절대 강조되어선 안된다. 이러한 이유로, 장식적 이어선 안된다. 그러나, 동시에 너무 단순해도 안된다. 중도를 찾아가는 것이 비캔버스 디자인의 핵심이다. 좋은 디자인은 아름답지만, 위대한 디자인은 사용자를 디자이너의 의도대로 컨트롤할 수 있게 한다. 우리가 믿는 것을 그들이 믿게 만들고, 우리가 보는 것을 그들이 보게 만든다. 착시현상이나, 게슈탈트 법칙 등 많은 디자인 이론들을 총동원하여 사용자의 감각을 무력화하고, 새로운 지각 세계를 만들어나가야만 한다. 이를 위해, 디자인이 지속적으로 개선 작업을 거칠 것이다. 디자이너의 숙명은 이러한 비캔버스와 JOKERPACK의 디자인 철학에 위배되지 않으면서도 아름다운 디자인을 해내는 것이다. 특별하지 않으면서 평범하지도 않은, 장식적이지 않으면서 단순하지도 않은, 낯설게 느껴지지만 익숙하기도 한 예술의 영역을 창조해야만 한다. 따라서, 과도한 벤치마킹은 경계돼야 한다. 디자인 설계에 앞서 아이덴티티를 고려하고, 아이덴티티를 고려함에 앞서 JOKERPACK의 철학적 중심을 고려해야 한다. 디자이너의 개인 취향은 이러한 중심에서 벗어날 경우 철저히 무시된다. 어떠한 것을 믿는지, 내면의 소리가 무엇을 말했는지, 비캔버스가 이러한 디자인을 입고 어떤 모습으로 어떠한 가치를 줄 수 있는지에 대해 고민해야만 한다. 원론적인 고민이 끝난 후에 그를 아름답게 만드는 것이다. 인간에게는 기본적인 휴리스틱(Heuristic)이 있다. 이는 어느 정도의 보편타당함을 지니며, 인간이 기대하는 심성 모형(Mental model) 또한 일정한 패턴을 갖는다. 디자이너는 이러한 패턴을 면밀하게 분석하여 사용자의 인터랙션과 시스템의 인터랙션이 반하지 않도록 디자인을 설계해야 한다. 꾸미는 것은 3류나 하는 일이다. JOKERPACK의 디자이너는 꾸미지 않고 설계해야 한다. 디자인은 실용적인 예술의 일부분이며, 근본적으로 예술 태생이라고 믿는다. 누군가의 실험적 예술이 표준화되고 상업화 가능해질 경우 디자인이 되는 것이라고 본다. 즉, 모든 예술은 하나의 뿌리를 갖고 있기 때문에, 사용자들이 비캔버스의 디자인을 접했을 때 내면에서 어떤 음악같은 것이 떠올라야 한다. 이렇게 사용자들이 떠올리게 될 음악을 생각하며 제품을 디자인 하면 딱딱하고 진부한 GUI에 리듬감과 생명력이 생긴다. 청각적으로 지각되는 Feel의 영역을 시각적으로 옮긴다면 비캔버스가 분명히 강력하고 통합적인 디자인 스펙을 가질 것이라고 확신한다. 근본 없는 디자인을 경계해야 한다. 근본 없는 디자인은 근본 없이 떠나간다. 사람들의 뇌리에도 박히지 않으며, 다시금 찾게 만드는 매력도 없다. 디자인은 브랜드의 일부이며, 개발의 일부다. 이런 게 모듈별로 모두 명세돼있다. 너무 길기 때문에 생략.                   향후 개발 방향 공유 기능을 강화한다. 캔버스의 기본적 개발이 모두 이뤄지면 공유 기능을 강화하여, 어디서든 쉽고 빠르게 공유될 수 있다는 것을 사용자가 느낄 수 있게 만들어야 한다. 이에 앞서, 아직 해결되지 못한 Canvas 내부의 개발 이슈들을 trouble shooting 하는 것이 우선이기 때문에, 지속적으로 빠르고 신중하게 개발을 이뤄나가야 할 것이다. 또한, 현재 js파일 하나에 과도하게 코드가 몰려있어 유지보수가 힘들다. 모두 분할하고 리팩토링하여 유지보수 생산성을 높이고, 코드의 유닛 테스트도 수월하게 만들어야만 할 것이다. Microsoft Azure를 이용해 서버 운영비를 추산하고, 이에 따라 프리미엄 유저의 가격정책도 세워나가야 한다. 그를 위해 Azure에 대한 기본적인 지식을 습득하여 서버 운영에 있어 어떠한 오류도 발생하지 않도록 해야 한다. 커스텀 템플릿은 공유 기능이 완벽해질 때까지 JOKERPACK 내부적으로 계속 만들어서 사용자에게 유포한다. 이는 어떠한 템플릿이 인기가 많은 지에 대한 데이터를 모을 수 있게 할 것이다. 축적된 데이터를 분석하여 후에 개발할 커스텀 템플릿 에디터의 개발방향도 세울 수 있으니 일석이조다. 힘든 개발이고, 앞으로 더욱 힘들어지겠지만 그만큼 가치 있는 웹서비스가 될 것이다. 결과를 돌아보면 우리가 BeeCanvas 개발에 참여했다는 것이 자랑스럽게 느껴질 날이 반드시 올 것이다. 그를 위해 넷이 한마음으로 뭉쳐서 지옥을 다녀와야 한다.
조회수 1834

잔디 ‘이모티콘’의 아버지, 디자이너 David과 함께 하는 맛있는 인터뷰

잔디 이모티콘 디자인하면 빼놓을 수 없는 디자이너BX디자인팀 David을 만나다 반갑다, 데이비드 초이. 오늘 우리가 온 맛집은 어떤 곳인가? 꽤 유명한 집인 것 같다David: 반갑다. 맛있는 인터뷰를 평소 즐겨봤는데 나도 꼭 해봤으면 싶었다. 깊은 감사를 표하고 싶어 평소 즐겨 찾는 ‘역삼역 맛집’으로 왔다. 잔디 사무실 건너편에 있는 이곳의 이름은 ‘호타루’다. 일식 전문점으로 늘 먹어도 질리지 않는다. 명성이 자자해서 그런지 점심시간에는 조금 일찍 나와야 먹을 수 있다. 잔디는 어떻게 지원했나?David: 대학에서 시각 디자인과 애니메이션을 복수 전공했다. 자연스레 졸업 후, 디자인 회사나 애니메이션 회사 지원을 생각하던 중 두 분야 업무를 모두 할 수 있는 곳은 없을까 고민하게 되었다. 그러던 중 잔디 BX(Brand Experience)팀의 채용 공고를 보았다. 메신저 형태의 업무 커뮤니케이션 플랫폼이기 때문에 이모티콘뿐만 아니라 다양한 디자인 업무를 해볼 기회가 있을 거라 생각해 지원했다.▲ 캐나다 곰들이 연어를 즐겨 먹는 이유를 알 것 같다.여담이지만 디자이너라 그런지 디테일을 많이 본다. 잔디의 채용 공고 포스터는 다른 회사보다 더 정성을 다한 우주의 기운이 느껴져 지원을 결정하는데 영향을 미쳤다. 우주의 기운을 담아 잔디에서 맡은 역할을 소개해달라David: BX 팀에 소속되어 온라인 광고, 일러스트레이션, 이모티콘 등 다양한 크리에이티브 작업을 하고 있다. 최근 이모티콘 작업을 하고 있는데 이전에 발표했던 Day and Emily 세트에 이어 신규 이모티콘 세트를 발표할 예정이다. 이 자리를 빌려 잔디 블로그 독자들에게 처음 공개한다. 오! 그렇지 않아도 Daivd이 작업한 이모티콘이 인기가 많다. 새로 나오는 이모티콘에 대한 설명을 부탁한다David: Day and Emily 이모티콘은 ‘캐릭터를 만들어야지!’라는 일념으로 제작되었다면 새로 나오는 이모티콘은 업무 커뮤니케이션에서 적절하게 쓸 수 있는 목적을 달성하겠다는 생각으로 만들었다. 물론, 잔디의 브랜드 아이덴티티에 부합한 이모티콘을 만들고자 많은 노력을 기울였다. 최근 카카오 프렌즈나 라인 프렌즈 등을 보면 캐릭터 사업이 브랜드 인지도를 높이는 주요 전략으로 자리 잡은 것 같다. 전공자가 보기에 어떻게 캐릭터/이모티콘이 브랜드 연상까지 영향을 미치는지 궁금하다David: 음. 잔디를 예로 들어 설명하고 싶다. 우리 브랜드의 에센스는 ‘Lively Collaboration Enhancer’이다. 풀어보면 ‘Lively=유쾌한’, ‘Collaboration=팀워크’, ‘Enhance=개선하다’ 인데, 각 단어에 담긴 의미와 연관 키워드를 도출하고 모으면 MBTI로 하나의 인격체를 설정할 수 있다.▲ 곧 출시 예정인 잔디 신상 이모티콘 (메이드 바이 데이비드 초이)잔디 브랜드 에센스에서 추출할 수 있는 의미와 키워드를 조합하면 유쾌하고 친화력 있는 미래지향적 성향이 나오는데, MBTI에서는 ESTP(모험을 즐기는 사업가)와 매칭된다. 원피스 루피 같은 캐릭터라고 보면 이해가 쉬울지 모르겠다. 아무튼 이런 성향을 캐릭터/이모티콘에 녹아냄으로써 우리 브랜드가 갖고 있는 성격, 방향을 시각적으로 담아내 유저와 소통할 수 있다. 어릴 적 내 자아붕괴에 일조하던 MBTI가 캐릭터에 이용되다니 참신하다. 다른 질문을 하고 싶다. 좋은 이모티콘이란 무엇이라 생각하는지?David: 좋은 이모티콘. 어려운 질문이다. 개인적인 생각이나 이모티콘은 사용자의 커뮤니케이션에서 그들이 원하는 적절한 감정 표현을 제공하고, 대화를 풍성하게 만들어야 한다. 잔디 이모티콘도 제작 초기 단계부터 사람들이 직장 내에서 표현하고픈 감정을 리서치했었다. 또한 잔디 유저를 대상으로 ‘감정표현 공모 이벤트’를 통해 참신한 아이디어도 얻고 사용자의 니즈를 파악하는데 주력했었다. 이모티콘 말고 다른 이야기를 해보자. 이전 맛있는 인터뷰이였던 Harry가 남긴 질문이 있다. 잔디 멤버 중 남들 몰래 연애를 잘할 것 같은 사람은?David: 세일즈 팀의 Scott. 무언가 치밀하고 완벽주의자 같아 사내 연애를 해도 몰래 스르륵 잘할 것 같다. 스르륵.. 쉬는 날엔 무엇을 하는지?David: 이것저것 하는 편이다. 집에서 독서하거나 맛집, 전시회, 여행 다니는 걸 좋아한다. 피규어나 팬시용품에 관심이 많아 홍대 상상마당이나 오브젝트도 자주 가는 편이다. 그리고 힙합 음악 듣는 걸 좋아한다. 앞으로 하고 싶은 일이 있다면?David: 이모티콘을 더 집중해 연구해보고 싶다. 메시지 커뮤니케이션의 형태가 다양하게 변화해 왔듯 이모티콘도 함께 변화해 왔다고 본다. 따라서 이모티콘 분야는 앞으로도 많은 변화가 있을 거라 생각한다. 개인적인 목표라면 실제로 만나 대화하는 것 이상으로 풍부하고 다양한 감정 표현을 할 수 있도록 혁신적인 이모티콘을 만들어 보고 싶다. 마지막 질문이다. 다음 맛있는 인터뷰 대상자에게 하고 싶은 질문이 있다면?David: 예상컨대 다음 인터뷰이 분은 회사에서 어마무시한 존재감을 갖고 있는 분이 될 것 같다. 그분에게 어울릴만한 질문을 하고 싶다. ‘전생에 공주 또는 왕자였을 것 같은 사람은?’ ..고맙다.. 엄청난 질문이다 David: ^^#토스랩 #잔디 #JANDI #디자인 #디자이너 #디자인팀 #팀원 #팀원소개 #팀원인터뷰 #인터뷰 #조직문화 #기업문화 #회사문화 #사내문화
조회수 1617

2017 NDC 리뷰) 크립돈 퓨처 미디어와 하츠네미쿠

 이번글은 덕력이 솟구친다는!!!은 아니고요(진짜 아니에요), 혹시 "하츠네 미쿠"라는 캐릭터를 보신 적 있으신가요?하츠네 미쿠! 설마 처음보는 분들이 계신가요?? 출처: https://ec.crypton.co.jp/pages/prod/vocaloid하츠네 미쿠는 VOCALOID(보컬로이드)로서, 간단히 설명하면, 야마하에서 만든 음성 엔진입니다(자세한 내용은 링크를 확인!). 해당 엔진을 기반(자세히는 VOCALOID2인데... 아, 저는 잘 몰라요 진짜예요...)을 기반으로 크립톤 퓨처 미디어사가 아티스트를 만들고, 이를 지적 재산권(이하 IP라고 하겠습니다)으로 창출해 낸 사례입니다! 해당 세션은 이 보컬로이드가 성공할 수 있게 된, 창작자들에게 프로그램 번들 시디를 팔던, 크립톤 퓨처 미디어사가 새로운 미디어와 아트의 중심에 설 수 있게 된 이유를 들을 수 있게 된 좋은 시간이었습니다. 앞으론 말이 매우 딱딱하니 이점 히해해 주세요~! 시작하겠습니다!씨디파는 회사가 인터넷 시대를 맞이하며 겪게 된 위기, 그리고 해결방안. 앞서 말씀드렸든, 크립톤 퓨처 미디어(이하 크립톤이라고 하겠습니다)는 창작자들을 위한 서비스(또는 프로그램)를 번들 또는 디스크 형식으로 판매하는 회사였습니다. 그리고 새로운 세대로 들어서면서, 해당 사업이 사양되고 있고(디스크 판매> 콘텐츠 다운로드의 변화), 특히 음악 제작 서비스의 경우, 작은 시장의 규모 때문에 비즈니스에 대한 한계를 느끼고, 새로운 사업 영역을 펼쳐나가기 위해 방향 모색하기 시작했다고 합니다. 그리고 크립톤이 생각할 수 있는 "자사가 가장 잘할 수 있는 것"을 생각해 보았을 때, "소리"라는 콘텐츠를 방점으로 서비스를 응용해 나가면서 스팩트럼을 넓히자!라는 생각을 했다고 합니다. 그래서 시작한 것이 바로, 보컬로이드!라는 것이었죠.보컬 합성 기술(보컬로이드) + IP의 도입은 처음부터 성공적이진 않았습니다. 처음 크립톤은 야마하의 보컬로이드 기술을 기반, Leon과 Lola라는 소프트웨어를 제작,  당사에서 유통을 시작했을 때에는, 타깃 유저를 잡는데 실패해 매출에 전혀 도움이 되지 않았다고 합니다(아래 사진을 보면 왠지 알 거 같...)첫 보컬로이드 레온과 로라입니다..... 음... 입술이 매력적 이네요.... 출처: http://vocaloid.wikia.com/wiki/Forever_(Zero-G_song) 그 이유는 해당 서비스를 사용할 것이라고 타게팅한 아티스트들의 경우, 목소리에 관해 리얼함을 추구하는 데, 해당 소프트웨어는 하드웨어로 조정하는 음과 음성들이 리얼함이 다소 떨어져 전혀 니즈가 없었던 것이죠.그래서 트립톤은"해당 서비스를 진짜 사용하는 유저들은 어떤 사람들 일까?"에 대한 고려를 기반으로,"메이코"라는 일본어로 노래하는 보컬로이드를 제작, 흥미를 끌 수 있도록 캐릭터를 모티브로 하는 커버 디자인 작업 시작(안드로이드 아니 보컬로이드 이니깐요!)이제는 버전 쓰리가 된 메이코! (출처:http://vocaloid.wikia.com/wiki/MEIKO) 첫 출시 당시, 거부감도 있었지만, 당시 KPI 목표인 500개를 훌쩍 넘어 3,000개의 판매 성공을 거뒀고, 성공의 요인은 패키징 디자인과 단순한 아티스트뿐만이 아닌, 다양한 콘텐츠에 관심을 가지는 다양한 유저들을 유저들을 이끌 수 있는 요소들이 있어서 라고 판단하였다고 합니다. (서비스를 사용할 것이다 라는 사용자의 경험에 대한 고려를 더 많이 한 포인트라고 생각되는 부분이지요!)메이코 이후 드디어 그분을 만들어 내는 것을 준비합니다.크립톤은 이때부터 정말로 사용자들이 무엇을 원하는가에 대한 생각을 많이 한 것 같다고 보이는 포인트입니다. 메이코의 등장 이후, "하츠네 미쿠"라는 캐릭터 산업으로 만들어 내는 것을 준비합니다. 그리고 해당 캐릭터를 하나의 "사업전략"으로 생각해 낸 이유는 메이코의 KPI달성도 있겠지만, "사람의 목소리와 극히 다른 목소리로 노래를 부르게 된다면, 이상하지 않을까?라는 부분을 오히려 역으로 기획, "인간이 아닌 다른 안드로이드가 하는 노래"라는 새로운 존재로서 IP를 만들어 버린 것이죠!또,  캐릭터를 기반으로 다양한 성격을 가질 수 있도록 "성우"라는 시스템을 집어넣어 "특별한 존재"라는 특징 성을 추가하였고, 기존의 보컬로이드는 "인간의 가수를 대체하는 것"이었으나, 하츠네 미쿠는 "안드로이드 가 부르는 진짜 보컬로이드"라는 접근을 통해 새로운 존재를 만들고, 메이코 디자인을 기반으로, "아이돌 라이즈 된 새로운 사이버 가수"를 만든 것이죠!아아.... 이제 고인이 되신 사이버 가수 아담... (http://beautinaru.tistory.com/196 또한, 해당 콘텐츠를 기반으로 음악을 만들었던 유저들에게 레트로 한 마크들을 집어넣어서 예전에는 이랬었지 라는 향수를 불러일으키고, 해당 콘텐츠를 기반으로 다시 작업을 할 동기를 줄 수 있도록 유저들의 의견을 듣고 반영하는 일들을 굉장히 많이 했다고 합니다!그리고 하츠네 미쿠의 진정한 아이덴티티를 생성합니다. 그것은 바로 Chain of Co-creation!!!하츠네 미쿠가 이렇게 성장할 수 있었던 이유는 저는 하나만 꼽으라 라고 한다면 이쁘잖아요! 가아니라... "확산 가능 여부"에 대한 많은 고려가 있었기에 가능했다고 생각합니다.인터넷 덕분에 음악 등을 만드는 사람들이 쉽게 업로드하고 공유할 수 있는 많은 플랫폼들이 생성되는 현실.덕이 많은 분들이 공유를 통해 자아실현을 하는 공감대를 형성할 수 있는 움직임이 확산.콘텐츠가 콘텐츠를 만들고 퍼져나가는 순기능적인 부분들이 늘어나는 현상들을 확인하고,2차 3차 저작물을 통한 확산> Chain of co-creation의 순선환 적인 기능들이 생겨나는 것이죠!! 그리고 그런 상황을 기반으로, 궁극적으론,모든 사람들이 제작자가 될 수 있는 현실 상황을 받아들이고,제작할 수는 있지만,  저작에 관련한 법률 등에서 막히는 상황을 막기 위해, 창작자들의 창작활동을 돕고, 실제 업로드된 콘텐츠를 기반으로, 실제 사업이 일어날 수 있는 방향으로 전개합니다!그리고 수익화를 통해서 창작자들이 창작활동 = 수익활동이 될 수 있도록 플랫폼 화를 추진한 것이죠!그래서 처음 하츠네 미쿠가 나온 2007년부터 10년이 지난 지금까지도 "보컬로이드"의 선두 주자로 전 세계적으로 콘서트를 다니며 성공적인 투어를 하고 있습니다.투어는 계속된다. (출처: http://mikuexpo.com/) 저는 하츠네 미쿠가 단지 덕후들의 승리라고 요만큼도 생각하지 않습니다.하츠네 미쿠를 성장시킬 수 있었던 건 "우리가 제공하는 서비스가 어떤 유저들에게 더 많은 강점이 있고, 해당 유저들은 어떤 행동을 통해서 자아를 성찰할 수 있을까? 그리고 해당 행동을 통해 유저가 얻는 궁극적인 이익들이 잇을까?"를 생각했던, 크립톤의 유저를 생각하는, 유저의 직접적인 경험을 서비스에 반영하려고 하는 강한 의지가 해당 서비스를 성공시킬 수 있게 한 요인이라고 생각해요. 그런 의미에서 저에겐 정말로 뜻깊고 즐거웠던 세션이었습니다!P.S.: 이제 슬슬 NDC2017 영상들이 올라오기 시작하네요! 관심 있는 분들은 https://ndc.nexon.com/main에서 확인해 보세요~오늘도 긴 글 읽어주셔서 감사합니다! 다소 글이 엉망진창이라도 이해해 주세요! #코인원 #블록체인 #기술기업 #암호화폐 #스타트업인사이트
조회수 952

앱 데이터 분석 시 사용자 세그먼트의 필요성

사용자 세그먼트(USER SEGMENTATION)란? 모바일 분석 툴을 사용하면 앱 사용자에 대한 많은 정보를 얻을 수 있습니다. 하지만 방대한 데이터는 오히려 의사결정에 혼란을 일으킬 수 있어 비즈니스에 의미가 있는 데이터를 선별해서 보는 것이 중요합니다.‘사용자 세그먼트’란 데이터의 필터 기능으로, 1차 데이터를 하위 기준으로 분류해서 보는 것을 의미합니다. 예를 들어 앱 사용자 전체의 데이터를 성별, 연령, 국가, 플랫폼 별로 나누어서 보는 것도 세그먼트에 해당합니다. 이 기능을 이용하면 ‘우리 사용자는 누구인가?’ 에서 더 나아가, 앱 서비스의 충성고객, 구매고객, 이탈고객 각각의 특성을 파악하고 이에 맞는 비즈니스 전략을 만들 수 있습니다.아래 내용을 통해 앱분석 시 사용자 세그먼트의 방법과 필요성을 알아보겠습니다.사용자 세그먼트 적용하기사용자 세그먼트가 무엇인지 실제 데이터 분석 툴의 예시를 보며 자세히 알아보도록 하겠습니다. 모바일 분석 서비스 와이즈트래커는 기본 세그먼트와 사용자 정의 세그먼트 기능을 제공하고 있습니다.기본 세그먼트기본세그먼트 기능을 통해 플랫폼, 성별, 연령대에 따라 데이터를 분류할 수 있습니다. 비즈니스에 따라 사용자 구분 시 중요한 지표가 있다면, 그것을 기본세그먼트 항목으로 추가하는 것도 가능합니다. 광고채널, 회원여부, 회원등급 등이 이에 해당합니다.[ 와이즈트래커 세그먼트 설정화면 – 필요한 세그먼트를 더블 클릭하거나, 오른쪽 상단의 ‘Drag Here’ 로 세그먼트 항목을 Drop하면 세그먼트가 적용됩니다. 여러가지 세그먼트를 동시에 적용할 수 있습니다 ]아래 데이터는 기본 세그먼트 중 연령대(20대, 30대, 40대) 세그먼트를 이용해 [신규방문 vs 재방문] 리포트 데이터를 하위 분석한 결과입니다.이를 통해 단순히 신규방문/재방문의 수치/비율 뿐 아니라, 각 방문 유형별 연령대 구성을 파악할 수 있습니다. 이 데이터를 통해 처음방문자의 경우, 20대와 30대의 수치가 비슷하게 나타나지만 반복방문자의 경우 30대의 비율이 20대보다 훨씬 높게 나타나, 앱 서비스가 20대보다 30대에게 지속적으로 어필되고 있다는 것을 확인할 수 있습니다.사용자 정의 세그먼트사용자 정의 세그먼트를 통해 기본적으로 제공되는 세그먼트를 조합해 비즈니스에 필요한 맞춤 세그먼트를 설정할 수 있습니다. 예를 들어, 앱 서비스의 주요 고객이 iOS를 사용하는 20~30대 여성이라면 아래와 같이 해당 속성값을 가지는 사용자 정의 세그먼트 ‘iOS_2030_여성’을 생성합니다.위에서 생성한 세그먼트를 위의 [신규방문 vs 재방문] 리포트에 적용하면 아래와 같은 데이터가 나타납니다.이처럼 사용자 정의 세그먼트를 이용하면 앱 사용자를 비즈니스에서 정의한 타겟 고객군과 잠재 고객군으로 분류하여 유의미한 사용자 그룹의 숫자를 파악할 수 있습니다.사용자 세그먼트의 필요성데이터 분석은 분석 자체가 목적이 아니라, 비즈니스의 성장과 목표 달성에 도움이 될 때 의미가 있습니다. 그럼 사용자 세그먼트는 비즈니스의 성장에 어떤 도움을 줄 수 있을까요?1. 의사결정에 필요한 데이터를 선별해 추출할 수 있다. 신규 고객을 위한 이벤트 기획 시, 신규 고객들의 성별, 나이, 플랫폼 등을 세그먼트 기능을 통해 파악할 수 있습니다. 만약, 아래 테이블처럼 신규 고객의 대다수가 20,30대 여성이라면, 이들의 흥미를 끌만한 이벤트를 기획해 이벤트 참여율을 높일 수 있습니다.[ 와이즈트래커 내 처음방문자 방문수 데이터에 연령_성별 사용자정의 세그먼트를 적용한 화면 ]2. 어떤 유저가 우리 비즈니스에 가장 유의미한지 파악할 수 있다. 앱 서비스의 핵심적인 유저는 앱을 주기적으로 방문하고, 구매 빈도/금액이 높은 사용자입니다. 이들의 특성을 세그먼트를 통해 파악하고, 이러한 데이터를 기반으로 해당 사용자들의 충성도와 구매율을 높이기 위한 프로모션을 진행할 수 있습니다.[ 와이즈트래커 내 1회 구매자 방문수 데이터에 여성들의 연령_플랫폼 사용자정의 세그먼트를 적용한 화면 ]3. 오디언스 타겟팅(AUDIENCE TARGETING)에 이용할 수 있다.세그먼트 기능을 통해 파악한 특정 사용자 그룹의 특성을 바탕으로 오디언스 타겟팅을 진행할 수 있습니다. 앱에서 한번도 상품을 구매하지 않은 비구매자 그룹의 특징을 파악했다면, 이를 기반으로 해당 그룹의 ADID/IDFA를 추출해 구매를 유도하는 푸시메시지 또는 광고를 노출할 수 있습니다.[ 와이즈트래커 오디언스 타겟팅 설정화면. 비구매자 그룹의 주요 특징이 회원인 40대 국내 남성이라면 이들의 ADID/IDFA를 추출해 구매를 유도하는 푸시메시지/광고 프로모션을 진행할 수 있다.]비즈니스 성장의 지름길 고객에 대한 이해도가 높을수록 비즈니스는 빠르게 성장합니다. 이 때문에 모바일 비즈니스에서 사용자 세그먼트를 통해 비즈니스 고객군 별 특성을 정확하게 파악하는 것은 선택이 아닌 필수입니다. 모바일 데이터 분석을 이제 시작했다면, 사용자 세그먼트 기능을 통해 데이터에 깊이를 더하고 비즈니스 성장에 핵심적인 데이터를 확인해보세요!
조회수 690

유통 공룡 아마존의 홀푸드 인수와 아마존고

책 장사로 시작해서 유통 공룡, 그리고 이제 클라우드 서비스로 발전한 아마존의 도약은 놀랍기만 합니다. 지난 2017년 6월에는 아마존이 유기농 식료품 체인 ‘홀푸드’를 인수해서 유통시장에 큰 파장을 가져왔는데요, 언론들은 아마존의 식품시장 진출로 인한 식품유통시장 변화와 막강 라이벌을 맞이할 월마트의 반응에 주목했습니다.아마존이 홀푸드를 인수한 후에 아마존의 주가는 급등했지만 경쟁사인 월마트, 코스트코 등은 일제히 하락을 했습니다. 그만큼 아마존의 식품시장 진출에 시장에서는 많은 기대를 한다는 반증이겠지요?아마존은 오프라인 매장에 ‘아마존 고’라는 무인시스템을 사용해서 인력을 줄이겠다는 전략이었지만 얼마 전 ‘아마존 고’ 매장을 현재로서는 더 늘릴 계획이 없다고 발표를 하였죠. 무인시스템 매장에 대한 고객들의 반응을 관찰해보는 기간이 필요한 것이 아닐까 추측해봅니다. 고객들도 적응하는 데는 시간이 필요하니까요.그동안 아마존이 괄목할만한 성장이 이루면서 핵심가치로 삼은 것은 ‘절약’과 ‘효율성’이기 때문에 직원의 행복과 만족을 중요시하는 홀푸드의 조직문화가 아마존의 문화와 조화를 이루기 위해 어떻게 변화되고 자리를 잡아나갈지 그 또한 관심을 가지고 지켜볼만한 점인 것 같습니다.더욱 재미있는 것은 한 때 아마존의 경쟁자들이었던 백화점 유통업체들이 아마존이 홀마트를 인수하는 것을 보면서 홀마트처럼 자신들도 아마존의 러브콜을 받아 부진을 극복해보기를 바라는 곳들도 생겨났다는 점입니다. 시장은 항상 변하기 마련이지만 '이윤창출' 보다는 '고객 편의와 확보를 통한 시장 확장'에 비중을 두는 아마존의 엄청난 성장은 어쩌면 당연한 것인지도 모르겠습니다.

기업문화 엿볼 때, 더팀스

로그인

/