죽은줄 알았던 Textcube가 살아서 돌아왔다

2009/12/24 at 6:47 PM Filed in:일상 No Comments

죽은줄만 알고 있었던 Textcube가 1.8 버전으로 돌아왔다

 

업그레이드 도중에 오류나서 소스를 까보게 됬는데 1.7대랑 정말 많이 바뀌었다.

 

사용중인 스킨이랑 한창 작업하다가 말았던 xquared 위지윅도 별 문제 없이 잘 돌아간다.

 

Textcube가 더이상 개발 안될거 같아서 크리스마스때는 wordpress로 이전해야지 하고 생각하고 있었는데

 

마침 나와서 좀더 써봐야겠구나.

 

개발자들 고생 많이 하셨어요.

 

 

 

XCode SCM Screencast

2009/12/01 at 3:09 PM Filed in:개발 No Comments

 

 

팀내 스터디에 사용.

 

SCM 사용해보기 (구글코드이용)

Subversion xcode 빌드 파일 무시 screencast

2009/12/01 at 3:07 PM Filed in:개발 No Comments

 

 

팀내 스터디하다가 올린 스크린캐슷

Adobe MAX 2009 발표중 Flash / iPhone App Export 지원관련

2009/10/07 at 4:39 AM Filed in:개발 No Comments

http://labs.adobe.com/technologies/flashcs5/appsfor_iphone/

AS3만 지원하고

AS3 Source  =빌드=> iPhone App 은 그렇다 치고 인증과 앱스토어 등록은 어떻게?

일단 App개발을 위해서는 똑같이 Apple Development certification 프로그램 가입되어 있어야하고,

그리고, 플래시 플레이어가 iPhone에 현재 들어가지 못하는 이유도 나와있다.

 

http://labs.adobe.com/technologies/flashcs5/ 를 보면

Flash CS5 에서는 FLA가 XML기반으로 변경되고, 에디터기능향상등이 있다고 한다.

삼각형 밑변 , 높이로 각도 구하기.

2009/09/28 at 8:33 AM Filed in:javascript 1 Comment

삼각형 밑변 높이로 각도 구하는 식

 

atan(밑변 / 높이) * 360 / 2 * 3.14

 

그럼 javascript에서 마우스를 누르고 띄었을때 각도를 구하려면 

 

Math.atan(Math.abs(움직인X값) / Math.abs(움직인Y값)) * 360 / (2 * Math.PI);

 

끗.

 

OSX Trash(휴지통) 파일 안지워지는 문제

2009/09/21 at 7:36 AM Filed in:Computing No Comments

OSX 사용중 (snow leopard) 휴지통에 이런 파일이 계속 남아있는경우가 있다.

option 키를 누르고 삭제해도 삭제가 되지 않고

터미널에서 rm * 으로 삭제 시도해도 되지 않고

ls -i 로 inode를 보려고 해도 no such file… 이라고만 나오고

안전모드로 부팅을 해서 보면 Trashes 디렉토리 가 비어져 있고

싱글모드로 부팅을 해서 보아도 Trashes 디렉토리가 비어져 있고

Disk Utility 에서 Verify 를 해도 소용없다.

사용자 삽입 이미지이것을 고치고자 구글링을 해보았으나 위에 써놓은 방법정도만 주로 나와있었다.

 

원인은 bootcamp 로 윈도 설치한 문제인데

윈도 에서 체크디스크를 한번 하니 사라졌다. <- 해결법

 

 

ActiveX 에서 외부 javascript 호출 꼼수

2009/08/27 at 5:11 AM Filed in:개발 No Comments

 

activeX에서 외부 javascript 호출할때 꼼수로

 

HTMLViewer 가 Explorer 핸들러일때

 

HTMLViewer.Navigate("javascript:layoutHandler();", NULL, NULL, NULL, NULL);

 

간혹 test로 함수호출할때 편함

 

Iphone Application 구동

2009/08/26 at 4:25 PM Filed in:개발 No Comments

iPhone Application 이 구동될때 어떤식으로 view가 뜨는지까지을 한번 찾아보고 정리.

 

main.c 에서UIApplicationMain 메쏘드가 실행되면서 UIApplication 이 실행된다.

UIApplication은 info.plist에 정의된 main xib(nib) 파일 을 참고하여 xib파일의 File’s owner 가 인스턴스화

 

인스턴스화 된 UIApplication 은 지정된 delegate 클래스로 여러가지를 delegate한다.

 

가령

 

applicationDidFinishLauncing 등

 

기본적으로 MainWindow.xib 를 Interface Builder에서 열어 delegate의 참조를 확인해보면 기본적으로 생성된

애플리케이션AppDelegate 클래스 이다.

이 애플리케이션 AppDelegate 클래스로 application에서 발생된 메시지를 보내는 것.

그래서 applicationDidFinishLauncing 에

[[self window] addSubView:새로인스턴스화 된 뷰]

가 subview로 등록되면서 stage가 완성

 

그런 연유로 인하여

소스코드를 통채로 grep 해 보아도

어느눔이 애플리메이션AppDelegate를 하는지는 코드상에 나와 있지 않다.

 

MainWindow.xib 파일은 XML파일인데

<Object class=”코코아클래스” key=”이름”>뭐 이런형식으로 잔뜩채워져 있는데

이 XML파일을 바탕으로 빌드시, 혹은 runtime시(이건 확실하지가 않다) 에 클래스를 생성하는 듯하다.

 

끗.

 

 

iPhone SDK 3.0 XML Parsing with NSXMLParser

2009/08/26 at 3:58 PM Filed in:개발 No Comments

iphone sdk 3.0으로 XML데이터를 파싱하다가 몇가지 사실을 알게됬다

 

iphone sdk 2.x 대로 개발된 XMLParser Class가 있어서 그것을 사용하여 빌드를 해 보려는데

에러발생으로 빌드가 되지 않았다.

 

코드는

파싱 함수코드는

 

- (void)parseContents:(NSURL *)url  {         NSXMLDocument *xmlDoc = [[NSXMLDocument alloc] initWithContentsOfURL:url options:1 << 10 error:nil];         [self parseXMLData:[xmlDoc XMLData]];         [xmlDoc release]; }

 

였는데

NSXMLDocument undeclared … 에러 발생…

SDK API를 찾아보아도 NSXMLDocument Class는 찾을 수 가 없었다.

그런데 빌드를 2.0으로 하면 에러없이 잘 됬다.

 

어쨌든 SDK 3.0으로 개발을 해야되니 일단 에러발생을 없애기 위해서

이런 함수로 파싱을 시작

-(void)parseXMLUrl:(NSURL *)url {    NSXMLParser*p =[NSXMLParser alloc];    [p initWithContentsOfURL:url];    [p setShouldProcessNamespaces:YES];    [p setDelegate:self];    [p parse];    [p release];}

그러나 파싱실패. 이유는 XML데이터가 온전하지 않는 데이터

태그 안에 특수문자가 있어 CDATA로 감싸야 되는 상황

급한대로 

 

NSString*xmlString =[NSString stringWithContentsOfURL:url];NSData*xmlData =[[self shitXMLToGood:xmlString] dataUsingEncoding:NSUTF8StringEncoding];

 

이런식으로 잘못된 데이터를 교정하는 함수를 만들어 얻어온 XMLString을 교정하도록 하였다.

NSData 에 dataUsingEncoding이라는 함수로. NSString 형식을 NSData로 변환 할수 있다 (물론 Charset에 맞게)

NSString 의 stringWithContentsOfURL 은 PHP의 file_get_contents와 같은 놈.

쓰레드로 잡고있는듯 하다. 실행완료후 다음코드 진행, 무엇인가 메시지를 발생시키거나 Delegate 를 지정하여 Delegate Method를 실행시키는 등의 복잡한 방법이 필요없이 편하게 잘된다. (Cocoa의 API인데..)

 

다음은 교정하는 함수

 

-(NSString*) shitXMLToGood:(NSString*)string {    NSString*goodString =[string stringByReplacingOccurrencesOfString:(NSString*)@"</link>" withString:(NSString*)@"]]></link>"];    goodString =[goodString stringByReplacingOccurrencesOfString:(NSString*)@"<link>" withString:(NSString*)@"<link><![CDATA["];    return goodString;}

 

이는 <link></link>안을 CDATA로 감싸는 메쏘드인데

NSString 의 strignByReplacingOccurencesOfString 메쏘드로 replace해버린다

첫번째 파라메터가 target, 두번째 withString이 replace될 String

프로시져 형식의 메쏘드가 아니라 새 String을 리턴한다. NSString을 인스턴스화 해서 해보진 않았다. API상에 그냥 return new … 이렇게 써있어서.

 

 

어찌되었든 이런 특별한 경우가 아닌 경우 – 정확히 작성된 XML을 가져올 경우- 에는 XML파싱을 위해 XML의 구조를 “먼저” 알고 있어야 한다. URL일 경우에는 브라우져로, 파일인 경우에는 읽어서 판단.

왜냐면 NSXMLParser에서 중요한 4개의 메쏘드가 parsing작업을 담당하는데,

이는 트리구조를 직접 만들어 주지 않는다. AS 3.0이나 뭐 여타 라이브러리들의

TREE구조 혹은 Hash Object형식으로 만들어 주지 않는다. 어떻게 해주는지는 밑에 설명

 

NSXMLParser 가 delegate 하는 메쏘드들 중에 가장 중요한 4가지

 

-(void)parser:(NSXMLParser*)parser parseErrorOccurred:(NSError*)parseError-(void)parser:(NSXMLParser*)parser didStartElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qualifiedName attributes:(NSDictionary*)attributeDict-(void)parser:(NSXMLParser*)parser didEndElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qName -(void)parser:(NSXMLParser*)parser foundCharacters:(NSString*)string 

이렇게 네가지

첫번째 parseErrorOccured 는 파싱중 에러발생시에,

두번째 didStartElement는 <>로 감싼 태그를 만날 때

세번째 didEndElement는 </>로 감싼 태그를 만날 때

네번째 foundCharacters 는 didStartElement 와 didEndElement “후” 에 String을 반환한다.

중요한 것은 네번째 foundCharacters인데

이것은 didStartElement 이후, didEndElement 이후에 delegate된다

이것이 무엇이냐

didStartElement 이후 delegate되는 경우에는 파라메터로 엘리먼트안의 데이터가 넘어온다

그러나

didEndElement 이후 delegate되는 경우에는 파라메터로 무언가 (== nil 혹은 == @”" 가 아님.) 넘어오는데

여튼 쓸수 없는 값이다 (\n인가)

그래서 delegate method를 작성할때 많은 예제들에서 사용하는 방식이

xmlValue를 전역 변수 선언해 놓고

didStartElement안에서 xmlValue를 빈 값으로 리셋

xmlValue = @”"; 이런식

그리고 foundCharacters 에서

xmlValue = string 으로 할당

didEndElement에서 xmlValue를 알맞은 곳에 사용

 

하는 형식으로 작성해야 한다. foundCharacters안에 string을 직접 알맞은 곳에 사용하다간 didEndParsing 이후 delegate되는 foundCharacters의 이상한 string값이 잘못 사용되어 지기 때문이다.

이것은 SDK 2.x대의 NSXMLDocument를 사용한 구조에서는 발생하지 않는다고 한다. 2.x에서 NSXMLDocument를 사용한 경우에는 foundCharacters 가 한번만 호출.

뭐 XML데이터가 잘못되어 SDK3.0에서도 한번만 호출되더라도 이런 경우가 발생 할 수 있기 때문에

전역 xmlValue를 update하는 방식으로 XML data를 관리하는것이 낫겟다는 생각이다.

 

그리고

Tree구조가 아니기 때문에

didStartElement에서 elementName으로 얻어오는 tag name을 가지고 판단하여

알맞은 NSMutableDictionary나 array나 뭐 구조체처럼 쓰이는 Class등에 데이터를 migration할수 있겟다.

 

NSMutableDictionary 구조가

people – title

           – name

           – friend – best

                      – worst

뭐 이런식이라면

 

XML데이터가 트리구조로 되어있던 뭔구조로 되어있던간에

tag name이 title이면 didEndParsing 에서 dictionary의 title key값에다가 직접 set을 해줘야된다.

best든 worst 키값이던간에 평면적으로 넘어오는 데이터를 트리구조로 변환해야되는 것.

 

 

이 아니면 어쩌나 길게썻는데 ㅠㅠ.

간단한 canvas 예제

2009/08/25 at 5:18 AM Filed in:javascript No Comments

그림그리기

간단하게

 

FF, Opera, Chrome 만됨

 

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>     <title>SK UI Dev test</title>     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script type="text/javascript"></script>  <script type="text/javascript"> var started = false;window.addEventListener('load', function() {    var canvas, context, stage;    var init = function() {        var stage = document.getElementById('container');        var canvas = document.getElementById('stage');        context = canvas.getContext('2d');        started = false;        canvas.onmousedown = function(ev) {            context.beginPath();            console.log(ev);            context.moveTo(ev.clientX - 8, ev.clientY - 8);            started = true;        };        canvas.onmousemove = function(ev) {            if (started) {                context.lineTo(ev.clientX - 8, ev.clientY - 8);                context.stroke();            }        };        canvas.onmouseup = function(ev) {            if (started) {                started = false;            }        };     };    init();}, false);</script> <style type="text/css"> #stage {    border:1px #DDD solid;}</style>  </head> <body>      <div id="container">         <canvas id="stage" width="800" height="600">         </canvas>     </div> </body> </html>