반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

코로나 네트워킹 과 웹 서비스 1

2011. 10. 21. 23:27 | Posted by 솔웅


반응형
Networking and Web Services

코로나는 웹 서비스를 위해서 LuaSocket library 2.02버전을 사용합니다.
이 루아 소켓 라이브러리는 SMTP, HTTP, FTP같은 프로토콜을 지원합니다. 이 외에 인코딩 프로토콜인 MIME와 URL 사용 그리고 LTN12 (데이터 트랜스퍼와 필터링) 기능도 지원합니다.
이 Luasocket은 코로나 앱에 이미 인스톨 되 있어서 director.lua나 ui.lua 같이 따로 파일을 복사해 넣을 필요는 없습니다. 하지만 앱실행시의 퍼포먼스 문제로 자동으로 로드되지는 않습니다.
그러므로 이것을 사용하기 위해서는 우선 require 해야 합니다.
local socket=require("socket") 이나 local http = require("http") 같이 먼저 선언하고 난 다음에 사용할 수 있습니다.
LuaSocket 문서는 아래 링크에서 볼 수 있습니다.

http://www.tecgraf.puc-rio.br/~diego/professional/luasocket/reference.html

아래 샘플 코드가 있습니다.
-- Load the relevant LuaSocket modules
local http = require("socket.http")
local ltn12 = require("ltn12")
 
-- Create local file for saving data
local path = system.pathForFile( "hello.png", system.DocumentsDirectory )
myFile = io.open( path, "w+b" )
 
-- Request remote file and save data to local file
http.request{
    url = "http://developer.anscamobile.com/demo/hello.png",
    sink = ltn12.sink.file(myFile),
}
 
-- Display local file
testImage = display.newImage("hello.png",system.DocumentsDirectory,60,50);

print("hello.png image is in " .. path)


일단 http 통신을 하기 위해서 socket.http를 require하고 파일을 transfer하기 위해서 ltn12를 require했습니다.
그 다음 http.request{} 부분을 보면 이미지가 있는 url을 지정하고 이 파일을 미리 지정해 두었던 myFile에 hello.png라는 이름으로 저장합니다.
io.open 으로 미리 쓰기 가능 상태로 두었습니다.
이 path는 device의 기본 폴더입니다. 캡쳐 화면의 터미널 부분을 보면 애플 컴퓨터의 디렉토리가 나오는데요. 아이폰으로 하면 아이폰 폴더 경로가 나올 겁니다.

여기 까지 하면 원격에 있는 이미지를 내 핸드폰으로 가져오는 것까지 성공 한 겁니다.
일단 가져왔으니까 그 다음엔 그냥 보여주면 되겠죠?
display.newImage() 를 통해서 이미지를 폰에 뿌려줍니다.

안드로이드에서는 인터넷을 하려며 퍼미션 (Permissions)를 주어야 합니다.
이 퍼미션은 build.settings 파일에서 설정해 줍니다.

-- build.settings
settings =
{
    androidPermissions =
    {
         "android.permission.INTERNET",
    },
}

광고 ( Ads)
광고는 이전에도 잠깐 다룬적이 있습니다.
현재 코로나는 inMobi 광고만 공식적으로 지원하고 있습니다.
그리고 광고는 시뮬레이터에서 지원을 안하기 때문에 빌드하고 디바이스에 인스톨 한 다음에 테스트 하셔야 됩니다.

아래 샘플 코드를 보시면요.

local ads = require "ads"
 
-- Example for inmobi:
ads.init( "inmobi", "12345abc6789defghijk123" )
 
-- iPhone, iPod touch, iPad
ads.show( "banner320x48", { x=0, y=100, interval=5, testMode=false } )
ads.show( "banner300x250", { x=0, y=100, interval=5, testMode=false } )
 
-- The following are iPad only
ads.show( "banner728x90", { x=0, y=100, interval=5, testMode=false } )
ads.show( "banner468x60", { x=0, y=100, interval=5, testMode=false } )
ads.show( "banner120x600", { x=0, y=100, interval=5, testMode=false } )

처음에 ads를 require합니다.
그리고 ads.init을 불러와서 광고서비스 이름과, App ID 를 세팅하고
ads.show로 적당한 위치에 제공되어지는 배너 크기를 정해 넣습니다.
광고를 보이지 않게 하기 위해선 ads.hide()를 사용합니다.

이 때 테스트를 하시려면요.
App ID 에 4028cb962895efc50128fc99d4b7025b 를 넣으시구요.
testMode=true 로 하세요.

그리고 직접 등록해서 사용하시려면 www.inmobi.com 으로 가셔서 등록하신 후 사용하시구요.

아래는 제 안드로이드 앱인 Spin the bottle 1 Lite 를 코로나로 iPhone 버전으로 만든겁니다.

이 화면은 ads.show() 를 이용해서 banner320x48 를 맨 위에 위치 시킨 겁니다.

이 화면은 ads.show()를 이용해서 banner320x48 를 맨 아래에 위치 시킨 겁니다.

이 화면은 ads.show()를 이용해서 banner300x250 를 적당한 위치에 놓은 겁니다.

지금 아직 앱스토어에서 Waiting for Review 상태라서 앱 URL을 inMobi 에 등록 시키지 못했습니다.
아마 앱이 앱스토어에 오픈 되고 이 URL이 확인 된 다음에 광고를 보내 주나 봅니다.

저희 회사에서 테스트할 수 있는 디바이스가 iPod Touch뿐이라서요. 다른건 테스트를 못 해봤습니다. (테스트 디바이스 지원이 너무 열악해요. 우리 회사... ;;)

iPod Touch 에서는 화면이 뜬 다음에 아직 광고가 나오지 않은 상태에서 다른 화면으로 넘어가면 에러가 나오면서 앱이 강제종료 되더라구요.

이에 iPod Touch에서만 나오는 에러인지 아니면 이런 에러를 방지하는 코딩이 따로 있어야 되는건지는 잘 모르겠어요.

다른 디바이스에서도 테스트를 해 봐야 겠는데....

하옇든 아래 코로나에서 제공하는 Ads관련 샘플 코드를 분석 해 보겠습니다.
혹시 이에 대한 해결책이 있는지 한번 볼까요?

--==================================================================================================
--
-- Abstract: InMobi Ads Sample Project
--
-- This project demonstrates Corona Banner Ads support (from inmobi network).
--
-- IMPORTANT: You must get your own "app ID" from the advertising
-- agency you want to display banner ads for. Further, you must build for device
-- to properly test this sample, because "ads" library is not supported by the
-- Corona Simulator.
--
--   1. Get your app ID (example, from inmobi)
--   2. Modify the code below to use your own app ID
--   3. Build and deploy on device
--
-- The code below demonstrates the different banner ads you can use
-- with the InMobi ad network.
-- Version: 1.0 (July 7, 2011)
-- Version: 1.1 (July 22, 2011) - Added Hide button and changed Next button behavior.
--
-- Sample code is MIT licensed, see http://developer.anscamobile.com/code/license
-- Copyright (C) 2011 ANSCA Inc. All Rights Reserved.
--
--==================================================================================================


--==================================================================================================
-- INITIAL SETTINGS
----------------------------------------------------------------------------------------------------

-- hide the status bar:
display.setStatusBar( display.HiddenStatusBar )

-- Below is the ad network that will be used:

local adNetwork = "inmobi"

-- Replace nil below with your app ID:
-- String; e.g. surrounded by quotes (ex. "abcdefghijklmnop")

local appID = "4028cb962895efc50128fc99d4b7025b"

--==================================================================================================

-- Make Banner Ads features available under "ads" namespace
local ads = require "ads"

-- initialize ad network:
if appID then
    ads.init( adNetwork, appID )
end

-- initial variables
local sysModel = system.getInfo("model")
local sysEnv = system.getInfo("environment")

local bgW, bgH = 320, 480
local currentAdIndex = 1

local adsTable = {
    "banner320x48",
    "banner300x250",
}
if sysModel == "iPad" then
    -- change settings if on iPad. It has 3 additional adUnitTypes it can show.
    bgW, bgH = 768, 1024
    adsTable = {
        "banner320x48",
        "banner300x250",
        "banner728x90",
        "banner468x60",
        "banner120x600"
    }
end

-- localize a widget function
local newButton = require( "widget" ).newButton

-- change settings if on iPad
if sysModel == "iPad" then
    bgW, bgH = 768, 1024
end

-- create a background for the app
local backgroundImg = display.newImageRect( "space.png", bgW, bgH )
backgroundImg:setReferencePoint( display.TopLeftReferencePoint )
backgroundImg.x, backgroundImg.y = 0, 0


if appID then
    -- Shows the banner indexed by variable "currentAdIndex"
    local showIndexedBanner = function()
        print("Showing Banner: " .. adsTable[currentAdIndex])
        local adX, adY = 0, 0
        ads.show( adsTable[currentAdIndex], { x=adX, y=adY, interval=5, testMode=true } )
    end

    -- onRelease event listener for 'nextButton'
    local onNextButtonReleased = function( event )
        currentAdIndex = currentAdIndex + 1
        if (currentAdIndex > #adsTable) then
            currentAdIndex = 1
        end
        showIndexedBanner()
    end

    -- onRelease event listener for 'hideButton'
    local onHideButtonReleased = function( event )
        ads.hide()
    end

    -- if on simulator, make sure onRelease event for buttons are set to nil
    if sysEnv == "simulator" then
        onNextButtonReleased = nil
        onHideButtonReleased = nil
    end

    -- create a next button (to show a different ad unit)
    local nextButton = newButton{
        default="button.png",
        over="button_over.png",
        label = "Show Next Banner",
        onRelease= onNextButtonReleased
    }
    nextButton:setReferencePoint( display.CenterReferencePoint )
    nextButton.x = display.contentWidth * 0.5
    nextButton.y = display.contentHeight - 120

    -- create a hide button
    local hideButton = newButton{
        default="button.png",
        over="button_over.png",
        label = "Hide Banner",
        onRelease= onHideButtonReleased
    }
    hideButton:setReferencePoint( display.CenterReferencePoint )
    hideButton.x = display.contentWidth * 0.5
    hideButton.y = display.contentHeight - 60

    -- if on simulator, let user know they must build for device
    if sysEnv == "simulator" then
       
        local font, size = "Helvetica-Bold", 22
       
        local warningText1 = display.newText( "Please build for device ", 0, 135, font, size )
        local warningText2 = display.newText( "to test this sample code.", 0, 165, font, size )
       
        warningText1:setTextColor( 255, 255, 255, 255 )
        warningText2:setTextColor( 255, 255, 255, 255 )
       
        warningText1:setReferencePoint( display.CenterReferencePoint )
        warningText2:setReferencePoint( display.CenterReferencePoint )
       
        local halfW = display.contentWidth * 0.5
        warningText1.x, warningText2.x = halfW, halfW
       
        -- make buttons appear disabled
        nextButton.view.alpha = 0
        hideButton.view.alpha = 0
    else
        -- display initial banner ad
        showIndexedBanner()
    end
else
    -- If no appId is set, show a message on the screen
    local font, size = "Helvetica-Bold", 22

    local warningText1 = display.newText( "No appID has been set.", 0, 105, font, size )
    warningText1:setTextColor( 255, 255, 255, 255 )
    warningText1:setReferencePoint( display.CenterReferencePoint )

    local halfW = display.contentWidth * 0.5
    warningText1.x = halfW

    if sysEnv == "simulator" then
        local warningText2 = display.newText( "Please build for device ", 0, 185, font, size )
        local warningText3 = display.newText( "to test this sample code.", 0, 215, font, size )
        warningText2:setTextColor( 255, 255, 255, 255 )
        warningText3:setTextColor( 255, 255, 255, 255 )

        warningText2:setReferencePoint( display.CenterReferencePoint )
        warningText3:setReferencePoint( display.CenterReferencePoint )
        warningText2.x, warningText3.x = halfW, halfW
    end
end

이 샘플 코드는 Show Next Banner를 누르면 해당 디바이스에서 보일 수 있는 배너 크기별 광고를 차례대로 보여줍니다.
그리고 Hide Banner를 누르면 이 배너를 감춥니다.

코드를 라인별로 분석해 볼까요?
(아래 압축파일에 원본소스와 이미지 등이 있습니다.)



우선 주석은 다 지나가고 34번째 줄부터 시작합니다. 이 줄은 아이폰의 statusBar를 없애는 부분입니다.
39번째 줄에 adNetwork라는 변수에 inmobi라는 값을 담았습니다.
그리고 appID에 inmobi에서 받은 값을 넣어야 하는데요. 위 소스는 nil로 돼 있어서 저는 테스트용 id를 넣었습니다. "4028cb962895efc50128fc99d4b7025b"

그 다음 49번째 줄에서 ads를 require 했고 다음 줄(52)에서 appID가 nil이 아니면 ads.init을 해 줍니다.

그리고 sysModel에 디바이스의 모델을 그리고 sysEnv에 디바이스의 environment를 담습니다.

61번째 줄을 보면 bgW,bgH를 아이폰 해상도에 맞게 320,480 으로 정합니다.
다음줄에 currentAdIndex 에 1을 대입합니다.

다음 adsTable이라는 테이블에 아이폰에서 가능한 배너크기 두가지를 넣습니다.
그리고 sysModel이 iPad 이면 bgW,bgH에 768,1024 를 대입하고 adsTable에는 5종류의 배너크기 모두를 대입합니다.

82번째 줄은 newButton을 wedget의 버튼으로 선언합니다.

85~88번째 줄은 iPad일 경우 bgW,bgH를 바꿔 주는 부분인데요. 70번째 줄에서 이미 한 작업인데 여기서 또 하네요. 이건 없애도 되겠습니다.

다음 92~94째줄은 backgroundImg를 세팅해 주는 부분입니다.

이제 다음부터 어떤 로직이 나오나 봅니다. (저도 지금 이거 처음 보면서 작성하는 거라서 뭐가 나올지 모릅니다.)

appID가 있으면  local showIndexedBanner 함수를 선언하는데요. adX,adY를 0,0으로 하고 ads.show()를 통해서 광고를 보여줍니다.

그 다음 onNextButtonReleased 함수가 있는데 파라미터로 event를 받는 거로 봐서 어떤 리스너에서 호출할 건가 봅니다.
여기서는 currentAdIndex에 1을 더해주고 adsTable의 요소보다 커지게 되면 다시 currentAdIndex를 1로 해주는 로직이 있구요.
이 작업이 끝나면 showIndexedBanner()를 호출합니다.

그러니까 어떤 버튼이 클릭되면 currentAdIndex를 바꿔서 showIndexedBanner()함수를 호출하니까 adsTable에 있는 배너 종류가 차례대로 보이겠네요.

그 다음 117번째 줄은 onHideButtonReleased 함수가 있는데 이것도 event 파라미터가 있는 걸로 봐서 리스너에서 호출 할 겁니다.
당연히 hide ads버튼에서 호출하겠죠?
이 함수가 호출되면 ads.hide()를 실행 시켜서 광고를 없앱니다.

그 다음 123번째 줄은 sysEnv가 시뮬레이터면 onNextButtonReleased와 onHideButtonReleased 함수를 모두 없앱니다.

130번째 줄 nextButton 에는 default button image와 over시 버튼 이미지를 정해주고 글자를 Show Next Banner라고 정해 줍니다. onRelease 에는 onNextButtonReleased를 대입해 줍니다.
그리고 그 위치를 정해 주고요.
142번째 줄에서는 hideButton을 선언해주고 위치를 정해 줍니다.

154번째 줄에서는 sysEnv가 시뮬레이터 이면 warningText1,warningText2를 뿌려줍니다.
그리고 두개의 버튼에 투명도를 주어서 안 보이도록 합니다.
시뮬레이터가 아니면 showIndexedBanner()를 실행 시켜서 광고를 보여줍니다.
버튼에 투명도 처리하는 부분도 적용 안 되니까 이 경우엔 버튼도 보이겠죠?

177번째 줄은 저 위에 있는 if문하고 연결 됩니다 뭐냐하면 97번째 줄의 if appID then 요.

만약 appID가 없다면 97번째 이후에 있던 코드는 다 실행하지 않고 181번째 줄에 있는 warningText1을 화면에 표시합니다.
그리고 시뮬레이터 이면 warningText2,warningText3를 출력합니다.

여기까지가 이 소스코드를 모두 분석한 내용입니다.

제가 iPod Touch에서 겪었던 에러 (화면 뜨고 광고가 뜨기 전에 화면이동-director.lua- 할 경우 생기는) 를 해결 할 수 있는 부분은 없네요.

아직 코로나에서 미처 대응하지 못했던 에러가 아닌가 합니다.
iPhone이나 그 이후 버전의 phone이나 iPad에서는 이러한 현상이 일어나는지 어떤지 잘 모르겠습니다.

이거 회사 테스트 디바이스 지원이 너무 열악해요...

하여간 오늘은 간단히 소켓통신에 대해 알아봤구요.
그리고 코로나에서의 광고 띄우기 (inMobi) 에 대해 자세히 알아봤습니다.

다음엔 네트워킹과 web service에 대해 마저 알아볼 건데요.
요즘 제가 관심 가지고 있는 In-App Purchases 에 대해서도 있네요.

시간이 허락되면 여기까지 다 공부 하겠습니다.

반응형