Development
- #iOS #AppStore 통계 분석 사이트. 2011.10.13
- #Bash find + xargs 에 공백 문자가 있는 경우. 2011.10.12
- #iOS Local Notification Programming 2011.10.12
- #iOS NSURL to NSString 로 변환하기. 2011.10.11
- #OSX #TWUI twui 를 사용하다가 View가 깨지는 경우. 2011.10.11
- #OSX #TWUI의 구조 분석. - TUINSView 와 TUIView 2011.10.11
- #OSX twui 를 소개 합니다. 2011.10.10
- #iOS TouchXML 에서 xml node attribute 구하기. 2011.10.07
- #iOS Unit Test Target이 Original Target의 소스를 못찾는 문제 2011.10.06
- #OSX LSUIElement=1 인 application 에서 Window시작시 Focus를 받지 못하는 문제. 2011.10.05
#iOS #AppStore 통계 분석 사이트.
#Bash find + xargs 에 공백 문자가 있는 경우.
find ./ -name "Thumbs*" -print0 | xargs -0 ls
-print 0 on "find"
"It prints the pathname of the current file to standard output, followed by an ASCII NUL character"
-0 on "xargs"
"Change xargs to expect NUL (``\0'') characters as separators, instead of spaces and newlines.
This is expected to be used in concert with the -print0 function in find(1)."
xargs 와 find 를 조합하라고, -0 와 -print0 를 조합해서 사용하라고, man page에 소상히 적어 두었군요 :)
#iOS Local Notification Programming
예제 이미지 - "Local and Push Notification Programming Guide" 문서에서 발췌
Local Notification 이 무엇인가 ?
Local Notification 이전에, Push Notification 이라는 기능이 있었습니다.
개발사의 서버로부터 Apple Server 로 Notification을 발송하면, Apple Server 에서 iPhone 으로 Notification 을 "Push" 해주는 기능입니다.
Push Notification이 개발사마다 서버를 갖추어야 하고, 이래저래 세팅할것도 많습니다.
정말 필요한 경우가 아니라면 ( 예 : 카카오톡, 마이피플 ) Push Notification을 지원하는 일은 쉬운일이 아닙니다.
서버비용도 발생하고요,
그에 대안(!?) 으로 Local Notification 이라는 기능을 iOS 4.0 부터 지원하기 시작했습니다.
iPhone 내부에서, Notification 을 Scheduling 해주면, Apple Push Server의 도움 없이, Notification Alert을 발생시킬수가 있습니다.
Alram App 같은 것을 만들때 유용하게 사용할 수 있을것 같습니다 ^^
Local Notification이 없던 시절에는 반쪽짜리 Alarm App ( 항상 앱을 켜두어야 하는 ) 밖에 개발할 수 없었지요.
Local Notification Scheduling 하기.
1. UILocalNotification Object를 생성합니다.
2. fireDate설정
3. 필요하다면 아래의 Property 를 세팅해줍니다.
// alerts @property(nonatomic,copy) NSString *alertBody; // defaults to nil. pass a string or localized string key to show an alert @property(nonatomic) BOOL hasAction; // defaults to YES. pass NO to hide launching button/slider @property(nonatomic,copy) NSString *alertAction; // used in UIAlert button or 'slide to unlock...' slider in place of unlock @property(nonatomic,copy) NSString *alertLaunchImage; // used as the launch image (UILaunchImageFile) when launch button is tapped // sound @property(nonatomic,copy) NSString *soundName; // name of resource in app's bundle to play or UILocalNotificationDefaultSoundName // badge @property(nonatomic) NSInteger applicationIconBadgeNumber; // 0 means no change. defaults to 0
4. UIApplication 의 Local Notifiactoin Method들을 통해 scheduling을 합니다.
@interface UIApplication (UILocalNotifications) - (void)presentLocalNotificationNow:(UILocalNotification *)notification __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0); - (void)scheduleLocalNotification:(UILocalNotification *)notification __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0); // copies notification - (void)cancelLocalNotification:(UILocalNotification *)notification __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0); - (void)cancelAllLocalNotifications __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0); @property(nonatomic,copy) NSArray *scheduledLocalNotifications __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0); // setter added in iOS 4.2 @end
Sample Code
- (IBAction) pressPushNow:(id)sender { UILocalNotification *localNotif = [[UILocalNotification alloc] init]; localNotif.fireDate = [[NSDate date] addTimeInterval:10]; localNotif.timeZone = [NSTimeZone defaultTimeZone]; localNotif.alertBody = @"AlertBody"; localNotif.alertAction = @"AlertAction"; localNotif.soundName = UILocalNotificationDefaultSoundName; localNotif.applicationIconBadgeNumber = 1; [[UIApplication sharedApplication] scheduleLocalNotification:localNotif]; [localNotif release]; }
Sample Screen Shot
자~~알 나옵니다 :)
#iOS NSURL to NSString 로 변환하기.
- (NSString *)absoluteString;
- (NSString *)relativeString; // The relative portion of a URL. If baseURL is nil, or if the receiver is itself absolute, this is the
NSURL 에는 absoluteString/ relativeString 이라는 Method가 있습니다.
http:// 로 시작하는 web url 의 경우 absoulteSting을 사용하면 됩니다.
but, iOS 혹은 OSX 내의 File Path 인 경우에는 absoulteString method를 사용하면,,
file://localhost/Users/
우와 같이 이상한 Path 가 나타나서, NSFileManager등에서 Path를 제대로 인식하지 못합니다.
- (BOOL)isFileURL; // Whether the scheme is file:; if [myURL isFileURL] is YES, then [myURL path] is suitable for input into NSFileManager or NSPathUtilities.
NSURL 의 isFileURL 이라는 method에 FileURL 인 경우는 -(void) path 를 사용하라고 주석이 달려 있습니다.
Apple 이놈들... 이런건 absoulteString에 주석이 달려 있었어도 좋았을텐데 말이죠.. ㅎㅎ
#OSX #TWUI twui 를 사용하다가 View가 깨지는 경우.
TWUI를 활용하여 작업하고 있는데,
위와 같이 View가 깨지는 상황이 발생했습니다.
해결하고 보니, 참 우습군요 ;ㅂ;
TUITableView 를 사용하고 있는데,
TUITableView에서 Row Count 가 0 인경우 즉 아무것도 그리지 않는 경우에 위와 같은 현상이 발생하였습니다.
그래서
tableView.backgroundColor = [TUIColor colorWithWhite:0.9 alpha:1.0];
BackgroundColor를 지정해주고 나니, BOOM!
잘 나옵니다.
TWUI Framework의 view들은 default로 아무것도 그리지 않기에,
view hierachy 상에 아무것도 그리지 않는 곳이 생긴다면 위와같이 View가 깨져버리는 현상이 나타납니다. -_-
혹시 사용하시는 분이 있다면 삽질 하지 마시길 바랍니다 :)
#OSX #TWUI의 구조 분석. - TUINSView 와 TUIView
일전에 소개 해드린 TWUI를 살짝 분석한걸 얘기해볼까 합니다.
http://taehoonkoo.tistory.com/190
아래 코드는 TWUI Sample에서 긁어온 소스입니다.
TUINSView *tuiTableViewContainer = [[TUINSView alloc] initWithFrame:b];
[tableViewWindow setContentView:tuiTableViewContainer];
[tuiTableViewContainer release];
ExampleView *tableExample = [[ExampleView alloc] initWithFrame:b];
tuiTableViewContainer.rootView = tableExample;
[tableExample release];
현재 TUINSView와 ExampleView Class 의 Object를 생성하고 있는데,
여기서 ExampleView 는 TUIView 의 sub Class 입니다.
그럼 말하고자 하는 TUINSView 와 TUIView 의 object들인 셈이죠.
결론 부터 말하고 넘어가면, TUIView는 NSView의 sub class 가 아닙니다.
NSResponder의 SubClass 입니다.
이말인 즉슨, NSView에 바로 addSubView해서 사용할수 없는것이죠.
그래서 TUINSView라는 녀석이 있고, 이녀석이 Container역할을 해서
NSView와 TUIView 를 연결 시켜 주게 됩니다.
구현체를 좀더 살펴보니,
TUIView 가 가지고 있는 CALayer Object를 TUINSView의 layer에 addSubLayer하는 형식으로 되어 있습니다.
iOS 스타의 Animation을 구현하기 위해서, NSView자체보다 CALayer를 사용한 것같은데..
직관성이 상당히 떨어 지는 군요.
NSView를 subclassing 하고, 해당 NSView의 CALayer를 활용하는 방식도 가능했을텐데.. 말이지요.
"왜 이런 구조 여야만 했는가? " 에 대한 질문은 아직 깊이있게 살펴보지 않아서,.. ㅎㅎ
좀더 알게 되면 Posting하도록 하겠습니다.
#OSX twui 를 소개 합니다.
twui 는 Twitter 에서 제공하는 Open Source UI Framework 입니다.
Twitter사에서 밝히고 있듯이, iOS Framework 에서 영감을 얻은 즉 iOS Component를 Mac 환경에서 사용할 수 있도록
구현해 놓은 녀석입니다.
위의 예제 이미지를 봐도 UITableView와 매우 흡사합니다.
아직 Code를 자세히 살펴보진 않았지만, Code 목록을 보면..
TUITableView, TUITextField 등 iOS의 UIKit에 있는 녀석들과 비슷 한녀석들이 많습니다.
TUITableViewDelegate Protocol도 UITableViewDelegate Protocol 과 매우 유사합니다.
- (void)tableView:(TUITableView *)tableView willDisplayCell:(TUITableViewCell *)cell forRowAtIndexPath:(TUIFastIndexPath *)indexPath; // called after the cell's frame has been set but before it's added as a subview
- (void)tableView:(TUITableView *)tableView didSelectRowAtIndexPath:(TUIFastIndexPath *)indexPath; // happens on left/right mouse down, key up/down
- (void)tableView:(TUITableView *)tableView didDeselectRowAtIndexPath:(TUIFastIndexPath *)indexPath;
- (void)tableView:(TUITableView *)tableView didClickRowAtIndexPath:(TUIFastIndexPath *)indexPath withEvent:(NSEvent *)event; // happens on left/right mouse up (can look at clickCount)
- (BOOL)tableView:(TUITableView*)tableView shouldSelectRowAtIndexPath:(TUIFastIndexPath*)indexPath forEvent:(NSEvent*)event; // YES, if not implemented
- (NSMenu *)tableView:(TUITableView *)tableView menuForRowAtIndexPath:(TUIFastIndexPath *)indexPath withEvent:(NSEvent *)event;
지금 진행하고 있는 Project에 한번 써볼 요량입니다. ㅎㅎ
자세한 내용은 이래저래 좀 더 만져보고 알려드리겠습니다 :)
# Project Page
https://github.com/twitter/twui
# License
Apache License 2.0 을 따릅니다.
한글 번역 자료 : http://yesarang.tistory.com/272
#iOS TouchXML 에서 xml node attribute 구하기.
http://www.tizag.com/xmlTutorial/xpathattribute.php
에 따르면 @ATTRIBUTE 로 찾으면 된다고 합니다.
그래서 "/problem/contents@type" 으로 찾아 보았으나..
XPath error : Invalid expression
/problem/contents@type
위와 같이 XPath Error 가 뜹니다.. ㅠㅡㅠ
그래서 'content' element를 구하고, 거기서 attribute를 가져오는 방식으로 시도 해보았습니다.
[xmlDoc nodesForXPath:@"/problem/contents" error:&error];
CXMLElement *theNode = [theNodes objectAtIndex:0];
[[[theNode attributeForName:@"type"] stringValue];
이렇게 하니 자~알 되는군요 !
#iOS Unit Test Target이 Original Target의 소스를 못찾는 문제
원래 Unit Test 가 없던 프로젝트에, Unit Test를 집어 넣은 후 undefined symbol error에 봉착했습니다 ;ㅂ;
Test Code에서 사용하고 있는 Real Code를 찾을 수 없는 에러 인데..
위와 같이, Unit Test Target에 App Target이 Dependency 가 걸려 있음에도 불구하고 에러를 내뱉더군요 ;ㅂ;
구글님.. 아니, stackoverflow 님은 역시 모든것을 알고 계시더군요 ㅎㅎ
http://stackoverflow.com/questions/5783294/link-error-while-building-a-unit-test-target
범인은 바로 !!!
이녀석입니다.
이 옵션이 뭐냐하면, compile 된 excutable file 에서 symbol을 찾지 못하게 하는 옵션입니다.
그래서 Unit Test Target에서 symbols not found 에러가 발생한것이지요 ~
Unit Test를 실행시킬 Debug Profile 에서만 No 를 걸어 줍니다.
그러면 에러가 사라집니다 ㅎㅎ
#OSX LSUIElement=1 인 application 에서 Window시작시 Focus를 받지 못하는 문제.
LSUIElement 는 OSX Application Activation Policy 와 관련 있는 옵션입니다.. (.plist 파일에서 설정 )
보통 FaceTab for Facebook 과 같은 Status Bar Item base Application 에서 사용하는 옵션입니다.
해당 옵션을 키면, Dock에 노출되지도 않고, Menu가 노출되지도 않습니다.
NSApp이 NSApplicationActiviationPolicyAccessory로써 동작하게 되는것이죠.
/* The application does not appear in the Dock and does not have a menu bar, but it may be activated programmatically or by clicking on one of its windows. This corresponds to LSUIElement=1 in the Info.plist. */
NSApplicationActivationPolicyAccessory,
주석에 나와 있는데로, User가 click 을 하거나, 소스코드상에서 강제로 Activate 시키지 않으면 실행이 되지 않습니다.
그래서, 환경설정등을 위해 Window를 띄워도 아래와 같이 Deactivate된 상태로 노출되게 됩니다.
이를 해결 하기 위해서 아래의 한줄만 써주면 됩니다.
[NSApp activateIgnoringOtherApps: YES];
OSX 개발 newbie 라... 이런 모드가 있는지도 몰랐고 ;ㅂ;
저 한줄의 코드를 찾기위해, 1시간 가량 구글이랑 놀았습니다. ㅠㅠ