iOS2012. 6. 20. 21:10

제목그대로 인데요

아이폰에서 탭바를 사용시에

탭을 4개 넣을껀데요

그 하나하나당 이미지를 넣을껀데 그 이미지에 사이즈가 최대사이즈가 얼마가 들어갈수있는건가요?


developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/MobileHIG/IconsImages/IconsImages.html


아래주소로 가보면 


30 x 30  이 기본이고 60 x 60 이 높은퀄리티인거 같은데...

탭바아이템 하나하나가 정사각형이 아니고 직사각형 모양인데...기준은 저렇게 적혀있어서

탭바를 4개 넣을시에 최대사이즈를 알고싶습니다..

76x48 정도로 잡아서 해봤었는데 이미지가 삽입되는데 아랫부분이 잘려서 들어가지더라구요...

(이것도 좀 의문입니다...분명 가로크기를 기준에서 벗어났는데 들어가진걸보면...)

도움좀 주세요~


Posted by 다오나무
iOS2012. 6. 20. 20:22


APNS 프로세스 정리 URL : 

http://www.imaso.co.kr/?doc=bbs/gnuboard.php&bo_table=article&wr_id=38399




APNS 설정 처리 관련 : 

설정>알림 > 해당 App 알림 설정에 가면


알림센터

보기

알림스타일

아이콘에 알림표시

사운드

잠근화면으로 보기


메뉴들이 있다. 이때 실제 확인 가능한 이벤트 들은

알림스타일 , 아이콘에 알림 표시, 사운드로 판단 된다.


그래서 위 세가지 설정 값을 확인 할 수 있는 방법은 아래와 같다.

그 중에서도 알림 스타일이 "없음"인 경우에는 Push  메세지를 서버에서 날려도

화면에 나타나지 않는다.


// 앱을 실행시켰을 때 푸시 알람 형태 활성화 설정. 뱃지, 알림창, 사운드
  NSUInteger rntypes = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];


 NSString *pushAlert = 
 (rntypes & UIRemoteNotificationTypeAlert) ? @"enabled" : @"disabled"; //알림스타일 여부 (이 값이 0인 경우 알림 메세지가 보이지 않는다.)

  NSString *pushBadge = 
 (rntypes & UIRemoteNotificationTypeBadge) ? @"enabled" : @"disabled"; //아이콘에 알림 표시 여부

  NSString *pushSound = 
 (rntypes & UIRemoteNotificationTypeSound) ? @"enabled" : @"disabled";  //사운드 설정여부



<APNS 최초 알럿에서 "승인"을 클릭 한 경우와 "미승인"을 클릭 한 경우의 차이점>

아래와 같이 App의 APNS등록 로직이 들어 간 경우,

"승인" 또는 "미승인"에 관계없이 "설정>알림>해당App 설정" 화면은 동일하게 나타난다.


//APNS등록

UIRemoteNotificationType notiType = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;

if (iOSVersion >= 5) notiType = notiType | UIRemoteNotificationTypeNewsstandContentAvailability;

    

[[UIApplication sharedApplicationunregisterForRemoteNotifications];

[[UIApplication sharedApplicationregisterForRemoteNotificationTypes:notiType];


iOS 디바이스 2대로 각각 테스트 결과, App 최초 설치 후 APNS "승인" 과 "미승인"의 차이점은 

사용자가 최초 "승인"을 클릭 한 경우, 해당App의 알림 스타일이 "배너"로 되어 있었고

사용자가 최초 "미승인"을 클릭 한 경우, 해당App의 알림 스타일이 "없음"으로 되어 있었다.


결국, 최초 APNS승인 여부의 차이는 "승인" 또는 "미승인" 클릭 시, 화면에 알림 메세지를 보여 줄 것이냐 아니냐의 차이였다.

Posted by 다오나무
iOS2012. 6. 20. 19:07

일반적인 경우라면 iOS에서 기본적으로 제공하는 Cell Type을 통해 구현이 가능하지만, 특별히 사용자가 디자인한데로 cell을 만들어 사용하는 방법도 있다. Interface Builder를 통해 cell xib를 만들어 customize 한 cell을 만들어 보자.

1. 프로젝트를 생성하고 "UITableViewCell" 을 상속받은 Objective-C 클래스를 생성한다.



2. Custom Cell을 꾸밀 xib파일을 생성한다.(일반적으로 objective-c 클래스 파일 이름과 xib이름을 동일하게 - CustomCell이라고 - 만든다)

3. xib파일을 열어 우측 하단의 library에서 "Table View Cell"을 끌어다 놓는다. 끌어다 놓은 Table View Cell을 선택하고"Identity Inspector" 창에서 Custom Class를 위에서 만든 Objective-c Class인 "CustomCell"로 지정한다.

 4. xib에 구성하고 싶은 UI들을 올려놓고 "CustomCell class"에서 IBOutlet을 이용하여 UI component들과 연결을 한다.
 
5. TableView를 사용하기 위한 기본설정을 한다. 기본적인 내용은 여기에서 확인하면 된다.

6. ViewController.h에 TableView에 넣을 NSArray형태의 데이터를 @property로 선언하고 @synthesize로 선언한다.
 //ViewController.h
@property (retainNSMutableArray *products;
//ViewController.m
@synthesize products; 
 
 
7. 테이블에 들어갈 내용이 상품정보임으로 상품정보를 가지고 있을 Objective-C클래스(domain object)를 만든다.(이름은 Product라는 이름으로 만든다.)
 
 
8. CustomCell에 Product를 넘기면 Product의 property값을 CustomCell에 set해주는 method를 만들어 준다.

9. TableView 사용시 구현해야할 delegate method들을 구현한다.
 

 [실행 결과]

Posted by 다오나무
iOS2012. 6. 20. 15:24

안녕하세요, 개발자여러분^^


제가 이번에 이미 등록된 앱에  in app purchase 기능을 추가해서 심사중인데요.

아직 in app purchase의 실제 상품 등록은 안한 상태입니다.

현재까진 테스트 상품으로 테스트만 했구요.


근데 이제 상품을 등록하려다보니 새로 in app purchase 기능이 추가된 앱이 아직 리뷰중이라서

상품을 등록하면 이전의 앱을 기준으로 리뷰가 될 것 같은 데

현재 리뷰중인 앱을 기준으로 상품을 등록하려면 어떻게 해야 하나요?


찾아보니 아직 등록안된 앱을 기준으로 상품을 등록하려면

Version Details Page에서 뭔가 수정해야 한다는데

아무리 봐도 찾을 수가 없네요.


혹시 이런 경험해보신분 계시나요?


(그리고 상품 리뷰는 승인될 때까지 몇일 정도 걸리나요?)





질문자 인사 감사합니다. 무사히 잘 맞게 등록되었네요^^

 

리뷰중일때 IAP 쪽에서도 리뷰 신청을 동시에 하면

실제 게임이 올라가면서 IAP도 함께 RFS되는거 같습니다. 참고하세요~~

Posted by 다오나무
iOS2012. 6. 20. 15:19

당신은 지난 몇개월간 (어쩌면 몇일간) 고생해서 만든 앱을 앱스토어에 올려놨다.
아마 Waiting for Review단계라서 잠이 안 올지도 모르겠다.
그리고 처음 등록한 앱이라서 아직 설레이기도 하고 요즘 대세라는 FreeMium모델로 IAP도 설계해놨고
이제 대박이 나서 로또맞을 생각만 하고 있을지도 모른다. 
당신의 앱이 IAP설계상에서 만들어졌다면, 심사전에 반드시 확인하고 또 확인했으면 하는 것이 있다. 

케이스 1) 

A씨는 야심차게 준비한 앱을 승인올리고 매일 심사가 마무리되길 기다렸다.
승인을 올린지 4일 째 되던날 In Review가 들어갔고,
다음 날 아침에 일어나보니 Ready for Sale이라는 메일을 받았다.
신나서 앱을 릴리즈하고 보니 앱내에서 IAP 결제가 안되는 것이었다.
이런 망 ;;;; 



당신의 앱이 최초로 승인받는 앱이라면, IAP는 앱과 함께 "심사를 거쳐야 한다"
당신이 IAP를 통해서 무슨 콘텐츠를 제공할지 모르는 애플은 이 모든 것을 심사하길 원한다. 
그러므로 당신은 앱 심사를 올린 후에, [Manager In-App Purchases]에서 IAP의 상태를 다시 한번 점검해야 한다. 



 
IAP 아이템의 상태는 총 4가지 있으니 잘 기억하기 바란다. 


1) Ready to Submit: 당신의 IAP가 생성되었으나 아직 애플에 승인이 들어가지 않은 상태이다. 그러니 위의 케이스같은 황당한 일을 겪지 않기 위해서는 <앱 승인을 최초로 올려놓고 당신의 IAP가 "Ready for Submit"이라면> 큰 착오를 한것이라고 이해하고 다시 한번 App을 올려야 할 것이다. (IAP 승인요청 방법은 나중에...) 

2) Waiting for Review: 앱과 마찬가지로 심사를 기다리고 있는 중인 것이다. 당신은 "참 잘했어요" 도장을 받아야겠다.

3) Developer Action Needed: 이 케이스는 언제 발생하냐면, 애플이 당신의 앱을 리젝했을 때, 앱과 함께 심사를 요청했던 IAP들도 함께 심사가 반려된다. (IAP의 리젝은 아니다) 그 때 당신의 IAP의 상태는 Developer Action Needed 상태로 변결된다. 이때는 IAP의 <Display Name>을 살짝 수정해주면 다시 "Waiting for Review"상태로 변경되는 것을 확인할 수 있다. 만약 Developer Action Needed 상태에서 리젝됐던 앱만 다시 승인을 올릴 경우에는 다시 Case1의 상황을 맞을 수 있으니 주의하자. (난, 아직 안 당해서 모르겠네 ;;;) 
 

 

4) Approved: 앱이 판매 가능한 상태가 Ready for Sale 이라면 IAP는 Approved이다. 초록불을 보고 기뻐하면 된다. 



5) Waiting for Screenshot: 아, 이런 케이스도 봤다. IAP를 스크린샷으로 표현할 수 없는 경우도 있다. 그리고 어떤 개발자(혹은 담당자)는 깜빡하고 스크린샷을 안 올리는 실수를 범할 수 있다. 이때는 애플은 가찬없이 스크린샷이 없어서 심사를 못 하겠다고 한다. 이때는 스크린샷을 올리면 Waiting for Review상태로 돌아온다. 




자 이제 마무리를 하자. 
당신이 앱을 올리고 나서 [Manage IAP]메뉴로 들어가서 반드시 확인할 것은 "IAP가 Waiting for Review"상태인 것을 확인하는 것이다. 이 절차를 빠뜨렸다가는 아까운 5일의 시간을 그냥 날려버리는 수가 있다. 



In-App Purchase 아이템을 심사요청하는 절차는 애플이 프로세스를 이상하게 만들어놨다고 생각하는데,
어째든 그건 이 글이 사람들에게 도움을 주고 있는지 여부(댓글의 여부?)를 살펴보고 계속 작성해야겠다. 

Posted by 다오나무
iOS2012. 6. 20. 14:52

전에 어플내 컨텐츠 구매에 대해서 썼는데 이를 테스트하기 위해선 어떻게 해야하는지를 써 볼까 합니다. 아주 사소한 문제로 2, 3일 고생했네요..ㅋㅋ


1. 테스트용 어플 등록
 일반적으로 컨텐츠를 다운로드하기 위해선 App Store에 요청을 하여 과금요청을 하여 OK가 난 경우 실제 컨텐츠를 다운로드 받습니다.
 하지만 테스트를 하기 위해서 매번 과금요청을 하면 돈 버는 것보다 테스트하느라 나가는게 더 많겠죠. 그래서 애플은 샌드박스환경을 제공합니다.
 통상 과정을 동일하나 테스트용 계정을 만들어서 과금이 발생안하고 테스트를 가능하게 해줍니다. 단순히 OK만 주는게 아니고 구입이력도 관리해줍니다.

 우선 테스트를 위해선 App Store에 과금컨텐츠를 등록합니다. 그런데 개발중이니 어플도 등록안되어 있을 텐데 컨텐츠를 등록한다는게 웃기죠.

 iTunes Connect메뉴에 들어가서 어플을 추가합니다. 이때 어플은 바이너리를 올릴 필요없이 가짜 정보를 입력해도 됩니다. 근데 귀찮게 아이콘(512*512)도 올려야 되더군요. 입력 정보는 전부(SNU번호 이외0 나중에 수정 가능하니 대충 입력합니다.

2. App ID등록
 이렇게 등록했으면 이번엔 iTunes Developer Program Portal에 가서 새로운 App ID를 등록합니다. 물론 등록한 ID에 맞게 프로비저닝도 수정할 필요도 생깁니다.

3. 과금컨텐츠 등록
 이제 다시 iTunes Connect에 가면 In App Purchase Content를 등록하는 메뉴가 있습니다. 주체가 되는 어플과 App ID를 선택해주고 Product ID를 입력하고 등록합니다. 역시 실제로 앱스토어에 보이는게 아니니 테스트용으로 입력합니다.

4. 테스트용 ID 등록
 iTunes Connect메뉴중 Account를 관리하는 메뉴가 있고, 그 안에 보면 In app purchase Account를 관리하는게 있습니다. 여기서 테스트 유저를 만듭니다. 모든 정보, 심지어 이메일주소로 대충 입력하면 됩니다.

5. 기존 계정은 사인아웃
 실제 사용중인 계정은 설정-Store에 들어가서 사인아웃해줍니다.

6. 코드 실행
 코드를 실행하면 알림창이 뜨고 다운받을 컨텐츠 정보와 계정등을 입력하는게 뜹니다. 이건 일반적으론 안뜨고 샌드박스 환경에서 테스트할 때만 뜹니다. 이때 계정은 4번에서 만든 계정을 입력합니다.

7. 컨텐츠 다운로드
 모든게 성공하면 response로 성공이 옵니다. 그럼 컨텐츠를 다운로드 하면 OK

이게 일반적인 겁니다. 모두 레퍼런스에도 나와있죠. 그런데 전 6번에서 계정입력창이 뜨지 않고 iTunes Store에 연결할 수 없다는 에러만 나오더군요. 한참 찾았습니다. 결국 Info.plist에 정의한 번들아이디가 2번의 App ID와 완전일치하지않아서 발생했습니다. 대소문자까지 구별해서..ㅠㅠ

테스트라고 해도 모두 등록 및 설정을 확실히 해주어야 합니다.

Posted by 다오나무
iOS2012. 6. 20. 13:37

UIAlertView *alert = [[UIAlertView allocinitWithTitle:@"원하는 정보를 선택\n" 

  message:@"" // 제목

  delegate:self

  cancelButtonTitle:@"Cancel" // 취소버튼

          otherButtonTitles:@"아황산가스(SO2)"@"이산화질소(NO2)"@"일산화탄소(CO)"@"오존(O3)"@"미세먼지(PM10)",nil];


[alert show];

[alert release];


- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex

{

    if (buttonIndex == 0// "아황산가스?버튼

    {

// 처리 내용

NSLog(@"gogogo");

}

}

Posted by 다오나무
iOS2012. 6. 20. 13:26

흔히 경고창으로 사용되는 UIAlertView는 자주는 안 쓰이지만, 사용할 때를 대비해서 커스텀해보도록 하겠습니다.



먼저, UIAlertView 사용법부터 보겠습니다.

UIAlertView *nomalAlert = [[UIAlertView alloc]initWithTitle:@"공지사항" message:@"기본 경고창입니다."delegate:self cancelButtonTitle:@"확인" otherButtonTitles:@"취소"nil];

[nomalAlert show];


initWithTitle : (문자열) 타이틀이 들어갑니다

message : (문자열) 안에 들어가는 내용을 쓰시면 됩니다.

delegate : 기본적으로 self로 연결해줍니다. ( Textfield 등 다른 delegate도 연결가능합니다. )

cancelButtonTitle : 눌렀을 때, 자동으로 AlertView가 없어집니다. 보통 "확인" 버튼으로 사용됩니다.

otherButtonTitles : "확인"버튼 이외의 버튼을 추가적으로 넣을 수 있습니다.

아, 그리고 반드시 show함수를 호출해야 화면에 표시됩니다.


+@ 각 버튼에 대한 이벤트는 <UIAlterDelegate>를 통해 
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex 를 통해 제어할 수 있습니다.

ex) if( buttonIndex == 0) // 첫번째 버튼 이벤트
       else if( buttonIndex == 1) // 두번째 버튼 이벤트

[결과화면]


자 그럼 UIAlterView를 커스텀하기 위해서 xCode에서 Command+n으로 소스를 하나 만듭시다.
이름은 원하시는 대로, 전 customAlert라고 만들었습니다.

기본적으로 NSObject Class를 상속받고 있지만 이걸 UIAlertView로 바꾸어 줍시다.

// UIAlertView 상속

@interface CustomAlertView : UIAlertView


UIAlertView를 하나의 모양으로 정해놓는 방법
- 첫번째 방법의 경우 실질적으로 화면에 표시되는 UIAlertView의 show함수만 재정의 하는 방법으로 가능하며

// Custom하는데 필요한 함수들 Overriding
-(void)show
{

    [super show];

    for (UIView* view in self.subviews) {

        if ([view isKindOfClass:[UIImageView class]]) {  // SubView UIImageView이면 -> 바탕

            UIImage *bg = [UIImage imageNamed:@"bg.png"];

            ((UIImageView*)view).image = [bgresizableImageWithCapInsets:UIEdgeInsetsMake(50,10,10,10)];

        }

        else if ([view isKindOfClass:[UIButton class]]) { // Button type 이면 

            [(UIButton*)view setBackgroundImage:[UIImage imageNamed:@"buttonBG.png"]forState:UIControlStateNormal];

        }

        else if ([view isKindOfClass:[UILabel class]]) {  // UILabel이면.

            l.shadowColor = [UIColor blackColor];

        }

    }


}


이 경우에는 우리가 만든 customAlert를 통해 선언 후에 기본 AlertView와 똑같이 사용해도 바뀜.


-- 결과 --

CustomAlertView *alert = [[CustomAlertView alloc]initWithTitle:@"공지사항" message:@"\n커스텀 경고창입니다." delegate:self cancelButtonTitle:@"확인" otherButtonTitles:@"취소"nil];

[alert show];





[참고]

배경으로 쓰인 이미지 입니다.


버튼 배경으로 쓰인 이미지 입니다.

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. 6. 20. 12:36

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

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

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

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


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

Posted by 다오나무