iOS2012. 9. 26. 10:27

iOS5 시뮬레이터에서는 트위터 계정을 입력하여 트위터를 보낼수가 있다 ^^. 현존하는 시뮬레이터 중에서 가장 유용한 시뮬레이터가 아닌가하는 생각이 든다. iOS5에서 추가된 Twitter.framework를 이용해서 간단히 트위터 메세지를 보내는 방법에 대해서 간단히 포스팅한다.
 



우선 iOS5의 트위터 메세지 발송을 위해서는 Twitter.framework를 추가해줘야한다.
 Target중 production target을 선택하고, Build Phases에서 Link Binary With Libraries에서 Twitter.framework를 찾아서 추가한다.
 

 

storyboard에서 UIView 위에 UIButton을 추가하고 IBAction을 연결한다.


Twitter.h를 임포트하고 IBAction으로 연결된 메소드를 구현한다.
 

#import <Twitter/Twitter.h>

- (IBAction)onUpdateTwitterButton:(id)sender {

    TWTweetComposeViewController *twitter = [[TWTweetComposeViewControllerallocinit];

    [twitter setInitialText:@"iOS5 Twitter API 테스트합니다."];

    [self presentModalViewController:twitter animated:YES];

    [twitter setCompletionHandler:^(TWTweetComposeViewControllerResultresult){

        NSString *title = @"트위터 상태";

        NSString *message;

        

        if (result == TWTweetComposeViewControllerResultCancelled) {

            message = @"트위터 업데이트를 취소합니다.";

        } else {

            message = @"트위터를 업데이트 완료했습니다.";

        }

        

        [[[UIAlertView allocinitWithTitle:title message:messagedelegate:self cancelButtonTitle:nil otherButtonTitles:@"확인"nil] show];

        

        [self dismissModalViewControllerAnimated:YES];

    }];

}

 

Build and Run을 하면 다음과 같은 화면이 나타난다. 이 화면은 시뮬레이트에 트위터 계정이 설정되지 않아서 그렇다.


  Settings를 누르고 들어가서 트위터 계정으로 로그인하고 다시 실행하면 다음과 같이 트위터 컴포즈가 준비된다.

send를 누르면 트위터 페이지에 트위터가 업데이트 된것을 확인할 수 있고, setCompleteHandler에 구현한 결과처리를 한다.

 

Posted by 다오나무
iOS2012. 9. 4. 11:02

How to Customize UITabBar on iOS 5

Building the new version of the app Blocos de Rua I was challenged to customize the UITabBar so it meets what the designer wants. In iOS 5 this is pretty easy to do but I haven’t figured out the proper way to do it from the beginning, this post is my findings on how to do it properly by correctly using the new iOS 5 APIs to customize appearance.

The final look:

Keep reading to see the code.

The appearance APIs in iOS 5 are great. They reduce lots of custom drawRect: that used to be necessary to customize the default UIKit components. The first time I tried to customized the tab bar I had some problems with images been offset upwards because I was using the wrong methods.First thing I learned, the setFinishedSelectedImage:finishedUnselectedImage: from UITabBarItem is the tab’s icon not a image for the whole tab with background, icon and label.

Customize the UITabBar is a peace of cake when you understand how the APIs should be used, take a look:

From inside out, the UITabBar

First - usually in your app delegate - set the image for the entire tab bar’s background, which represents the “normal” state of all tabs. The dimension is 320 x 49 points.

1
[[[self tabBarController] tabBar] setBackgroundImage:[UIImage imageNamed:@"background"]];

Then configure the selected state of a tab. This is necessary because in this app I don’t want the default white highlight that represents the selected tab. Pay attention to the image’s width, it must be the same of a single tab. In my case 320/4, 80 points wide.

1
[[[self tabBarController] tabBar] setSelectionIndicatorImage:[UIImage imageNamed:@"selected"]];

Last but not least, the UITabBarItem

Unlike the default behavior the image shouldn’t change when the tab is selected, this is why I set the same image in both states. For each UIViewController that will be part of the tab bar you need to configure the tab image like this:

1
2
3
4
5
6
7
- (id)init {
    self = [super initWithNibName:@"MyNibName" bundle:nil];
    if (self) {
        self.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"The Title" image:nil tag:0];
        [[self tabBarItem] setFinishedSelectedImage:[UIImage imageNamed:@"tab_icon"] withFinishedUnselectedImage:[UIImage imageNamed:@"tab_icon"]];
    }
}

The last detail is the title’s color on the unselected tab, they can’t be the default gray color. To change the color we need a dictionary of attributes whit the UITextAttributeTextColor key:

1
2
3
4
// below the setFinishedSelectedImage:withFinishedUnselectedImage:
[[self tabBarItem] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
        [UIColor whiteColor], UITextAttributeTextColor,
        nil] forState:UIControlStateNormal];

That’s all folks.

Posted by 다오나무
영삼이의 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. 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 다오나무