영삼이의 IT정보2012. 6. 20. 13:17

iOS 5부터 UIAlertView에 alertViewStyle 프라퍼티가 추가되었다. 기존에 약간의 커스텀 작업을 통해 텍스트필드를 추가할 수 있었는데 이제는 간단히 상수를 이용하여 원하는 작업을 좀더 간단히 할 수 있게 되었다. 자 간단히 살펴보자.

1. 기본 스타일

UIAlertView *alertView = [[UIAlertView allocinitWithTitle:@"기본 스타일"

                                                    message:@"기본 스타일의 얼럿 입니다."

                                                   delegate:self

                                          cancelButtonTitle:@"취소"

                                          otherButtonTitles:@"확인"nil];

[alertView show]

 

 
2. 텍스트 입력 스타일

UIAlertView *alertView = [[UIAlertView allocinitWithTitle:@"텍스트 입력 스타일"

                                                    message:@"텍스트 입력 스타일의 얼럿 입니다."

                                                   delegate:self

                                          cancelButtonTitle:@"취소"

                                          otherButtonTitles:@"확인"nil];

alertView.alertViewStyle = UIAlertViewStylePlainTextInput;

[alertView show];


이 경우 텍스트 필드에 입력된 데이터의 접근은 다음과 같이 한다.

UITextField *textField = [alertView textFieldAtIndex:0];

NSLog(@"Plain text input: %@",textField.text);


 3. 압호 입력 스타일

UIAlertView *alertView = [[UIAlertView allocinitWithTitle:@"암호 입력 스타일"

                                                    message:@"암호 입력 스타일의 얼럿 입니다."

                                                   delegate:self

                                          cancelButtonTitle:@"취소"

                                          otherButtonTitles:@"확인"nil];

alertView.alertViewStyle = UIAlertViewStyleSecureTextInput;

[alertView show];


 
4. 로그인(ID)과 비밀번호 입력 스타일

UIAlertView *alertView = [[UIAlertView allocinitWithTitle:@"로그인과 비밀번호 입력 스타일"

                                                    message:@"로그인과 비밀번호를 입력하세요."

                                                   delegate:self

                                          cancelButtonTitle:@"취소"

                                          otherButtonTitles:@"확인"nil];

alertView.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;

[alertView show];


이 경우 텍스트 필드에 입력된 데이터의 접근은 다음과 같이 한다.

UITextField *loginField = [alertView textFieldAtIndex:0];

NSLog(@"Login input: %@",loginField.text);

    

UITextField *passwordField = [alertView textFieldAtIndex:1];

NSLog(@"Password input: %@",passwordField.text);

 


또한, UIAlertViewDelegate에도 alertViewShouldEnableFirstOtherButton: 메서드가 추가 되었다. 이 메서드를 이용하여 다음과 같이 버튼을 동적으로 enabling/desabling 시킬 수 있다.

- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView

{

    UITextField *textField = [alertView textFieldAtIndex:0];

    if ([textField.text length] == 0)

    {

        return NO;

    }

    

    return YES;

}


 



Posted by 다오나무
영삼이의 IT정보2012. 6. 20. 12:36

NSString 레퍼런스를 참고 했을 때,
compare라는 메소드를 사용하면 가능하다고 나와있었는 데 실패했다.

출력하거나 메모리에서 비교하면 똑같은 데이터인데, 틀리다고 나와서..
(주 원인은 포인터값 때문에 그런지 아직도 못찾았다.)

 그래서 다음과 같은 방법도 시도.
NSString *title = @"편집"; 
if ( [title isEqualToString:@"편집"] );
(생략)

근데 역시 실패해서 c언어 스타일로 작성하니까 잘 되었음.


int test = strcmp([tempString UTF8String], [columnName UTF8String]);
   
상황에 따라 case by case 인지 확인을 정확히 해봐야 할 듯.

Posted by 다오나무
영삼이의 IT정보2012. 6. 12. 10:12

기본적으로 Mac OS X에는 Subversion 프로그램이 있다.

1.터미널에서 SVN 서버와 클라이언트 버젼을 확인해 보자

서버 : svnserve --version
클라이언트 svn --version

 




2. 소스 저장할 위치에 대해 폴더를 생성 하고 Repository 생성한다.

svnadmin create [경로]


실행화면


다음과 같이 폴더와 파일이 생성된다.



 3. SVN 로그인 계정 등록
[Repository 폴더]/conf/passwd 파일을 수정한다.


예) 아이디 : zang / 패스워드 : 1234 

 
4. SVN 환경 설정
[Repository 폴더]/conf/svnserve.conf 파일을 수정한다.


익명 사용자 접근 막기 (anon_access = none)
인증 사용자 쓰기 권한 (auth_access = write)
인증 데이터베이스는 passwd 사용 (password-db = passwd)




5. Mac에서 SVN 서버를 자동으로 실행하기 위한 스크립트 파일 만들어야 한다.
[참고] 직접 서버를 실행하는 명령어

svnserve -d --listen-port=3690 -r [Repository경로]


스크립트 파일을 만들어 명령어를 입력한다.



스크립트 파일 저장후 파일 권한 설정해준다.

chmod 755 [스크립트 파일 경로]



6. Mac에서 부팅시 자동으로 스크립트 실행하도록 설정한다.

[시스템 환경설정]-[사용자 및 그룹]-[로그인 항목]에서 하단의 + 버튼을 눌러서 방금전에 생성한 스크립트 파일을 선택하면 된다.




7. 설치된 SVN 서버에 기존 소스를 import 하기 


디렉토리 생성

svn mkdir svn://localhost/trunk
svn mkdir svn://localhost/branches
svn mkdir svn://localhost/tags 


오류가 다음처럼 나오면 export SVN_EDITOR=vi를 처리해준다. 

svn: Could not use external editor to fetch log message; consider setting the $SVN_EDITOR environment variable or using the --message (-m) or --file (-F) options
svn: None of the environment variables SVN_EDITOR, VISUAL or EDITOR is set, and no 'editor-cmd' run-time configuration option was found


export SVN_EDITOR=vi


실행하고 나면 vi창으로 넘어감.. -> esc키 -> :q! -> 엔터 -> c 
왜 이렇게 하는건지는.. 자세히 안봐서 아직 모르겠고 그냥 vi빠져 나가고 continue(C) 눌러주면 폴더 생성


디렉토리 삭제  

svn rm svn://localhost/trunk



프로젝트 Import 

  svn import --no-auto-props --no-ignore -m "test프로젝트 추가" /Volumes/data/workspace/test svn://localhost/trunk/test


--no-auto-props --no-ignore 옵션을 주면 바이너리 파일을 추가 할수 있음.
-m "메시지" SVN 기록 메시지 

 

프로젝트 export

  svn export svn://localhost/trunk/test

'영삼이의 IT정보' 카테고리의 다른 글

mac용 svn시작하기 [출처] mac용 svn시작하기|작성자 seungbeomi  (0) 2012.06.12
mac os x 에 apache module dav_svn 설치하기.  (0) 2012.06.12
Tabbar 아이콘  (0) 2012.06.11
StoreKit  (0) 2012.06.10
iOS 키보드  (0) 2012.06.10
Posted by 다오나무
영삼이의 IT정보2012. 6. 11. 18:14

아이폰(iPhone) 탭바 구현 - (3) (tabBar)에 아이콘과 색깔 넣기

 

개발환경 : Mac OS X 10.6.3, Simulator - 3.1.3

 

글보다는 그림(아이콘이 탭바에 들어가게 되면 보다 명확하게 어떤 기능을 하는

곳을 가리키는지 알려줄수 있어서 좋다하지만 단점이 있다일반 그림이 들어가게

되면 색깔정보(Opaque) 는 무시되고 이미지에 포함된 Alpha(투명색정보로만

표시가 된다그러니까 일반 그림을 넣게되면 형태만 나오게 된다.

테스트를 해보고 싶다면 투명색정보를 집어넣던지 아니면 투명색 정보가 있는

아이콘으로 해보면 될것이다색깔 쪽은 무지한 상태로 일단 넘어가기로 한다.

 

[원본그림]

[표현그림]

들어가는 이미지의 기본크기는 30x30 이다이에 맞지 않는다면 자동으로 확대/축소된다.

 

탭에 이미지를 넣고 싶다면 먼저 Resources 폴더에 쓸만한 아이콘을 집어넣는다.

그리고 MainWindow.xib 를 클릭해 인터페이스 빌더를 띄운다탭을 클릭하지 말고

표나 타이틀을 클릭하게 되면 그 부분만 선택되게 된다그 상태에서 Inspector 창의

Attributes 란을 보게 되면 아래쪽에 Image 라는 란이있다콤보를 클릭해서 보면

Resources 란에 집어넣었던 이미지가 다 나오게 되는데 이중 하나를 선택하면

표시가 되게 된다다른 탭도 마찬가지 과정을 거치면 된다.

3개의 탭에 모두 다른 그림을 집어넣고 실행한 화면이다어째 마음에 안들지만

Alpha 어쩌구 때문에 그렇다는건 알았기 때문에 그걸로 만족해야겠다

'영삼이의 IT정보' 카테고리의 다른 글

mac os x 에 apache module dav_svn 설치하기.  (0) 2012.06.12
맥용 SVN 서버 설치  (0) 2012.06.12
StoreKit  (0) 2012.06.10
iOS 키보드  (0) 2012.06.10
아이폰 OS 개발 자료 총정리  (2) 2012.06.04
Posted by 다오나무
영삼이의 IT정보2012. 6. 10. 17:08

- (void) viewDidLoad 에서

scrollView.contentSize = self.view.frame.size;

선언 이후 화면 변환(키보드 등장)에 대한 노티피케이션 감시 코드 추가

1) viewWillAppear 에서 UIKeyboardDidShowNotification 과 UIKeyboardDidHideNotification 등록

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];


-(void)keyboardDidShow:(NSNotification *)notif 
{
//키보드를 여러 객체들이 열 수 있는데, 자신의 키보드에만 반응하기 위해서, 이 정보를 갖고 있어야 한다
  if(keyboradVisible) 
  { return; }
  NSDictionary* info = [notif userInfo];
  NSValue* aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
  CGSize keyboardSize = [aValue CGRectValue].size;

  CGRect viewFrame = self.view.frame;
  viewFrame.size.height -= keyboardSize.height;

  scrollView.frame = viewFrame;
  keyboardVisible = YES;
}

-(void)keyboardDidhide:(NSNotification *)notif 
{
  if(!keyboardVisible)
  { return; }

  NSDictionary *info = [notif userInfo];
  NSValue *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
  CGSize keyboardSize = [aValue CGRectValue].size;

  CGRect viewFrame = self.view.frame;
  viewFrame.size.height += keyboardSize.height;

  scrollView.frame = viewFrame;
  
  keyboardVisible = NO;
  
}

2) viewWillDisappear 에서 등록 해지

[[NSNotificationCenter defaultCenter
] removeObserver:self]



'영삼이의 IT정보' 카테고리의 다른 글

Tabbar 아이콘  (0) 2012.06.11
StoreKit  (0) 2012.06.10
아이폰 OS 개발 자료 총정리  (2) 2012.06.04
UIImageJPEGRepresentation  (0) 2012.06.04
XHTML/CSS 무료 템플릿 배포사이트  (0) 2012.06.01
Posted by 다오나무
영삼이의 IT정보2012. 6. 4. 13:47

KT앱 대회 준비하면서 모은 자료들을 정리해서 올립니다.
거의 맥부기 카페 자료들이 대부분인데 한곳에 모아서 찾아보기 쉬우라고 올려봅니다.


-푸쉬  서버  개발  관련 자료-
이지 APNS 오픈 소스 라이브러리
http://www.easyapns.com/
구글 코드 APNS 오픈 소스
http://code.google.com/p/apns-php/
서버 튜토리얼
http://blog.boxedice.com/2009/07/10/how-to-build-an-apple-push-notification-provider-server-tutorial/


-label이나 textView에 현재 시간을 표시하고 싶습니다-
NSDate *t = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
NSString *timeStr = [formatter setDateFormat:@"HH:mm:ss"];
myLabel.text = timeStr;
...
[textView scrollRangeToVisible:NSMakeRange([textView.text length]-1, 1)];


-시뮬레이터 포토 라이브러리 자신의 이미지 추가 방법-
UIImage * sShot = [UIImage imageNamed:@"imageName.jpg"];
UIImageWriteToSavedPhotosAlbum(sShot, nil, nil, nil);


-네이게이션바 스타일 바꾸기-
http://cafe.naver.com/mcbugi/1241


-이미지 자르기 함수를 소개합니다. (UIImage)-

- (UIImage*)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)rect
{
CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);
UIImage *cropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return cropped;
}
http://www.hive05.com/2008/11/crop-an-image-using-the-iphone-sdk/


-HTTP 라이브러리-
http://allseeing-i.com/ASIHTTPRequest/How-to-use


-json 관련-
라이브러리 http://code.google.com/p/json-framework/
json 투토리얼 http://iphonedevelopertips.com/networking/iphone-json-flickr-tutorial-part-1.html


-알럿 템플렛-
self.myAlertView = [ [UIAlertViewalloc]
initWithTitle:@"알림"
message:@"이메일을입력해주세요"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:@"확인", nil];
self.myAlertView.delegate = self;
[self.myAlertViewshow];


-푸쉬서버 구현을 위한 서버 인증서 pem 만들기-
애플 개발자 센터 apps ID 추가 (이때 와일드카드(*)는 사용하면 안됨)

키체인에서 개인 인증서 하나 만들어 애플 개발 센터에 등록

애플 개발센터에서 cert파일을 다운받아서 키체인으로 추가

키체인에서 내보내기로 p12파일로 저장

커맨드에서  p12파일을 pem파일로 변환
openssl pkcs12 -in quizers_dev_cert.p12 -out quizers_dev_cert.pem -nodes -clcerts


-전역변수를 사용해 보자...-
http://cafe.naver.com/mcbugi/55643


-JSON 2중 뎁스 이상 키 접근하기-
NSDictionary*feed =[self downloadPublicJaikuFeed];
// get the array of "stream" from the feed and cast to NSArrayNSArray*streams =(NSArray*)[feed valueForKey:@"stream"];
// loop over all the stream objects and print their titlesint ndx;
NSDictionary*stream;
for(ndx =0; ndx < stream.count; ndx++){
        NSDictionary*stream =(NSDictionary*)[streams objectAtIndex:ndx];
        NSLog(@"This is the title of a stream: %@", [stream valueForKey:@"title"]); 
}


-배열 NSArray-
초기 데이터로 생성
NSArray *array = [[NSArray alloc] initWithobjects:추가할 객체들.. , nil];
 스트링으로 생성
NSArray *joins =(NSArray*)[result objectForKey:@"joins"];
길이 구하기
NSLog(@"Array size : %d " , sizeof(BUILDING_DATA) / sizeof(BUILDING_DATA[0]));


-NSString 클래스를 이용하여 문자을 넣자니 유니코드를 받아 초기화-
-(NSUInteger) UnicharLength:(const unichar*)str
{
unichar* pStr = (unichar*)str;
for( ; pStr[0] != nil ; pStr++ );
return (NSUInteger)(pStr - str);
}
[[NSString alloc] initWithCharacters:(원본문자열) length:[self UnicharLength:(원본문자열)]];


-랜덤 출력-
srandom(time(NULL));
value = random() % 100;
위처럼 하시면 0~99사이의 한수를 리턴합니다.
srandom(time(NULL)); 는 첨에 한번만 해주시면 됩니다.


-Code Sign error: Provisioning profile이 맞지 않을 때 변경 방법-
여러 장비에서 작업을 하거나 여러 프로젝트를 진행 중에 변경된 Provisioning profile이 적용되지 않아 Debug를 할 때 ”Code Sign error: Provisioning profile ‘3E6AA725-6534-46F8-B9CE-D19AC9FD854B’ can’t be found” 이런 오류가 발생하는 경우가 있는데요. 이럴 때 현재 사용중인 Provisioning Profiles로 프로젝트 세팅을 변경해주는 방법을 소개한 글(원문)이 있어서 공유합니다.

1. 실행중인 Xcode Project를 닫습니다.
2. Finder에서 프로젝트 폴더로 이동합니다.
3. 프로젝트 .xcodeproj 파일 선택하고 마우스 오르쪽 키를 눌러 '패키지 내용 보기'를 선택합니다.
4. 패키지 내용 보기를 통해 패키지 안에 있는 project.pbxproj 파일을 Xcode로 불러옵니다.
5. 검색을 통해 PROVISIONING_PROFILE 부분을 찾아 변경된 Provisioning profile 로 변경해줍니다.
6. 현재 Provisioning profile을 확인하려면 Organizer 창을 열어보면 알 수 있습니다.
7. Window > Organizer로 Organizer 창을 열고 왼쪽에 IPHONE DEVELOPMENT > Provisioning Profiles로 이동합니다.
8. 오른쪽에 있는 Profile Identifier를 복사해서 변경해주면됩니다.
9. 변경이 끝나면 project.pbxproj 저장하고 프로젝트를 열어 테스트합니다.


-아이폰 웹개발에서 디바이스 아이디 가져올수있나요?-
[[UIDevice currentDevice] uniqueIdentifier];



-Accessing Objects in a NSArray-
To access an object in an NSArray, you use the -objectAtIndex: method, as in the following example:NSArray *numbers;
NSString *string;

numbers = [NSArray arrayWithObjects: @"One", @"Two", @"Three", 
                                     nil];
string = [numbers objectAtIndex: 2];   // @"Three"

Of course, you have to be careful not to ask for an object at an index which is negative or bigger than the size of the array; if you do, an NSRangeException is raised (we'll learn more about exceptions in another tutorial).
To get the length of an array, you use the method -count, as in:
NSArray *numbers;
int i;

numbers = [NSArray arrayWithObjects: @"One", @"Two", @"Three", 
                                     nil];
i = [numbers count];   // 3


-상태바 제어-
안 보이게
[UIApplication sharedApplication].statusBarHidden = NO;

스타일
UIApplication *myApp = [UIApplication sharedApplication];
[myApp setStatusBarStyle:UIStatusBarStyleBlackOpaque];


-메모리 오버되어서 어플이 죽는 경우에 호출되는 이벤트??-

뷰컨트롤러 베이스로 작업을 한다면

- (void)didReceiveMemoryWarning

함수로 메모리가 위험할시에 위 함수를 핸들링하니 내부에 관련 대응할 처리를 구현해주면 됩니다.



-D-Day 구하기-
NSDate* date  = [NSDatedateWithNaturalLanguageString:@"2010-06-30"];
NSDate* d_day = [NSDatedateWithNaturalLanguageString:@"2010-12-31"];

NSDateComponents *dcom = [[NSCalendar currentCalendar]components: NSDayCalendarUnit
fromDate:date  
  toDate:d_day  
  options:0];

NSLog(@"day=%d",   [dcom day]);   // 184


-라디오 버튼이나 체크박스등을 찾지를 못하고  있는데-
Interface Builder 에서 library를 보시면 segmented control, switch가 보일겁니다.
말씀하시는 라디오버튼이나 체크박스는 없지만  
라디오버튼은 segmented control로 대체, 체크박스는 switch 로 대체하셔서 사용하시면 될듯합니다.


-책장 넘기기 효과-
UIView 를 하나 만들고 그 안에 UIImageView 를 만들었습니다.
이제 이미지뷰어의 내용을 채울때 책장을 넘기듯이 넘기는 방법입니다.

[UIView baginAnimations:@"stalker" context:nil]; <- stalker 는 UIView 의 이름입니다
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:stalker cache:YES];
[UIView setAnimationDuration:1.0];
imageView.image = [UIImage imageNAmed:이미지파일명];
[UIView commitAnimations];

이 걸 터치 이벤트나 이런곳에 삽입하면
책장을 넘기듯이 이미지의 전환이 일어납니다. 


-image를 fade out 효과-
[UIView beginAnimations:nil context:NULL];
[imageView setAlpha:0.0];
[UIView commitAnimations]; 


-UIView Animation 중복방지-
[UIView beginAnimations:nil context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveLinear]; 
....
[UIView setAnimationDelegate:self]; 
[UIView setAnimationDidStopSelector:@selector(animationFinished:finished:context:)];
        [UIView commitAnimations];

이런 식으로 에니메이션을 만들었는데 간단하게 UIImageView를 한점에서 다른 한점으로 이동시킵니다.
근데 그래서 에니매이션이 끝나면 다시 또다른 다른 두 좌표로 해서 위의 코드가 실행되서 계속해서 UIImageView를 움직이게 하고 있습니다.

근데 질문은 1. setAnimationDidStopSelector 에서 에니매이션이 끝난것을 알기전에 강제로 에니메이션을 멈출수 있나요?
2. 제 경우에는 어떤 경우에 위 코드가 setAnimationDidStopSelector 가 호출되었을때 만 실행되는 것이 아니라 다른 부분에서도 호출하기도 합니다.  근데 문제는 동시에 위 코드가 중복되어서 호출되면 이상하게 작동해요.  그래서 꼭 위 코드를 실행(에니매이션을 commit 하기전에는 반드시 에니메이션을 강제로 멈추던지 아니면 다른 체크를 해야 할것 같은데.....  

혹시 방법이 있으면 부탁드립니다.

꾸벅~

답글 : 
[UIView setAnimationsEnabled:NO];
// 에니메이션을 종료 합니다. 


-일정시간 딜레이 후 함수 호출-
[self performSelector:@selector(playerStop) withObject:nil afterDelay :1.0f];

-(void) playerStop 
{
}


-개발 완료, 베타 테스팅용 Ad Hoc 배포-
http://cafe.naver.com/mcbugi/9042


-테이블뷰에 원격이미지를 넣을경우 스크롤이 느려지는 현상-
LazyTableImages 샘플 http://developer.apple.com/iphone/library/samplecode/LazyTableImages/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009394
AsyncImageView 클래스 http://www.markj.net/iphone-asynchronous-table-image/


-테이블 뷰 섹션별로 이름 주기-
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if( section == 0 ) {
return@"발행한퀴즈";
} elseif( section == 1 ) {
return@"참여한퀴즈";
} else {
return@"진행중인퀴즈";
}
}


-정사각형으로 사진을 CROP 하고, 썸네일 크기에 맞게 리사이즈-
먼저, 출처는 다음 기사입니다.
http://tharindufit.wordpress.com/2010/04/19/how-to-create-iphone-photos-like-thumbs-in-an-iphone-app/ 
 
iPhone 사진앨범의 특징은 가로나 세로가 긴 이미지라 할지라도,
정사각형으로 사진을 CROP 하고, 썸네일 크기에 맞게 리사이즈 시킵니다.
 
위의 기사의 내용을 나름대로 보기 편하게(?) 수정을 했습니다.
 
함수명 - makeThumbnailImage
파라미터 - 원본 이미지, 리사이즈없이 CROP만 할지 여부, 리사이즈할 정사각형 한변의 길이
리턴값 - CROP 및 리사이즈된 이미지
 
- (UIImage*) makeThumbnailImage:(UIImage*)image onlyCrop:(BOOL)bOnlyCrop Size:(float)size
{
 CGRect rcCrop;
 if (image.size.width == image.size.height)
 {
  rcCrop = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
 }
 else if (image.size.width > image.size.height)
 {
  int xGap = (image.size.width - image.size.height)/2;
  rcCrop = CGRectMake(xGap, 0.0, image.size.height, image.size.height);
 }
 else
 {
  int yGap = (image.size.height - image.size.width)/2;
  rcCrop = CGRectMake(0.0, yGap, image.size.width, image.size.width);
 }
 
 CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], rcCrop);
 UIImage* cropImage = [UIImage imageWithCGImage:imageRef];
 CGImageRelease(imageRef);
 if (bOnlyCrop) return cropImage;
 
 NSData* dataCrop = UIImagePNGRepresentation(cropImage);
 UIImage* imgResize = [[UIImage alloc] initWithData:dataCrop];
 
 UIGraphicsBeginImageContext(CGSizeMake(size,size));
 [imgResize drawInRect:CGRectMake(0.0f, 0.0f, size, size)];
 UIImage* imgThumb = UIGraphicsGetImageFromCurrentImageContext();
 UIGraphicsEndImageContext();
 [imgResize release];
 return imgThumb;
}

위 소스를 참고하시면, 이미지를 CROP 하는 방법이나, 이미지를 RESIZE 하는 방법을 참고하실수 있을겁니다.
 
사족을 붙이자면, 왜 Resize 할지 여부를 따로 분리 시킨 이유는 실제로 사용을 해보면 Resize 루틴에서
많은 CPU 부하가 걸립니다. 그래서 UIImageView 에  contentMode를 UIViewContentModeScaleAspectFit 로 설정해서
자체적으로 리사이즈를 하게 하는 방법이 비동기적으로 괜찮습니다. (물론.. 실제 Resize된 이미지가 아니므로 메모리적인 소비는 있습니다.)
 
많은 도움 되셨으면 좋겠네요 ^^


-사진찍을때  아래에서  올라오는  메뉴 UIActionSheet-
http://ykyuen.wordpress.com/2010/04/14/iphone-uiactionsheet-example/


-uibutton disable-
http://www.iphonedevsdk.com/forum/iphone-sdk-development/2499-uibutton-disable.html


-이미지  슬라이드  샘플-
http://lievendekeyser.net/index.php?module=messagebox&action=message&msg_id=1351


-커버플로우  라이브러리-
http://apparentlogic.com/openflow/


-Xcode3.2.3과 SDK4로 업그레이드 후, 기존 앱 업그레이드 하는 법-
XCode3.2.3 과 SDK4로 버전업한 후, 기존 앱을 업그레이드 할 때 간단한 Tip 입니다.
1. XCode3.2.3과 SDK4로 업그레이드 한다. 별도로 기존 XCode 3.1 버전을 따로 보관할 필요가 없습니다.
2. 기존 앱을 새 XCode3.2.3에서 연다.
3.Group & Files를 right click -> Get Info 후
  3-1.General Tab 에서
Project Format 을 Xcode 3.2-compatible 로 바꾼다.
 3-2.Build Tab 에서
 Base SDK를 iPhone Device 4.0(배포시), 혹은 iPhone Simulator 4.0(테스트시) 로 바꾼다
 iPhone OS Deployment Target 을 iPhone OS 3.0 (즉 지원하고자 하는 하위버전으로) 로 바꾼다.
이렇게 하시면 됩니다.


-객체 타입 비교-
if ( [a isKindOfClass:b] )


-문자열 비교-
NSString *strText = idField.text;
if([srText isEqualToString:@"mihr01"])
....
else if([srText isEqualToString:@"mihr02"])
....
else
...
이렇게 하셔도 되고요 완전 같은 스트링이 아니라
 
포함된것을 찾으려면
if([strText rangeOfString:@"mihr01"].length) 


-탭뷰에 스타일시트를 붙일때-
UIActionSheet *popupQuery = [[UIActionSheetalloc]
initWithTitle:nildelegate:self
cancelButtonTitle:@"취소"
destructiveButtonTitle:nil
otherButtonTitles:@"사진찍기", @"기존의사진선택", nil];
popupQuery.actionSheetStyle = UIActionSheetStyleBlackOpaque;
QuizersAppDelegate *appDelegate = (QuizersAppDelegate *)[[UIApplicationsharedApplication] delegate];
[popupQuery showInView:appDelegate.window];


-스크롤  밀어서  데이터  리플래쉬  하기-
소스코드
http://github.com/facebook/three20/tree/master/samples/TTTwitter/
설명
http://www.drobnik.com/touch/2009/12/how-to-make-a-pull-to-reload-tableview-just-like-tweetie-2/


-테이블뷰 위에 검색창 붙이는 방법-
테이블뷰 위에 검색창 넣으신 후에, viewDidLoad 메서드 부분에 [table setContentOffset:CGPointMake(0.0, 44.0) animated:NO];해주시면 처음 보여질 때는 검색창이 안 보이다가 밑으로 땡기면 나타나게 됩니다.


-네트워크  연결  됐는지  확인 Reachability-
http://www.raddonline.com/blogs/geek-journal/iphone-sdk-testing-network-reachability/
http://theeye.pe.kr/entry/how-to-check-network-connection-on-iphone-sdk



-아이폰 강제종료 버튼 이벤트-
아래 메소드가 어플이 종료될 때 수행되는 함수입니다.
종료될 때에 각종 리소스들을 Free시킬 경우에 사용됩니다.
참고하시면 될 듯 합니다~
 - (void)applicationWillTerminate:(UIApplication  *)application



-크랙 방지 클래스-
http://cafe.naver.com/mcbugi/11661



-어플을 강제 종료하는 API 는 아이폰에서 제공하지 않는다?-
http://cafe.naver.com/mcbugi/11803



-탭바 클릭시 바로 UISearchBar 클릭되도록 할려면 어떻게 해야 하나요?-
UISearchBar가 first responder가 되게 하면 됩니다.
[searchBarObj becomeFirstResponder];



-UITextField 입력값 체크하기 : 문자열 길이, 숫자여부 체크-

헤더(.h)에 UITextFieldDelegate 선언

@interface 클 래스명 : UIViewController



구현부(.m)에 다음 메쏘드를 구현하면 됨

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 

//return NO하면 입력이 취소됨
//return YES하면 입력이 허락됨
//textField 이용해서 어느 텍스트필드인지 구분 가능

//최대길이

int maxLength = 128;

NSString *candidateString;

NSNumber *candidateNumber;


//입력 들어온 값을 담아둔다

candidateString = [textField.text stringByReplacingCharactersInRange:range withString:string];


if(textField == IDField) {
maxLength = 8;
} else if(textField == AgeField) {
//숫자여부 점검

//length가 0보다 클 경우만 체크
//0인 경우는 백스페이스의 경우이므로 체크하지 않아야 한다

if ([string length] > 0) {

//numberFormatter는 자주 사용할 예정이므로 아래 코드를 이용해서 생성해둬야함

//numberFormatter = [[NSNumberFormatter allocinit];

//[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];


//numberFormatter 를 이용해서 NSNumber로 변환

candidateNumber = [numberFormatter numberFromString:candidateString];


//nil이면 숫자가 아니므로 NO 리턴해서 입력취소

if(candidateNumber == nil) {

return NO;

}


//원 래 문자열과 숫자로 변환한 후의 값이 문자열 비교시 다르면

//숫자가 아닌 부분이 섞여있다는 의미임

if ([[candidateNumber stringValuecompare:candidateString] !=  NSOrderedSame) {

return NO;

}


maxLength = 2;

}

}

//길이 초과 점검

if ([candidateString length] > maxLength) {

return NO;

}


return YES;

}

http://cafe.naver.com/mcbugi/37651



-How to split string into substrings on iPhone?-
http://stackoverflow.com/questions/594076/how-to-split-string-into-substrings-on-iphone



-메모리 누수-
http://cafe.naver.com/mcbugi/64257


-디바이스 가로 세로 상태-
UIDeviceOrientationIsLandscape([UIDevicecurrentDevice].orientation) ?


-UITextField 에 자동 포커스 주기-
키보드 올리면서 커서를 넣을때는 아래방법을 이용하시면 됩니다.
[textField becomeFirstResponder]; 
참고로 이건 커서를 빼면서 키보드를 내리실때 사용하시면 되구요...
[textField resignFirstResponder]; 


-홈버튼이 눌렸을 때도 텍스트뷰 내용을 저장하려면 어떻게 해야할까요?-
- (void)applicationWillTerminate:(UIApplication *)application / Application Delegate 메서드 부분에 구현하시면 되지않을가요? 


-3.2 4.0  동영상  플레이-
http://iphonedevelopertips.com/video/getting-mpmovieplayercontroller-to-cooperate-with-ios4-3-2-ipad-and-earlier-versions-of-iphone-sdk.html


-한글완성형(EUC-KR)을 iPhone/Mac에서 사용할 수 있는 언어셋으로 변환하기-
http://blog.backpackholic.tv/160


-인터페이스 함수들을 편하게 가져오는 방법-
http://code.google.com/p/xcode-auto-assistant/


-#pragma mark로 코드 쉽게 구분하기-
http://cafe.naver.com/mcbugi/64408


-os4에서 applicationWillTerminate가 안먹어서 알게된것-
os4에서 applicationWillTerminate: 가 안먹어서 삽질하다가 알아낸 결과입니다.
뒷북 인지는 모르지만 혹시 모르시는 분을 위해서 적어봅니다.
os3.x 에서는 홈버튼을 한번만 누르면 applicationWillTerminate 가 아주 잘 호출됩니다.
하지만 os4 에서는 홈버튼을 한번만 누르면 
applicationDidEnterBackground 가 호출됩니다.
os4 에서 멀티태스킹을 위해서 좀 바뀌었습니다.
os4에서도 홈버튼 한번 누를때 applicationWillTerminate 가 호출되게 하려면
info.plist 에서 'Application does not run in background' 이 속성을 추가해주면 됩니다.
위 속성이 없으면 기본적으로 멀티태스킹이 되는걸로 간주합니다. (진짜 멀티태스킹은 아니지만)
위 속성이 없을때 호출되는 메소드를 실험해 봤습니다.
-----------------------------------------------------------------
처음 어플을 실행시키면
     didFinishLaunchingWithOptions, 
applicationDidBecomeActive 
이 호출되고
홈버 튼을 한번 만 누르면
applicationWillResignActive, 
applicationDidEnterBackground
호출되면서 어플이 종료되고
이상태에서 다시 어플을 실행시키면
applicationWillEnterForeground, 
applicationDidBecomeActive 
호출됩니다.
홈버튼을 두번 누르면
applicationWillResignActive
이 호출됩니다.
----------------------------------------------------------------
'Application does not run in background' 을 체크하면
홈버 튼을 한번만 누르면 applicationWillTerminate 를 호출합니다.
'근데 속성 체크 안했을때 applicationWillTerminate 는 호출이 안되는건지 궁금하네요.
아시는 분 좀 알려주세요.

답글 : 
Applicationwillterminate함수 대신에 applicationDidENterBAckground 사용하라고하네여 이곳에서 공유자원해제나 사용자데이타 저장,타이머 무효화,어플상태정보등 저장을 하라고 합니다. http://cafe.naver.com/mcbugi/65497


-COCOS2D 번개 효과-
http://www.cocos2d-iphone.org/forum/topic/370


-iPhone 4.0 호환 키보드에 버튼 or 뷰 붙이기-
기존꺼에 비해 약간 수정되 었을뿐입니다....
하지만 -_-이거 찾느라 ㅠㅠ;; 

3.1.x에서는 windows 서브뷰에 항상 키보드 뷰가 있었지만 ...
4.0 부터는 windows 에 항상 있는게 아니고, 키보드를 불렀을때 -_- 붙어서 오더라고요.. 그래서

Done 버튼 붙이는 예제 입니다. (Number 패드에)

아래 액션을 Text필드의 BeginTouched 에 연결 시킵니다.
 // 키보드가 나왔을때랑 사라질때의 이벤트를 잡아냅니다.
//3.1.X 에서는 UIKeyboardWillShowNotification 으로 잡지만
// 4.0 때문에 --; DidShow로 잡아줬습니다.
//그래야 윈도우에 키보드가 있더라고요 ;;;
-(IBAction)FieldTouched{
    
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(keyboardWillShow:) 
                                                 name:UIKeyboardDidShowNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(keyboardWillHide:) 
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
    
    
}

// 키보드가 나왔을때 Done 버튼 붙여주기 
- (void)keyboardWillShow:(NSNotification *)note {  
    
    UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
    doneButton.frame = CGRectMake(0, 163, 106, 53);
    doneButton.adjustsImageWhenHighlighted = NO;
    [doneButton setImage:[UIImage imageNamed:@"DoneUp.png"] forState:UIControlStateNormal];
    [doneButton setImage:[UIImage imageNamed:@"DoneDown.png"] forState:UIControlStateHighlighted];
    [doneButton addTarget:self action:@selector(backgroundTap:) forControlEvents:UIControlEventTouchUpInside];

    //3.1.x 와 4.0 호환 키보드 붙이기
    for( UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows] ){
        for( UIView *keyboard in [keyboardWindow subviews] ){
            NSString *desc = [keyboard description];
            if( [desc hasPrefix:@"               [desc hasPrefix:@"               [desc hasPrefix:@"            {
                [keyboard addSubview:doneButton];
            }
        }
    }
    
}

// 키보드가 없어질때 Done 버튼을 삭제 합니다.
- (void)keyboardWillHide:(NSNotification *)note {  
    
    for( UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows] ){
        for( UIView *keyboard in [keyboardWindow subviews] ){
            NSString *desc = [keyboard description];
            if( [desc hasPrefix:@"               [desc hasPrefix:@"               [desc hasPrefix:@"            {
                for(UIView *subview in [keyboard subviews])
                {
                    [subview removeFromSuperview];
                }
                
            }
        }
    }
}

도 움 되시길 바랍니다 ;)
http://cafe.naver.com/mcbugi/62349


-배열내 숫자 값 비교해서 정렬하기-
만약에 객체내의 인스턴스를 키로 정렬할 경우에는 NSSortDescriptor 를
쓰시면 됩니다.
아래는 name으로 정렬한 예입니다.

@interface Test :
NSObject {
NSString *name;
double distance;
}
@property
(nonatomic, retain) NSString *name;
@property double
distance;
@end

@implementation Test
@synthesize name, distance;
@end


아 래는 사용방법입니다.
       Test *t1 = [[Test alloc] init];
Test *t2 = [[Test alloc] init];
Test *t3 = [[Test alloc] init];
[t1 setName:@"마바사"];
[t2 setName:@"아자차"];
[t3 setName:@"가나다"];
[t1 setDistance:1.2];
[t2 setDistance:2.5];
[t3 setDistance:0.5];
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:t1];
[array addObject:t2];
[array addObject:t3];
[t1 release];
[t2 release];
[t3 release];
// 이름순으로 정렬
NSSortDescriptor *nameSort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(localizedCompare:)];
[array sortUsingDescriptors:[NSArray arrayWithObjects:nameSort, nil]];
[nameSort release];
for(Test *t in array) {
NSLog(@"%@ %f", [t name], [t distance]);
}
[array removeAllObjects];


------[결 과]------
2010-07-12 17:46:13.117 Sort[5070:20b] 가나다 0.500000
2010-07-12 17:46:13.125 Sort[5070:20b] 마바사 1.200000
2010-07-12 17:46:13.130 Sort[5070:20b] 아자차 2.500000


p.s. distance로 정렬하고자 한다면 
NSSortDescriptor *distanceSort = [[NSSortDescriptor alloc] initWithKey:@"distance" ascending:YES];
nameSort 대신 distanceSort를 넣으시면 됩니다.
http://cafe.naver.com/mcbugi/65873


-[TIP] 시뮬레이터 사진앨범에 사진넣기-
1) 시뮬레이터를 실행시킵니다.

2) 맥에서 포토라이브러리에 넣을 사진을 시뮬레이터로 Drag&Drop 합니다.

3) 그러면, 사파리가 열리면서 Drag한 이미지가 표시가 될겁니다.

4) 그 표시된 이미지를 마우스로 꾸~~~~~~욱 눌러줍니다.

5) 그러면, 메뉴가 뜨면서 이미지를 저장할건지 복사할건지를 묻습니다.

6) 이미지 저장을 누릅니다.

7) 이제 시뮬레이터의 사진앨범에 가 보시면 아까 저장한 사진이 들어가있을겁니다.

'영삼이의 IT정보' 카테고리의 다른 글

StoreKit  (0) 2012.06.10
iOS 키보드  (0) 2012.06.10
UIImageJPEGRepresentation  (0) 2012.06.04
XHTML/CSS 무료 템플릿 배포사이트  (0) 2012.06.01
메인 runloop 쓰레드에 타이머 동작 시키기  (0) 2012.06.01
Posted by 다오나무
영삼이의 IT정보2012. 6. 4. 13:04

 [[NSData allocinitWithData:UIImageJPEGRepresentation(_image0.4)];


같은 경우 위의 0.4 의 자리에 들어가는 이미지 퀄리티와 바이트 량의 상관관계를 직접 실험해 보았다.



실험 대상 : 1,486,503 바이트 (약 1.5메가) JPEG 이미지. (생강꿀차 사진 ㅋㅋ)


 파라메터 값바이트 (원본과 비교한 %)
-0.2117143 
- 0.1117143 
 - 0.9117143  
-0.1 117143  
-0.01 117143  
0 117143  
0.000001 117143  
0.02 117143  
0.03 117143  
0.04117143  
0.05117143  
0.06117143  
0.067117143  
0.068117144   -> 처음으로 수치 변화
0.07117155
0.079117277
0.08117557
0.081117144
0.085118108
0.9118966
0.1119702 (8.053 %)
0.11119737
0.2136765 (9.200 %)
0.3204806 (13.777 %)
0.4355252 (23.898 %)
0.5531804 (35.775 %)
0.6731074 (49.180 %)
0.71147188 (77.176 %)
0.81326826 (89.258 %)
0.811338302 (90.030 %)
0.891455457 (97.912 %)
0.91470849 (98.946 %)
1.02601934 (175.037 %) -> 1.0 일땐 원본보다큰값
1.12601934 (175.037 %)
2.12601934 (175.037 %)

공식적으로는 0.1에서1.0 사이의 값을 사용하도록 되어있다.

그래도 -,1 이상의 값도 실험해 보았다.


특이점은 1.0일때 원본과 같은 값이 아니라 훨신 큰 바이트 값을 가진다는점이다.

0.9 정도일때 원본과 거의 비슷한 값이다. 서버와 통신을 위해서는 0.3, 0.4 정도값이 적당한 것같다.




그래프로 찍어보면 이런 형태의 수렴 그래프. 뭔가의 루트 값을 이용하는 것같다.


Posted by 다오나무
영삼이의 IT정보2012. 6. 1. 16:25

일반적으로 타이머를 동작시키면 UI 작동중에는 동작이 되질 않는다.


스크롤중이거나 버튼 터치시.. 등등 UI가 먼저 우선 순위인 것이다..


하지만 메인 runloop에 동작시키면 UI보다 우선순위가 될 수 있다..


다음처럼 하면 된다..



 self.timer = [NSTimer timerWithTimeInterval:0.5 target:self selector:@selector(countDown)

                                                        userInfo:nil repeats:YES];

 [[NSRunLoop mainRunLoopaddTimer:self.timer forMode:NSRunLoopCommonModes];

Posted by 다오나무
영삼이의 IT정보2012. 6. 1. 16:18

- (void)myStringExample

{

    // 파일명에서 확장자 얻기

    NSString *fileName = @"somefile.txt";

    NSString *fileExtension = [fileName pathExtension];

    

    // 공백문자 없애기

    NSString *myString = @" one two three ";

    NSString *trimed = [myString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

    

    NSString *string1 = @"some string";

    NSString *string2 = @"some other string";

    NSString *string3 = @"Some StRiNg";

    NSString *string4 = @"some other string";

    

    // 문자열 비교

    NSLog(@"%i",[string2 isEqualToString:string4]);

    NSLog(@"%i",[string1 isEqualToString:string3]);

    NSLog(@"%i",([string1 caseInsensitiveCompare:string3] == NSOrderedSame));

    

    // 스트링을 double, int값으로 변경하기 

    NSString *n = @"12345";

    double d = [n doubleValue];

    int i = [n intValue];

    NSLog(@"%f, %d",d,i);

    

    // URL에서 HTML얻기

    NSURL *url = [NSURL URLWithString:@"http://google.com"];

    NSString *pageContents = [NSString stringWithContentsOfURL:url];

    

    NSLog(@"%@", pageContents);

    

    // 숫자 변경

    NSString *numberString = @"one two three";

    NSRange foundRange = [numberString rangeOfString:@"two"];

    NSString *oneString = [numberString substringToIndex:3];

    NSString *twoString = [numberString substringWithRange:NSMakeRange(43)];

    NSString *threeString = [numberString substringFromIndex:8];

    

    NSString *repeatString = [numberString 

                              stringByReplacingOccurrencesOfString:@"three" withString:@"four"];

    BOOL found = ([numberString rangeOfString:@"two1"].location != NSNotFound);

    

    NSString *stringa = @"one";

    NSString *stringb = [stringa stringByAppendingString:@" two"];

    

    NSLog(@"%i - %i",foundRange.location, foundRange.length);

    NSLog(@"%@",repeatString);

    NSLog(@"[%@] [%@] [%@]",oneString,twoString,threeString);

    NSLog(@"%@",[numberString componentsSeparatedByString:@" "]);

}


- (void)myDateExample

{

    // 현재 날짜시간 얻기

    NSDate *myDate = [NSDate date];

    NSLog(@"%@", myDate);

    

    // 다음 날짜 얻기(초를 기반한 interval 계산)

    NSTimeInterval secondsPerDay = 24*60*60;

    NSDate *tomorrow = [NSDate dateWithTimeIntervalSinceNow:secondsPerDay];

    NSLog(@"%@", tomorrow);

    

    // 이전 날짜 얻기

    NSDate *now = [NSDate date];

    NSDate *yesterday = [now addTimeInterval:-secondsPerDay];

    NSLog(@"%@", yesterday);

    

    // 날짜 차이 얻기

    NSTimeInterval secondsBetweenDates = [yesterday timeIntervalSinceDate:now];

    NSLog(@"%@", secondsBetweenDates);


    NSDateComponents *comp = [[NSDateComponents allocinit];

    [comp setMonth:06];

    [comp setDay:01];

    [comp setYear:2010];

    NSCalendar *myCal = [[NSCalendar allocinitWithCalendarIdentifier:NSGregorianCalendar];

    NSDate *myDate2 = [myCal dateFromComponents:comp];

    

    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];

    [formatter setDateStyle:NSDateFormatterMediumStyle];

    NSString *friendlyDate = [formatter stringFromDate:now];

    

    NSLog(@"%@", friendlyDate);

    

    [formatter setDateFormat:@"yyyy-mm-dd"];

    NSString *friendlyDate2 = [formatter stringFromDate:now];

    

    NSLog(@"%@", friendlyDate2);

    

}


- (void)myArrayExample 

{

    NSString *string1 = @"one";

    NSString *string2 = @"two";

    NSString *string3 = @"three";

    

    NSArray *myArray = [NSArray arrayWithObjects:string1, string2, string3, nil];

    

    // Array 복사

    NSArray *myArray2 = [NSArray arrayWithArray:myArray];

    

    // 범위를 지정해서 Array 복사

    NSRange range = NSMakeRange(02);

    NSArray *subArray = [myArray subarrayWithRange:range];

    

    int arrayLength = [myArray count];

    NSLog(@"%d", arrayLength);

    

    int arrayLength2 = [subArray count];

    NSLog(@"%d", arrayLength2);



    // 루프를 출력

    for (NSString *obj in myArray) {

        NSLog(@"%@", obj);

    }

    

    // 루프를 거꾸로 출력

    for (NSString *obj2 in [myArray reverseObjectEnumerator]) {

        NSLog(@"%@", obj2);

    }

    

    // 정렬

    [myArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

    

}


- (void)myDictionaryExample 

{

    NSArray *arr1 = [NSArray arrayWithObjects:@"iPhone"@"iPod"nil];

    NSArray *arr2 = [NSArray arrayWithObjects:@"iMac"@"Mac Pro"@"Macbook"@"Macbook Pro"nil];

    

    //  부분에서 오류가 

    NSDictionary *myDict = [[NSDictionary allocdictionaryWithObjectsAndKeys:arr1, @"mobile", arr2, @"computers"nil];

    

    int dictSize = [myDict count];

    NSLog(@"%d", dictSize);

    

}


- (void)myNotificationExample

{

    // Notification 등록

    [[NSNotificationCenter defaultCenteraddObserver:self selector:@selector(doSomething:) name:MY_NOTIFICATION object:nil];

    

    // Notification 호출

    [[NSNotificationCenter defaultCenterpostNotificationName:MY_NOTIFICATION object:nil];

    

}


- (void)doSomething:(NSNotification *) aNote 

{

    NSLog(@"doSomething called...");

    

    // 만약 aNote 통해서 뭔가 전달되었다면

    // [aNote object] 받아서 처리함

    

}


- (void)myTimerExample 

{

    // 타이머 생성

    //NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(myTimerAction:) userInfo:nil repeats:NO];

    

    //[myTimer invalidate];

    // 하루의   

    NSTimeInterval secondsPerDay = 24*60*60;

    NSDate *tomorrow = [NSDate dateWithTimeIntervalSinceNow:secondsPerDay];

    NSTimer *myTimer = [[NSTimer allocinitWithFireDate:tomorrow interval:10.0 target:self selector:@selector(myTimerAction) userInfo:nil repeats:NO];

    

    [[NSRunLoop mainRunLoopaddTimer:myTimer forMode:NSDefaultRunLoopMode];

    

}


Posted by 다오나무
영삼이의 IT정보2012. 5. 31. 15:06

각 단말기에는 해당 단말기를 식별하는 유일값인 UDID가 존재합니다. iOS 플랫폼의 경우 SDK 상에서 쉽게 이 UDID 값을 추출할 수 있었습니다. 이 UDID는 사용자의 직접적인 개인정보를 이용하지 않고 사용자의 패턴 분석에서부터 타겟광고 소스 등 여러 부분에서 이용하고 있었습니다만 현재 베타테스트가 진행 중인 iOS5에서는 이 UDID 의 이용은 제한될(deprecated) 예정입니다. 이에 따라 애플에서는 UDID보다는 UUID를  생성하여 이용하라고 권고하고 있습니다. UUID는 단말기의 고유값이 아닌 어플리케이션에서 생성한 유일값으로 생성할 때마다 변경되는 랜덤값입니다. 따라서 개발자분들은 이에 대한 대응을 미리 하시는 것이 좋을 것 같아서 정리해보았습니다.

  • uniqueIdentifier 메소드가 사라질 예정

UDID는 단말기를 식별하기 위해 고유하게 할당된 40개의 숫자와 문자열입니다. 이런 고유값은 개인정보이다. 아니다 기기 식별값이므로 개인정보는 아니다라는 논란으로 잠시 인터넷이 뜨거웠던 적이 있습니다. (2011/05/10 서울경제 기사, http://economy.hankooki.com/lpage/it/201105/e20110510173640117700.htm)

이 UDID는 구글, 오픈페인트를 비롯한 여러 광고 및 트래픽 분석툴에 사용되고 있는 상황에서 애플이 드디어 칼질을 가하기 시작했습니다. iOS5 beta 6에서는 UDID를 가져올 때 사용하는 메소드를 없애겠다는 의지로 해당 메소드를 deprecated시키고 대신 Core 레벨에서 랜덤한 UUID를 생성하는 메소드를 이용하라는 권고를 내렸습니다. (Apple Sneaks A Big Change Into iOS 5: Phasing Out Developer Access To The UDID :http://techcrunch.com/2011/08/19/apple-ios-5-phasing-out-udid/).

실제로 iOS5 beta 6에서 [[UIDevice currentDevice] uniqueIdentifier]가 포함된 프로젝트를 빌드하면 아래와 같은 경고가 나타납니다.

  

  • UDID가 아닌 UUID를 이용하라는 권고

애플에서는 UDID값이 아닌 UUID(Universally Unique Identifiers)를 이용하라는 권고를 내렸습니다. CFUUID Documentation을 참조하면 이 UUID는 128-bit 값으로 생성된 유일값이며 이는 시간과 공간값으로 생성된 유일값이므로 중복될 염려가 없다고 합니다.

유일값 생성 방법은 아래와 같으며,

CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
NSString *string = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuid);

생성되는 UUID는 아래와 같은 형태의 결과값을 가집니다.

이렇게 생성된 UUID를 NSUserDefaults 등을 이용하여 값을 유지시켜줌으로 UDID와 동일한 역할을 하도록 개발자들의 추가 구현이 필요하다라고 문서에는 나와있습니다. 어느 부분에서는 한 줄이면 가능한 유일값 추출을 이제는 개발자가 직접 신경을 써서 관리하라고하니 한숨이 나오는 건 사실입니다.

  이렇게 생성된 관리를 위한 방법으로는 NSUserDefaults를 이용하여 앱 내부에서 관리하는 방법별도의 서버에 이 값을 저장하여 관리하는 방법, 또는 iOS5 이상의 iCloud를 이용하는 앱이라면 iCloud의 Key-Value Data Storage를 이용하는 방법을 생각해 볼 수 있습니다. 이도 문제가 된다면 Mac Address를 추출하고 이를 해쉬값을 이용(MD5)하는 방법도 최근 iOS 개발자분들이 관심을 가지고 있는 것 같습니다. (GitHub : http://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5).

 

  • UDID vs. UUID

 UDID는 Unique Device Identifier로 기기의 고유값입니다. 하지만 UUID는 앱 자체에서 생성되는 고유값으로 사용자가 사용하는 앱의 고유값으로 볼 수 있습니다. 즉, UUID를 사용하도록 권고하는 것은 단말기의 고유값을 사용하지 말고 앱마다 각자의 고유값을 이용하라는 풀이로 볼 수 있습니다.

  이 두 유일값의 장단점을 간략히 살펴보면 아래 표와 같습니다.

 

  • 당장은 고려하지 않아도 된다?
  •  

Deprecated 된 메소드는 아시다시피 현재 사용하지 못한다는 의미는 아니지만 앱스토어에 앱을 등록할 때 리젝 사유가 될 수 있습니다. 위에서 설명드린대로 경고가 항상 나타난다면 당장 대안을 찾아야하는 상황이지만 프로젝트의 Deployment Target을 5.0 이하. 즉, 4.x나 3.x로 한다면 메소드를 사용이 가능합니다. 물론 개발 상에서 사용가능하다는 것이며 정책상으로 어떻게 될지는 모르는 상황입니다.

UDID를 활용하는 서비스나 앱이 많을 것으로 예상됩니다. iOS5가 정식으로 릴리즈되더라도 당장에 사용못하게 하지는 않을 것으로 예상되지만 미리 준비를 해두시는 것이 좋을 것 같습니다.

아래는 Deployment Target을 4.0으로 설정하는 화면과 설정 이후 빌드한 결과 uniqueIdentifier에 경고가 나타나지 않는 화면입니다.

 

  • UUID가 아닌 다른 유일값 사용에 대해서
  •  

UUID가 아닌 유일값에 대해서는 애플에서는 아직 언급하고 있지 않습니다만 Ethernet의 MAC AddressBundle identifier 등 여러 대안을 생각해볼 수 있습니다. MAC Address의 경우 Cocoa API에는 추출 메소드가 없어 직접 Core에 접근하여 추출을 해야하며, 해당값을 그대로 사용하는 것이 아닌 MD5나 SHA-1 등의 해쉬를 이용하여 보안이슈가 발생되지 않게 해야합니다. 이로 인해 작업 공수가 더 추가된다는 것, 또한 이후에 애플에서 해당값의 사용을 금지할 수도 있다는 잠재적인 위험요소가 있으므로 되도록이면 애플에서 권장하는 UUID를 이용하는 방법으로 문제를 해결하는 것을 추천해드립니다.

 

  • 결론

UDID를 얻어오는 메소드는 iOS5부터 사용할 수 없는, 삭제 예정인 메소드입니다.
- 프로젝트의 Deploy Target을 5.0이 아닌 그 이하 버전으로 설정하는 경우에는 UDID 추출 메소드 사용이 가능합니다.
- 정책상 결정된 부분은 아니지만 애플의 권고는 UUID를 이용하는 것입니다.
- 또한, iOS5가 정식으로 발표된 이후에는 반드시 고려되어야하는 이슈이므로, 미리 이에 대한 대비가 마련되어야 합니다.
- UUID도 단말기의 고유값이 아니므로 서비스의 특성에 따라서는 UDID가 아닌 단말기의 고유값으로 간주할 수 있는 MAC Address를 이용하는 방법 등을 고려할 수 있습니다.
- UDID를 사용하지 못하는 것과 동일하게 MAC Address도 사용이 불가할 수도 있다는 점은 고려하여 대책 마련을 하시는 것이 좋습니다.
- MAC Address를 해쉬처리한 문자열이 단말기의 고유값으로 보는 방안은 애플의 정책에 위배되지 않는다는 가정하에서 현재 단말기의 유일값으로 지정할 수 있는 최상의 방안으로 고려됩니다. (iOS5 정식출시가 되어봐야 알 것 같습니다.)

Posted by 다오나무