개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
새로운 버전에는 아주 많은 기능들이 추가 됐고 버그들도 많이 수정됐습니다. 유료사용자분들은 이미 알고 계시겠지면 새로운 분들을 위해서 아래 주요한 내용들을 정리해 드리겠습니다.
In-app purchase on (Google Play/Android Marketplace)
Remote push notifications (iOS)
Game Center (iOS)
Facebook Single-sign on
Lua File System for creating, removing, getting contents of directories
Native video and web display objects (iOS)
And much more — you can read them all in the release notes.
저희는 지금 여러 기능들을 추가하고 고품질의 daily build를 제공하기 위해 새로운 지점에 와 있습니다.
다음주에 시작해서 최근에 말씀드린 첫번째 feature cycle을 시작할 겁니다. 바로 2-on-2 development의 일부분입니다. push 기능과 버그 수정입니다. 이 사이클이 끝날 즈음에는 여러분들이 이 기능을 앱 스토어 -iOS App Store, 구글 플레이, Nook Store, Amazon App Store- 에 출판할 수 있게 될 겁니다.
여러분들이 많이 원하시는 기능들에 대한 개선도 있습니다. 어느 정도 개발 이 완ㄹ 되면 daily build를 통해 여러분께 선보일 겁니다. 그리고 진짜 cool 한 SDK feature와 관련되서도 작업을 하고 있습니다. 여러분들께 말씀 드릴 수 있는 것은 저희 내부 적으로 부르는 이름인데요. Aloha 와 Flatland 입니다. 이게 공식적인 이름이 될지는 아직 모릅니다. 다만 daily build release에 이 기능이 추가 되서 언급이 되면 여러분들이 생소하지 않으시라고 이름을 알려 드립니다.
Corona Labs Celebration Sweepstakes에 이미 참가하시고 새로운 페이스북 페이지에 support 해주신 많은 분들께 감사드립니다. 콘테스트가 아직 반도 안 왔습니다. 아직 여러분께 알려드릴 많은 상품들이 있습니다. 단지 여러분이 하실 일은 한번 enter 하세요 그리고 저희의 새로운 Corona Labs Facebook page 에 Like 를 남겨 주세요. 아주 쉽죠? 일찍 enter 하실 수록 상품을 탈 가능성이 점점 커집니다. 주저하지 마세요.
콘테스트를 실시한 이후로 3명의 당첨자가 나왔습니다. 깔끔한 Corona Swag Pack 을 받으신 Justin Giles 그리고 100불 상당의 아이튠즈 상품권을 받으신 Nick Anderson씨에게 축하드립니다. 그리고 조만간 Corona Book Collection 당첨자가 나올 겁니다.
What are the prizes and when will winners be announced?
이번 콘테스트에서 대상은 3천불 상당의 Corona Enterprise license입니다. 저희들은 매일 정오에 다른 상들에 대해 추첨을 할 겁니다. 그 스케줄은 아래와 같습니다.
Friday, June 22: 1 seat to a year-long Corona Levels subscription (currently in Beta) Monday, June 25: 6 month Corona Pro subscription Tuesday, June 26: 1 hour of Premium Support Wednesday, June 27: 1 seat to a year-long Corona Enterprise license (worth $3,000!)
How can I enter the contest?
아주 간단합니다. form을 작성해 주시고 Facebook 의 Corona Labs에 Like를 남겨 주세요. 일찍 enter 할 수록 당첨될 확률이 더 높습니다. 마감은 6월 28일 정오까지 입니다. (미국 Pacific Time)
Roberto Ierusalimschy 씨가 Corona Labs의 가족이 되서 technical advisor and mentor 로 도움을 주시게 된 것을 진심으로 진심으로 환영합니다. 많은 분들이 아시듯이 Roberto는 Lua 의 핵심 architect 입니다. 코로나 앱이 이 언어를 사용하고 있고 gaming 부분에서는 표준으로 통하고 있죠.
저는 2010년에 Game Developer’s Conference (GDC SF)에서 Roberto를 처음 만났습니다. 그는 참 겸손했습니다. 올해 초 그는 스탠포드 대학교의 visiting professor로 초청됐습니다. 몇달 전 저녁식사 자리에서 스탠퍼드에서 연구한 결과에 대해서 아주 강조했던 것을 기억합니다. 그러면서도 자신의 공은 별로 없는 듯이 얘기 하더군요. 그래서 제가 농담 겸 해서 그와 그의 동료들이 있었기 때문에 GDC 가 존재할 수 있었다는 것을 다시 상기 시켜 줬습니다. Roberto를 부끄러워하게 만들 수 있는 한가지 방법은 그를 과도하게 칭찬하는 겁니다.
Roberto와 그의 동료인 Luiz Henrique de Figueiredo 그리고 Waldemar
Celes 의 업적에 의해 얼마나 많은 삶들이 영향을 받았는지 모릅니다. Lua는 embedded device에서 스마트폰 그리고 데스크탑 컴퓨터까지 애플리케이션을 만드는데 아주 광범위하게 사용되고 있습니다. 얼마나 많은 사람들이 Rovio의 앵그리 버드를 사용하는지를 한번 생각해 보세요. 얼마나 많은 사람들이 얼마나 오랫동안 World of Warcraft를 즐기는지를 생각해 보세요. 얼마나 많은 사람들이 Adobe Photoshop Lightroom으로 사진을 편집하나요.
Roberto는 분명히 이 우주에 그의 족적을 뚜렷이 남겼습니다. 우리의 목표를 향해 나아가는데 이 보다 더 좋은 멘토는 없을 겁니다.
이번주의 튜토리얼은 약간 다른겁니다. 코로나의 다른 기능들에 대해 다루기 보다는 어느 특정 기능보다도 더 중요하다고 할 수 있는 전체 코로나 개발에 대한 측면에서 바라볼 겁니다. 여러분이 오늘 배우실 것은 여러분이 코로나 프로젝트를 진행하면 반드시 사용하셔야 하는 분야 입니다. 바로 Corona SDK API Reference 이죠
Corona API Reference는 코로나의 특정 기능을 어떻게 사용하느냐에 대해서 배울 수 있는 문서 입니다. 특정 이벤트나 객체 타입에 대한 정보도 얻을 수 있고 항상 사용하셔야 할 자원입니다. 그러므로 이에 대한 튜토리얼을 소개하는 것은 당연하게 필요한 것이겠죠.
만약 여러분이 아직까지 API Reference를 충분히 활용하지 못하고 계신다면 처음에는 너무 많은 정보와 배울것들이 있다고 느낄겁니다. 오늘 제가 전반적인 내용을 훑어서 알려드리겠습니다. 그리고 이 Corona API reference가 더 좋아질 수 있도록 여러분이 도움을 주실 수 있는 방법도 알려드리겠습니다.
Interface Overview
코로나로 앱을 개발하기 위해 API를 많이 참조하시는 분은 지난주 이 API reference 웹 페이지가 새로 개편된 것을 보셨을 겁니다. 예전 페이지를 많이 참조하셨던 분들은 이번에 인터페이스가 완전히 바뀌어서 약간 불편해 하시는 분도 계실 수 있습니다. 하지만 조금 더 써보시면 훨씬 좋아졌다는 것을 느끼실 겁니다. 새 창이나 새 탭에 Corona API Reference를 띄우시고 아래 내용을 쭉 따라가 보세요.
Navigation and Sidebar
위쪽 sidebar에 있는 navigation bar는 보시면 아실 겁니다. 코로나의 전체 documentation을 크게 3부분으로 나눠서 각 section으로 갈 수 있도록 만들었습니다.
왼쪽은 각 세부 섹션들에 직접 갈 수 있는 링크들이 있습니다. Jump to... 드롭 다운 메뉴도 이 좌측 링크들과 비슷한 역할을 합니다. 하지만 좌측 메뉴는 그 세부 섹션 페이지로 가는데 반해 이 드롭다운 메뉴는 현재 페이지 내에서 해당 항목으로 가는 겁니다. (페이지가 바뀌지는 않습니다.)
이 API Reference page는 코로나의 모든 함수, 이벤트, 프로퍼티, object methods 그리고 data type 들에 대한 리스트가 있는 index 입니다. 여러분이 무엇을 찾는지 확실하게 아신다면 ctrl+F 를 누르셔서 검색하는 게 가장 빠른 방법입니다. 또 다른 유용한 기능은 아래쪽에 있는 바로 breadcrumbs 라고 합니다. 이 하단의 바는 항상 있는데요. 여러분이 지금 어디에 있는지 알려주는 역할을 합니다.
Libraries 컬럼은 Corona에 내장된 함수의 리스트 입니다. (display.newImageRect()나 storyboard.gotoScene() 같은). Events 리스트는 다양한 이벤트의 종류를 열거했습니다. 그리고 각 이벤트들에 대한 연관된 프로퍼티들도 있구요.Types
는 코로나의 여러 데이터 타입들을 포함하고 있습니다. 그리고 Library 함수들에 의해 생성된 객체들하구요 그와 관련된 프로퍼티와 메소드들(특정 객체 타입에 attached 된 함수들)이 있습니다.
Reference Pages
각각의 API reference 페이지들은 특정 함수와 프로퍼티 등에 대해 여러분들이 알아야할 모든 정보가 있습니다. 만약 여러분이 이 library 함수에 대한 아무 페이지나 보시게 되면 -예를 들어 display.captureScreen() 같은 - 아래 이미지와 같은 내용을 보실 겁니다. 보시면 아시겠지만 이전의 API reference 보다 더 많은 정보들이 있습니다.
딱 보면 어떤 종류의 객체(혹은 데이터 타입)를 이 함수가 return 하는지 Revision (Build)이 뭔지, parent library 는 뭔지 그리고 관련된 키워드는 무엇이 있는지 그리고 연관된 링크(다른 API나 튜토리얼, 외부 웹페이지 등) 등을 보실 수 있습니다. 다른 타입의 API 페이지는 윗 부분에 다른 내용들이 있을 겁니다. 그건 그 타입에 걸맞는 내용들입니다.
좀 더 아래쪽에는 overview가 있습니다. 여기에는 일반적으로 조심해야 될 부분이나 헛갈리는 부분에 대한 설명이나 syntax structure, 관련된 함수 파라미터들 그리고 예제들이 있습니다.
Searching the Documentation
만약 여러분이 특정 API 페이지를 찾으셔야 한다면 home/index 페이지로 가세요. 그리고 브라우저에서 page search 를 하시던가 좌측 메뉴 링크를 이용하시던가 Jump To 드롭다운 메뉴를 이용하세요. 그런데 그 API의 정확한 이름을 모르신다면 전체 Corona Docs에서 키워드를 사용해 검색을 하실 수 있습니다. (구글에서 검색하시는 것처럼요). 검색 필드는 오른쪽 위에 있습니다. (아래 이미지를 참조하세요.)
검색 결과는 구글이 코로나 내의 블러그나 API reference page 들에서 검색한 내용입니다. images를 타입하시고 엔터키를 쳐 보세요. 그 정확도에 놀라실 겁니다.
Help Improve the API Reference
새로운 API reference는 이전 API reference 보다 많이 개선 되었습니다. 하지만 완벽한것은 아니라는 것을 저희들은 압니다. 우리가 중요한 것을 간과하거나 잊어버리고 만들었을 수도 있습니다. (그것이 이전 API reference에 있었을 수도 있고 없었을 수도 있구요.) 어딘가 오탈자가 있을 수도있구요. 예제가 있어야 되는데 빠져 있을 수도 있구요.
코로나 API Reference 웹사이트는 계속 보완을 해 나갈 겁니다. 그리고 저희 스스로도 계속 보완할 내용을 찾는 작업을 할테고 여러분의 feedback 도 계속 받겠습니다. 특정 API 페이지에서 어떤 잘못 된 것을 발견하시거나 빠진것을 발견하시면 저희에게 알려 주세요. 그 방법은 아주 간단합니다. 각 API Reference Page의 아래쪽에 3개의 링크를 보실 수 있을 겁니다. 관련된 링크를 누르고 그 내용을 넣어 주시면 됩니다.
그러니까 API 에 관련해서 잘못 된 부분을 알려주시려면 이 블로그 글의 댓글을 달기 보다는 해당 API 페이지에 가셔서 밑에 있는 링크를 누르고 알려 주시면 감사하겠습니다. 그 링크를 누르시면 몇개의 checkbox들이 있을 겁니다. 그리고 comment 필드도 있구요. 관련 사항에 체크하시고 가급적이면 자세하게 코멘트를 달아 주세요.
여러분들 중에 이미 많은 분들이 이 feedback form을 사용해 보셨을 겁니다. 이 웹사이트를 지난주에 오픈했는데도 이미 많은 글들이 올라왔거든요. 저희들의 실수를 지적해 주신 모든 분들께 감사드립니다. 그리고 의견을 올려 주신분들도 감사드리구요. 여러분들 중에 몇분은 아주 잔인할 정도로 정직하시더라구요. 그게 바로 저희들이 원하는 겁니다. 계속 와 주세요. 지금 코로나의 함수들, 이벤트들 그리고 객체 프로퍼티와 메소드들에 대해 정통한 정보를 찾아서 사용 하세요.
Still confused?
만약 API Reference 페이지가 아직 헛갈리시면 그리고 어디서부터 시작해야 할 지 모르시면 우선 보실 필요가 있는 곳이 Guides 섹션 입니다. 여기에는 초보자 분들을 위한 Corona SDK Quick-Start 가 있습니다.
이 글은 주로 이 transition.to()함수에 대해 다룰 겁니다. 코로나의 transition library를 사용할 때 가장 많이 사용해야 할 함수죠. 대략적으로 정리하자면 transition.to() 는 두개의 파라미터를 사용합니다. 애니메이션 효과를 줄 객체와 그리고 회전, 투명도 x,y 값의 combination으로 구성되는 ending property 들의 조합인 table로 구성돼 있습니다. 그리고 이 transition에 걸릴 시간과 옵션으로 이 transition이 끝났을 때 호출될 함수도 넣을 수 있습니다. 이 transition이 시작되면 이 객체의 현재 value들은 여러분이 정해준 값으로 "tweened" 됩니다.
여러분이 코로나를 이용해 게임등의 앱을 개발하면서 충분한 시간을 투자할 수 없는 상황이라면 아마도 이 함수를 사용하실 겁니다. 이 함수는 아주 많이 유용하거든요. 여러분도 아시게 되겠지만 이 함수는 사용하기에 아주 많이 쉽기도 하거든요.
Fading an Object
아주 기초적인것 부터 시작하겠습니다. 우리는 객체를 생성할 거고 이 객체가 점차 투명해져서 사라지도록 만들 겁니다. 여러분들도 이미 아시겠지만 display object의 alpha 프로퍼티가 그 객체의 opacity를 담당하고 있습니다. 그래서 그 프로퍼티를 transition.to() 함수에 pass 해서 1.0에서 0 이 되도록 만들 겁니다. (1.0은 투명도가 전혀 없는 상태고 0은 완전 투명해서 안 보이는 상태입니다.)
아래 예제를 보세요. 우리는 이렇게 객체가 사라지는 시간을 3초로 정할겁니다. (3000 milliseconds)
local obj = display.newImage( "image.png" )
-- center the object
obj.x = display.contentWidth*0.5
obj.y = display.contentHeight*0.5
위 코드는 객체를 생성하고 "tweens" 해서 그 alpha 프로퍼티를 1.0에서 0으로 3초동안에 변화 시키도록 하는 겁니다. 아주 간단합니다. 이제 저 객체가 완전히 투명해져서 안 보이게 되면 그 객체를 완전히 remove 해 버리죠. 이 transition이 끝났을 때 실행 될 함수를 call 할 수 있습니다. 그걸 하려면 onComplete 파라미터를 사용하시면 됩니다.
local obj = display.newImage( "image.png" )
-- center the object
obj.x = display.contentWidth*0.5
obj.y = display.contentHeight*0.5
local function removeObject( object )
object:removeSelf()
obj = nil -- nil out original reference (upvalue)
end
NOTE: 저 객체의 transition이 첫번째 argument에서 onComplete 리스너 함수까지 어떻게 진행되는지 그리고 구현하는것이 얼마나 쉬운지 보세요. 이것을 활용해서 여러 transition들에 대해 이 한가지의 listener를 만들어서 사용하실 수 있습니다. 또는 저 객체가 out of scope 일 때도 그 리스너를 사용하셔도 됩니다.
Moving Objects
transition.to() 함수의 아주 유용한 부분중의 하나는 한번에 tweening 하는데 한가지만의 프로퍼티만 사용하라는 법이 없다는 겁니다. 우리 첫번째 예제를 조금 바꿔서 그 객체를 좌상단에서 우 하단으로 움직이면서 투명해지도록 해 보죠.
local obj = display.newImage( "image.png" )
-- set starting position (top-left of screen)
obj.x, obj.y = 0, 0
local function removeObject( object )
object:removeSelf()
obj = nil -- nil out original reference (upvalue)
end
-- some variables to be used in the transition
local end_x = display.contentWidth
local end_y = display.contentHeight
-- fade object to completely transparent and move the object as well
transition.to( obj, { time=3000, alpha=0, x=end_x, y=end_y, onComplete=removeObject } )
Easing Library
코로나의 Easing Library 는 transition.to() 함수와 함께 쓰여서 transition 프로퍼티를 통해 transition의 behavior 를 하는데 다루는 데 사용되어 질 수 있습니다. 디폴트로 이 transition 프로퍼티는 easing.linear로 세팅돼 있습니다. 이것은 transition이 처음부터 끝까지 같은 공간에서 꾸준히 tween 되는 상태를 말합니다.
각 transition 프로퍼티 behaves를 설명하는 것은 약간 어렵습니다. 백문이 불여일견이라고 샘플 앱에서 Transition1과 Transition2 예제를 보실것을 권장합니다. 이 샘플은 아래 경로에 있습니다.
/SampleCode/Graphics/Transition1
/SampleCode/Graphics/Transition2
이 샘플 예제를 보시고 다른 transition type들을 적용하면서 실행해 보세요. 이렇게 하는게 가장 쉽고 확실하게 배우는 길입니다. 그리고 여러분이 배운 Corona의 transition library에 대한 모든 것을 확실히 다져 주세요.
Canceling Transitions
In the event you need to stop a transition mid-way through, you can do so by using the transition.cancel() function. However, this function requires that you store a reference to an id of the specific transition you need to cancel.
여러분이 transition이 일어나는 중간에 이를 stop 시킬 필요가 있다면 여러분은 그렇게 하실 수 있습니다. transition.cancel() 함수를 사용하시면 됩니다. 이걸 이용하시려면 해당 transition의 id를 사용하셔야 합니다.
그러니까 이 transition을 cancel 하기 이전에 그 transition의 id를 variable에 store 할 필요가 있습니다. 아래 첫번째 예제를 약간 바꾼 샘플이 있습니다. 해당 transition 아이디를 transition_id 라는 변수에 대입을 했습니다.
local obj = display.newImage( "image.png" )
-- center the object
obj.x = display.contentWidth*0.5
obj.y = display.contentHeight*0.5
-- fade object to completely transparent
local transition_id = transition.to( obj, { time=3000, alpha=0 } )
Now, we can cancel the transition at any time by passing that stored
id as the first parameter to transition.cancel(). In the following
example, we’ll cancel the transition after 1.5 seconds.
local obj = display.newImage( "image.png" )
-- center the object
obj.x = display.contentWidth*0.5
obj.y = display.contentHeight*0.5
-- fade object to completely transparent
local transition_id = transition.to( obj, { time=3000, alpha=0 } )
timer.performWithDelay( 1500, function()
if transition_id then
transition.cancel( transition_id )
transition_id = nil
end
end, 1 )
위에서도 언급했는데요. 우선 transition을 cancel 하기 이전에 그 transition이 존재해 있어야 합니다. 여러분이 실전에서 코딩을 하실 때는 반드시 해당 transition이 선언돼 있는지 확인하시기 바랍니다.
그리고 여러분이 transition.cancel()을 call 할 때는 그 transition id를 저장하기 위해 사용한 변수를 nil-out 시키시기 바랍니다. 그렇게 하지 않으면 skeleton table이 남겨져 있게 됩니다. (마찬가지로 object:removeSelf() 한 이후에도 반드시 그 변수를 nil-out 시켜 주세요.)
WARNING: Do not remove currently transitioning objects!
만약 현재 tweened 되고 있는 객체가 remove 된다면 여러분의 앱은 crash를 일으킬 겁니다. 이것은 scene change 할 때 종종 일어나는 현상인데요. scene change를 하기 전에 transition.cancel()을 현재 active 상태에 있을 법한 변수에 적용하는 것이 에러가 일어날 가능성을 미리 방지하는 방법일 겁니다. 이 부분은 exitScene 이벤트 리스너에서 수행하는것이 가장 이상적입니다. 좀 더 자세한 사항은 Storyboard Scene Events Explained를 확인하세요.
오늘부터 우리는 ‘Corona Labs Celebration
Sweepstakes’ 를 시작합니다. 그리고 여러 상품도 준비했습니다. (대략 $3800 어치 선물). 이제 숫가락을 드시고 그 상품을 어떻게 먹을 수있는지 아래를 잘 살펴 보세요.
What prizes are we looking at?
Grand Prize: $3000 상당의 1년간 Corona Enterprise license 입니다. 아래 내용들을 잘 살펴 보세요.
More great prizes:
1 hour of Premium Support (worth $225)
6 month Corona Pro subscription
1 year Corona Levels subscription (currently in beta)
$100 iTunes gift card
1 Corona Book Collection: “Corona SDK Mobile Game Development:
Beginner’s Guide” by Michelle Fernandez and Mobile App Development with
Corona” by Brian Burton
1 Corona Swag Package: mug, t-shirt, stickers and more!
How can you win these awesome prizes?
아주 간단합니다. 여러분이 해야 될 일은 6월 28일 정오까지 (Pacific Time) Corona Labs Celebration Sweepstakes 에 enter 해 주세요. 그리고 페이스북에 저희에 대해 Like 해 주세요. 그냥 이렇게만 해 주시면 위 상품을 탈 수 있는 기회를 가질 수 있습니다.
How and when will we select the winners?
저희는 아래 날짜들 정오쯤에 랜덤하게 entrants 하는 분 들 중에 당첨자들을 뽑을 겁니다.
June 15: Corona Swag Package
June 18: Corona Book Collection
June 20: $100 iTunes gift card
June 22: 1 year Corona Levels subscription
June 25: 6 month Corona Pro subscription
June 26: 1 hour of Premium Support
June 27: 1 seat to a year-long Corona Enterprise license
오늘부터 우리는 우리를 Corona Labs라고 부르기로 했습니다. 여러분들 중에 미리 알고 계신분들도 계시겠지만 모르시는 분들을 위해서 몇가지 질문들에 대한 답변을 드리겠습니다.
왜 Corona Labs죠?
글쎄요. Corona는 당연하겠죠? 그런데 왜 Labs 가 들어갈까?
작년 12월에 말했듯이 코로나는 그냥 단순한 목적에서 만들어지지 않았습니다. 실제 사람들의 삶을 바꾸기 위해 만들어 졌습니다. 그 기준으로 우리가 목표로 삼을 수 있는 곳이 어딜까요? 벨 연구소 입니다.
벨 연구소 벨연구소는 1925년 설립된 세계 최고 수준의 민간 연구개발 기관이다. 설립 이래 3만 3000개가 넘는 특허와 13명의 노벨과학상 수상자를 배출했다. 20세기에는 정보통신 네트워크 시대를 이끌었고 21세기 들어서는 커뮤니케이션 혁신에 집중하고 있다. 원래 벨 시스템 사의 연구개발 연구소로 설립됐다. 1925년 당시 AT&T 사장이던 월터 기포드가 독립적인 성격의 기관으로 벨연구소를 설립했다. 연구소 명칭은 세계 최초 전화기 발명가인 알렉산더 그레이엄 벨의 이름을 땄다. 2006년에는 AT&T에서 프랑스의 알카텔-루슨트로 주인이 바뀌었다.
벨연구소가 개발한 제품으로 대표적인 것에는 전화교환기에서부터 전화선 피복, 트랜지스터 등이 꼽힌다. 1947년에 트랜지스터를 발명한 존 바딘, 윌리엄 쇼클리, 월터 브래튼은 1956년 노벨 물리학상을 수상했다. 디지털 카메라 기술도 벨연구소에서 나왔다. 1970년 윌라드 보일과 조지 스미스가 디지털 카메라 핵심 기술을 발명해 발표했고 두 사람은 2009년 노벨 물리학상을 받았다. 이 밖에 광케이블, 통신 위성기술 등도 벨연구소의 작품이다. 2005년 외부 출신으로는 처음 벨연구소 사장으로 한국인 김종훈 씨가 영입되기도 했다. 미국 뉴저지 주에 있다.
유닉스와 C 가 어디에서 나왔을까요. 태양광 모듈을 어디에서 나왔을까요? 디지털 카메라에 있는 CCD는 어디서 나왔을 까요. 이것 말고도 더 많이 있습니다. 이 기술들에 대한 핵심 기술과 기반 혁신은 벨 연구소에서 나왔습니다.
그들은 말 그대로 현대의 컴퓨터 세계를 만들어 냈습니다. 우리는 과학계에 그런 근본적이고 결정적인 영향을 주고 싶습니다. 그래서 "Corona Labs" 입니다.
이제 coronalabs.com 으로 접속하셔도 됩니다.
왜 이름을 바꿀 생각을 했을까요?
우리는 Corona 가 앱 개발자들에게 그냥 가족처럼 친숙한 이름이 됐으면 합니다. 지금까지 우리는 회사이름으로 Ansca 그리고 제품 이름으로 Corona를 사용했었는데요. 이게 내외적으로 좀 혼란스러웠거든요.
지난 몇년간 우리는 대부분의 사람들이 우리를 Corona를 만든 사람들로 생각하는 것을 관찰해 왔습니다. 그들은 Ansca라는
존재에 대해서도 몰랐습니다. 그 예로 고객들이 그들의 신용카드 영수증에 Ansca라는 이름이 찍혀있는걸 보고 이게 Corona
제품을 산 것에 대한 영수증이라는 것을 많은 사람들이 알아차리지 못했거든요.
사람으로 치면 회사가 진짜 이름하고 별명 두개를 갖고 있었던 거죠. 모두들 우리의 별명을 부르고 있었고 별명으로 기억하고
있었습니다. 그리고 모든 사람들이 그 별명을 좋아했습니다. 그래서 우리는 공식적으로 우리의 별명을 이름으로 사용하자고 결정했죠.
바뀐 이름에 어떤 큰 의미가 있을까요?
큰 의미가 있다면 Corona Labs는 평범한 lab이 아니라는 겁니다. 예전에는 labs (연구소)는 일종의 동굴 같았습니다. 외따로 떨어져있었고 밀폐된 환경이었습니다.
우리가 생각하는 Corona Labs는 근본적으로 다릅니다. 우리는 가장 개방적인 연구소로 만들 생각입니다. 다른 연구소들이
비밀을 간직할 때 우리는 좀 더 투명해 지려고 노력할 겁니다. 그 일환으로 여러분들은 지금까지의 site에서 우리늬 bug들을
보실 수 있었던 겁니다. 그리고 왜 우리들은 우리들의 roadmap에 대해 여러분들의 feedback을 받을까요. 바로 더 투명해
지려는 노력중 하나입니다.
그리고 마지막으로 코로나 팀들의 노고가 거기에 있었습니다. 여기 Corona Labs의 인간들은 정말 비범하게 헌신적입니다.
그러나 팀이란 그 인간들만을 말하는 것은 아닙니다. 그 팀에는 여러분 모두도 해당됩니다. 우리의 정말 대단한 Corona
community 가 우리 한 팀입니다.
여러분들이 우리에게 영감을 주었고 우리의 삶을 바꾸어 놓았습니다. 우리는 Corona Labs가 다음세대에도 계속 왕성하게 활동함으로서 그에 대한 화답을 하기를 바랍니다.
왜 시뮬레이터하고 디바이스하고 텍스트 spacing/positioning이 약간 다른가요? Answer
시뮬레이터와 디바이스는 서로 폰트들이 다릅니다. native.systemFont는 OS에 따라 다르게 됩니다. 맥에서는 LucidaGrande 24 pt이고 iOS에서는 Helvetica 입니다. 그리고 윈도우즈는 또 다릅니다. 다른 폰트는 사이즈가 같더라도 약간 다른 공간을 차지합니다. 그래서 alignment에 다른점들이 있게 됩니다.
같은 폰트라도 OS가 랜드링을 하면서 다를 수가 있습니다. 맥OS와 iOS는 비슷한 code paths를 사용하지만 기본 text drawing은 약간 다릅니다. 같은 폰트라도 약간 다르게 glyph를 랜더링 할 수가 있습니다. 그것은 저희쪽에서 어떻게 할 수 있는 문제가 아닙니다.
이렇게 서로 다르게 나타나는 것을 방지하려면 bitmap fonts를 사용하는 수밖에 없습니다.
Question 2
display.newText로 text를 aligning 하는데 문제가 있습니다. 제대로 잘 하려면 어떻게 해야죠?
Answer
display.newText는 x,y 파라미터를 top, left를 위치시키는데 사용하게 됩니다. 여러분이 객체를 생성하고 난 후 x,y를 세팅하면 디폴트로 text의 중앙을 세팅하게 됩니다. object가 생성될 때와 같은 alignment를 사용하려면 bject:setReferencePoint( display.TopLeftReferencePoint )를 사용하실 수 있습니다. (좀 헛갈리죠? 그래서 이런 factory methods로 x,y 파라미터의 alignment를 컨트롤 할 수 있도록 준비하고 있으니 조만간 나오는 Daily Build 에서 반영 될 겁니다.)
그리고 display.newText가 call 되는 방법에 따라 width(w)와 height(h)를 어떻게 계산하는지도 이해하는게 헛갈리기도 합니다.
w,h 가 제공되지 않으면 display.newText는 한줄짜리 객체를 생성하고 제공된 string에 맞게 대략적으로 사이즈도 생성됩니다. 이 w,h에 따라 x,y 포지션이 결정됩니다. w,h 가 정해져 있으면 display.newText는 제공된 width/height 를 사용해 포지션을 계산합니다. 그렇게 해서 x,y가 top left 가 됩니다. (만약 h가 0dlaus height는 해당 string에 따라 달라집니다.)
그러니까 생성하고 난 후 x,y를 세팅할 때 (예. txt.x = xAlign) 여러분은 디폴트로 object의 center를 세팅하게 됩니다. 그래서 두개의 text 객체가 같은 string 이지만 다른 width를 가질 수 있습니다. 그렇게 되니까 center로 세팅하면 좌측 정열이 되지 않는겁니다.
Question 3
여러 API를 사용해 baseDirectory를 봤는데요. 왜 이건 subdirectory를 지원하지 않죠?
Answer
display.newImage와 다른 API들이 사용하는 baseDirectory 파리미터는 시뮬레이터나 디바이스에서 사전에 지정된 시스템 디렉토리를 명시하기 위한 optional parameter 입니다. 이 파일 시스템은 sandboxed 입니다. 그래서 baseDirectory는 다음과 같은 것들 중 하나 입니다.:system.ResourceDirectory, system.TemporaryDirectory, system.DocumentsDirectory. 만약 아무런 baseDirectory가 명시돼 있지 않으면 디폴트로 system.ResourceDirectory가 됩니다.
만약 subdirectory를 참조할 필요가 있으면 그 디렉토리는 file name에 추가 되야 합니다. baseDirectory 파라미터에 추가 되지 않습니다. 아래에 Resource directory와 Document directory안에 myImages 라는 서브디렉토리의 이미지에 접근하기 위한 몇개의 샘플코드가 있습니다.
local image1 = display.newImage( "myImages/redBall.png", 10, 200 )
-- This next line is the same as the previous local image2 = display.newImage( "myImages/redBall.png", system.ResourceDirectory, 10, 200 )
local image3 = display.newImage( "myImages/redBall.png", system.DocumentsDirectory, 10, 200 )
Note: Documents directory는 이미지나 파일들을 저장하는데 사용될 수 있습니다. 이 때 어플리케이션은 반드시 먼저 그 디렉토리에 파일을 create/copy 해야 합니다.
여러분은 system.pathForFile인 디렉토리를 명시하거나 subdirectory의 path를 명시하는데 사용될거라고 생각할 수 있습니다. 하지만 baseDirectory가 필요한 곳에서는 제대로 작동하지 않을 겁니다.
Question 4
. 와 / 를 사용해서 subdirectory들에 접근하는게 잘 혼동되요. Answer
간단하게 답변을 드리면 . 는 require API로 로드된 서브 디렉토리안의 모듈에 접근하는데 사용되고 / 는 다른 모든 API들에 사용됩니다. (이전 질문 답에서 보여드렸던 display.newImage 같은 겁니다.) storyboard.gotoScene도 require를 사용하므로 . 가 서브디렉토리의 scene 모듈에 접근하는데 사용되는 겁니다.
만약 movieclip.lua 모듈과 Image가 assetes 서브디렉토리에 있다면 어떻게 접근해야 하는지 아래에 예제가 있습니다.
local movieclip = require( "assets.movieclip" ) local image1 = display.newImage( "assets/redBall.png", 10, 200 )
Question 5
File I/O API에서 baseDirectory를 찾아 볼 수가 없어요. 어떻게 이 디렉토리를 명시하죠? Answer
io.open API는 파일을 읽고 쓰기 위해 open을 사용합니다. 여기서 디렉토리와 파일 이름이 포함된 스트링인 path를 명시하죠. 이 스트링은 system.pathForFile로 생성됩니다. 아래에 File I/O를 사용해서 어떻게 디렉토리를 명시하는지 보여드립니다.
local path = system.pathForFile( "data.txt", system.DocumentsDirectory )
-- Open a file path local fh, reason = io.open( path, "r" )
if fh then -- Read all the contents of the file into a string local contents = fh:read( "*a" ) print( "Contents of " .. path .. "\n" .. contents ) else print( "Reason open failed: " .. reason ) end
만약 서브디렉토리 안의 파일에 접근하실 필요가 있다면 파일 이름에 서브디렉토리를 append 하시면 됩니다. 아래 예제는 Resource directory에서 서브디렉토리로 접근하기 위해 path를 사용하는 방법을 보여 드립니다. local path = system.pathForFile( "myFiles/data.txt", system.ResourceDirectory )
오늘은 여기까지 입니다. 즐거우셨기를 바라구요. 새로운거 몇가지를 배울 수 있는 기회가 됐다면 좋겠네요.
요즘 웹페이지를 표시하는 디바이스들이 많이 늘어나다 보니까 하나의 웹페이지를 데스크 탑, 모바일 폰, 타블렛 PC 등 다른 해상도의 디바이스들에 맞는 레이아웃을 각각 만들 필요가 있어 졌습니다.
이 Responsive WEB은 HTML5이 Media Queries 를 이용하여 하나의 소스로 제작된 컨텐츠로 여러 해상도의 화면을 제공할 수 있도록 만드는 개념입니다.
대표적으로 Boston Globe 가 있는데요.
1. A flexible, grid-based layout : 그리드를 상대적(% 단위 등)으로 지정하여 브라우저 크기에 따라 유동적으로 변환 2. Flexible width media: images, video : 너비가 변경되어도 웹페이지 안의 미디어가 넘치지 않게 하는 기법 3. Media queries : 다양한 브라우저에서 표현양식을 제어할 수 있게 고안된 기능
Responsive WEB에는 이 세가지 개념이 기본적으로 깔려 있습니다.
그런데 이 반응형 웹은 IE8 미만에서는 사용할 수 없다고 합니다.
오늘 제 immediate manager 인 Rajesh 가 Boston Globe를 보여주면서 이거 어떻게 하는지 아냐고 물어보더라구요.
예전에 이 Responsive WEB 소스코드로 한번 연습한 적이 있어서 대충 알려 줬는데요.
<body>
<h1>Simple one</h1>
<div id="pc_view">
<h2>Desk Top PC </h2>
<p>Make this browser narrow then 800 px. 브라우저의 너비를 800 px보다 작게 줄여보세요. </p>
<p>You can see Black background and White text. 배경이 검정색에 글자가 흰색으로 바뀔 겁니다. </p>
</div>
<div id="mobile_view">
<h2>Mobile</h2>
<p>Make it wider then 800px. 브라우저의 너비를 800 px이상으로 크게 늘여보세요. </p>
<p>White BG and Black Text. 배경이 흰색에 글자가 검정색으로 바뀔 겁니다. </p>
</div>
</body>
</html>
이게 제일 간단한 소스인데요.
우선 보시면 HTML5를 지정했구요. Charset 을 utf-8으로 하는 메타태그가 하나 있습니다.
그리고 뷰포트 메타태그가 있습니다. width=device-width 로 해서 화면을 사용자 디바이스 width 에 맞춰서 display 되도록 한 겁니다.
이 viewport 관련해서도 별도의 글에서 정리해 둬야겠네요.
그리고 그 다음이 css 파일인데요.
799픽셀 이하짜리와 800픽셀 이상짜리 두개를 따로 마련했습니다.
그리고 태그 안에 media query 가 있습니다. 이 부분에서 해상도에 맞게 css 파일을 불러 오는 겁니다.
그 다음에는 두개의 div 가 있는데 하나는 id가 pc_view 이고 다른 하나는 mobile_view 입니다.
이 id를 가지고 css에서는 어떻게 사용하는지 보죠.
우선 desktop_pc.css 파일 입니다.
@charset "utf-8";
body {
background-color: #fff; /* 배경 색상을 흰색 */
}
#mobile_view {
display : none; /* mobile_view선택자 영역은 화면에서 생략 */
}
보시면 여기서는 mobile_view 의 display 를 none으로 했죠?
그러면 pc_view 만 나오게 됩니다.
그럼 mobile.css를 보실까요?
@charset "utf-8";
body {
color: #FFF; /* 글자 색상을 흰색 */
background-color: #000; /* 배경 색상을 검정 */
}
#pc_view {
display : none; /* pc_view 영역은 화면에서 생략 */
}
많은 경우 데이터를 share 하고 모듈간에 링크를 걸고 하는 것은 아주 유용하게 사용됩니다. 인터페이스의 일관성을 유지하기 위해 convention 들이 만들어 졌습니다. 이 convention들은 아래와 같은 일들을 합니다.
다른 모듈의 데이터 값을 근거로 특정 모듈로 링크를 걸거나 값을 formatting 함 (예. people 디렉토리의 값에서 맵 모듈로 링크 걸기 등)
모듈의 모델 객체에 근거한 링크 생성과 value 포맷팅 (예. calendar event의 포매팅과 retrieval)
criteria에 근거한 다른 모듈의 data retrieval (used in the federated search feature)
만약 새 모듈을 만들거나 다양한 data source로부터 데이터를 포맷하기를 원한다면 오늘 다룰 내용을 자세히 읽어 보셔야 합니다.
Formatting Data from Existing Modules
다른 데이터(map locations, people)를 참조하는 하나의 데이터 소스(LDAP directory, calendaring system)에 있는 데이터를 가지고 있는 예는 아주 많습니다. 불행히도 이 두개의 시스템사이를 연결하는 strong link 는 없을 겁니다. 그 둘을 link 하려면 bridge를 사용해야 합니다.
다른 모듈의 데이터로 링크를 걸고 다른 모듈의 데이터를 보여주는 쿠로고의 built in 모듈은 2가지가 있습니다.(People, Calendar module) detail configuration의 module=xxx 파라미터는 다른 모듈로의 링크를 생성합니다. default로는 간단하게 디렉토리의 같은 value를 사용합니다. 그리고 filter 파라미터의 value를 사용해서 target 모듈의 search 페이지로 링크를 겁니다. 그러니까 맵 모듈로 링크를 건다면 아래와 같을 겁니다.
map/search?filter=value
이것은 많은 경우에 사용됩니다. 하지만 때때로 좀 더 특정 링크를 제공해야 할 때도 있습니다. 이를 구현하기 위한 과정은 아래와 같습니다.
target 모듈의 subclass를 생성한다. (i.e. map)
Create a file named SiteMapWebModule.php in SITE_DIR/app/modules/map안에 SiteMapWebModule.php파일을 생성한다. enclosing folder들을 사용해야 할 겁니다.
이 파일은 MapWebModule의 subclass이어야 함. 이것이 그냥 맵 모듈의 extension 이라면 다른 추가적인 프로퍼티를 포함할 필요는 없음
Implement a linkForValue($value, Module $callingModule, KurogoObject $otherValue=null) method
in your subclass. This method will receive:
a value from the other system
a reference to the calling module (이것으로 여러분은 어떤 모듈이 call을 할 것인지 정할 수 있습니다. )
옵션으로 모듈에 의해 underlying object가 제공됩니다. 그렇기 때문에 여러분은 response를 generate 할 때의 모든 value들을 고려해야 합니다.
이 메소드는 list item에 대한 해당 배열을 return 해야 합니다. 여기서 최소한 title 값을 include 해야합니다. 일반적으로 link를 include 하고 싶지 않다면 url 값을 include 해야합니다.
<?phpclassSiteMapWebModuleextendsMapWebModule{publicfunctionlinkForValue($value,Module$callingModule,KurogoObject$otherValue=null){switch($callingModule->getID()){case'people'://look at the location field to see which office they are from.//This assumes the relevant location is in the "location" field.$person=$otherValue;switch($person->getField('location')){case'New York':// New York office is first entryreturnarray('title'=>'New York Office','url'=>buildURLForModule($this->id,'detail',array('featureindex'=>0,'category'=>'group:0')));break;case'Boston':// Boston office is the 2nd entryreturnarray('title'=>'Boston Office','url'=>buildURLForModule($this->id,'detail',array('featureindex'=>0,'category'=>'group:1')));break;default:// don't include linkreturnarray('title'=>$value);}break;default://return the default implementation for other modulesreturnparent::linkForValue($value,$callingModule,$otherValue);}}}
Enabling interaction from new modules
새 모듈을 만드려면 full interaction을 가능하도록 하기 위해 몇개의 메소드들이 필요합니다.
searchItems($searchTerms, $limit=null, $options=null) - 이 메소드는 필터로서 searchTerms를 사용해서 KurogoObject 인터페이스를 confirm 하는 객체의 배열을 return 해야 합니다. 여러분의 implementation은 criteria를 사용해서 간단하게 검색하기 위해 필요한 메소드들을 call 해야 합니다. 여러분은 좀 더 structured queries를 사용하기 위해 옵션 배열들을 활용할 수 있습니다. federated search method의 디폴트 impementation을 활용한다면 ederatedSearch=>true를 포함해야 할 겁니다.
linkForItem(KurogoObject $object, $options=null) - This method should return an array
suitable for a list item based on the object included. This would typically be an
object that is returned from the searchItems method. An options array is included
to permit further customization of the link. For examples, see the People, News,
Calendar and Video modules. 이 메소드는 include 된 객체를 근거로 list item에 대한 해당 배열을 return 해야 합니다. 이것은 특히 searchItems 으로부터 return 된 객체가 됩니다. options array는 링크를 좀 더 customize 할 수 있도록 하기 위해 include 됩니다. 그 예로는 People, News,
Calendar 그리고 Video module 들이 있습니다..
쿠로고 객체는 싱글턴 인스턴스 입니다. 이 객체는 모듈을 개발 할 떄 사용하는 일반적인 태스크인 여러개의 메소드들을 포함하고 있습니다.
Static Class Methods
Kurogo::sharedInstance() - shared Kurogo singleton object를 return 합니다. This is typically not
necessary to use since all publically documented methods are static methods on the Kurogo class.
Kurogo::getOptionalSiteString($key, $default=’‘) - See Configuration
Kurogo::getCache($key) - Retrieves a value from the memory cache - See Caching
Kurogo::setCache($key, $value, $ttl = null) - Sets a value to the memory cache - See Caching
Kurogo::deleteCache($key) -Removes a value from the memory cache - See Caching
Kurogo::log($priority, $message, $area) - Logs a value to the kurogo log - See Logging in Kurogo
Kurogo::encrypt($value, key) - Encrypts a value (requires the mcrypt extension). See Encryption
Kurogo::decrypt($value, key) - Decrypts a value (requires the mcrypt extension). See Encryption
The AutoLoader
PHP 클래스를 사용하기 전에 클래서 정의가 로드돼 있어야 한다는 것을 기억하세요. 쿠로고는 그 클래스의 이름과 같은 PHP 파일 인 각 클래스를 포함하는 패턴을 따릅니다. 파일들을 활용하기 위해 PHP의 require와 include 구문을 사용할 수 있도록 Kurogo는 클래스가 request 됐을 때 그 파일을 자동으로 include하는 autoloading 메카니즘을 가지고 있습니다. autoloader는 site의 lib 폴더나 base Kurogo lib 폴더를 찾을 겁니다. 그리고 그 클래스와 같은 이름의 파일을 로드할 겁니다. 그러므로 SomeClass::method()로 call을 하면 아래와 같은 파일들을 찾을 겁니다.
SITE_DIR/lib/SomeClass.php
KurogoRoot/lib/SomeClass.php
Packages
클래스 파일들의 구성을 좀 더 유용하게 하기 위해 패키지라는 개념을 사용합니다. 이것은 비슷한 기능을 갖는 파일들을 한 그룹으로 묶는 겁니다. package를 include 하면 autoloader가 그 subforlder까지 찾을 겁니다. 또한 그 lib 폴더에 있는 Package.php라는 파일을 로드하려고 할 겁니다. 이렇게 함으로서 글로벌 상수나 글로벌 함수 정의들을 로드할 수 있도록 합니다. 예를 들어 Maps 패키지가 오드되면 다음과 같은 경로가 autoloader 검색 path에 추가 될 겁니다.
SITE_DIR/lib/Maps/
KurogoRoot/lib/Maps/
그리고 autoloader는 lib/Maps.php를 로드하려고 할 겁니다.
여러분의 여러분 site의 lib 폴더에 간단하게 폴더를 추가 생성함으로써 여러분의 패키지를 생성하실 수 있습니다. 아래 패키지들은 쿠로고에서 제공하는 패키지들입니다.
Authentication (included automatically when authentication is enabled)
Authorization - for connecting to various OAuth based web services
Calendar - includes classes to deal with date and time
db - used when you wish to interact with a database
Emergency - used by the emergency module
Maps - used by the maps module
People - used by the people module
Video - used by the video module
Encryption
1.4 버전에서는 암호화 된 데이터를 저장하고 retrieve 하기 위한 메소드가 추가 됐습니다. 이것은 보안을 유지하면서 원격 서버로부터 중요한 데이터를 저장하는데 유용하게 이용될 수 있을 겁니다. 이 메소드들은 mcrypt extension 이 필요합니다. 다른 암호화 시스템 처럼 데이터를 암호화하기 위해 사용되는 키들을 보호합니다. 기본적으로는 서버 소프트웨어의 인스톨 경로를 사용해 발생되는 SITE_KEY constant를 사용하게 됩니다. site.ini에서 SITE_KEY를 업데이트 해서 이 key를 세팅할 수 있습니다.
Caching
1.4 버전에서는 in-memory
caching을 사용해서 쿠로고의 퍼포먼스를 개선하기 위한 메소드를 추가했습니다. 서버가 특정 확장자들을 포함하고 있으면 configuration 값들과 탬플릿들의 search path들 그리고 remote data values 같은 쿠로고에 의해 사용되는 caching information으로 서버의 퍼포먼스를 크게 개선하실 수 있습니다.