XCode4 업데이트하고나서 build 디렉토리가 보이지 않길래 찾아봤더니 Preference에 위치 설정이 있네요.

 


 
Place build products in locations specified by targets <= 요거 선택

빌드하시면 프로젝트 폴더에 애타게 찾던 build가 돌아와 있을 겁니다 :-)

'iOS' 카테고리의 다른 글

[iOS] UIImage imageNamed  (1) 2011.08.09
[XCode4] Run "Attaching to YourAppName"  (0) 2011.06.09
[XCode4] build 디렉토리 설정  (0) 2011.05.20
[iOS] Custom Font  (0) 2011.05.19
[iOS] UITableView의 background touch시 이벤트 받기  (0) 2011.04.21
[XCode4] 단축키  (0) 2011.04.01
Posted by 지오아빠^^
TAG build, ios, Xcode4

댓글을 달아 주세요

[iOS] Custom Font

iOS 2011.05.19 11:54
사용자를 만족시키는 앱의 조건 중에는 디자인이 빠질 수 없습니다.
앱을 자주 구매하여 사용하시는 분들 중에는 아마도 필요하지 않은 앱이라도 스크린샷의 디자인만 보고 구매해본 경험이 있을 것입니다.
저만 그런가요^^? 아무튼 저는 디자인에 매료되어서 충동구매한 경험이 제법 있습니다.

또한 디자인에서 빠질 수 없는 것이 아름다운 폰트 입니다.
영어 폰트의 경우엔 iOS에 미리 탑재된 폰트가 있어서 어느 정도 선택의 폭이 있지만 한글의 경우는 애플고딕(맞나요?) 밖에 사용 할 수가 없었습니다. 그나마도 bold 등은 지원을 하지 않았죠. 다행히도 iOS 3.2이상 부터는 앱에 폰트를 내장 시키는 것이 가능해졌습니다.
iOS에서 Custom Font를 사용하는 방법을 정리해 보았습니다.

1. 우선은 사용하고자 하는 폰트를 리소스 폴더로 복사 합니다.
저는 테스트를 위해서 네이버의 나눔고딕 코딩 글꼴을 사용 했습니다.

2. info.plist에 아래 내용을 추가합니다.

 
3. 이제 부터는 그냥 사용 하면 됩니다.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

NSArray *fontFamilies = [UIFont familyNames];

for (NSString *fontFamily in fontFamilies)

NSLog(@"%@", fontFamily);

label.text = @"동해물과";

label.font = [UIFont fontWithName:@"NanumGothicCoding" size:60];

label.textColor = [UIColor blueColor];

[webView loadHTMLString:@"<div style='font-family:NanumGothicCoding;font-size:45pt;color:#0000ff;margin-top:60px'>동해물과</div>" baseURL:nil];

[self.window makeKeyAndVisible];

    return YES;

}



4. 결과는 이렇게!

 


샘플 다운로드

'iOS' 카테고리의 다른 글

[XCode4] Run "Attaching to YourAppName"  (0) 2011.06.09
[XCode4] build 디렉토리 설정  (0) 2011.05.20
[iOS] Custom Font  (0) 2011.05.19
[iOS] UITableView의 background touch시 이벤트 받기  (0) 2011.04.21
[XCode4] 단축키  (0) 2011.04.01
[XCode4] 이런 망할 -ㅅ-;  (0) 2011.03.31
Posted by 지오아빠^^

댓글을 달아 주세요

iOS 앱을 디바이스에 설치 해보기위해서는 디바이스의 UDID가 필요합니다.
디바이스의 UDID를 확인하는 방법을 정리했습니다.

1. iTunes를 실행

2. USB케이블을 이용해서 PC에 디바이스를 연결

3. 첫번째 그림과 같이 아이폰 모양의 버튼을 클릭

4. 우측 화면 디바이스 이미지 오른쪽에 "일련번호"를 클릭

그림을 클릭하면 확대됩니다.

5. "일련번호"가 "UDID"로 변경됩니다.

그림을 클릭하면 확대됩니다.

6. 이 상태에서 Ctrl + C (Command + C) 누르시면 UDID가 복사됩니다.

 복사한 내용을 메일등에 붙여넣기 해서 공유하면됩니다.


Posted by 지오아빠^^
TAG ios, TIP, UDID

댓글을 달아 주세요

 현재 개발중인 앱에서 카카오톡과 유사한 채팅기능이 들어가 있습니다.
사용자가 배경을 Touch했을때 키보드를 숨기는 기능을 개발하기 위해서  UITableView의 Cell이 아닌 UITableView자체를 Touch했는지 알 수 있어야 했습니다. 다른 다양한 방법이 있을 수 있겠지만 아래 방법으로 구현했습니다.


UIControl *control = [[UIControl alloc] initWithFrame:tvTableView.frame];

[control setBackgroundColor:[UIColor clearColor]];

[control addTarget:self action:@selector(onHideKeyboard:) forControlEvents:UIControlEventTouchUpInside];

[tvTableView setBackgroundView:control];

[control release];

 
물론 tableView:didSelectRowAtIndexPath: 에서도 onHideKeyboard:를 호출해 주어야 합니다.
 

'iOS' 카테고리의 다른 글

[XCode4] build 디렉토리 설정  (0) 2011.05.20
[iOS] Custom Font  (0) 2011.05.19
[iOS] UITableView의 background touch시 이벤트 받기  (0) 2011.04.21
[XCode4] 단축키  (0) 2011.04.01
[XCode4] 이런 망할 -ㅅ-;  (0) 2011.03.31
[iOS] 센스쟁이~  (0) 2011.03.23
Posted by 지오아빠^^

댓글을 달아 주세요

[XCode4] 단축키

iOS 2011.04.01 00:42
XCode3과 비교해서 제법 많이 바뀐듯 하여 올려본다.


'iOS' 카테고리의 다른 글

[iOS] Custom Font  (0) 2011.05.19
[iOS] UITableView의 background touch시 이벤트 받기  (0) 2011.04.21
[XCode4] 단축키  (0) 2011.04.01
[XCode4] 이런 망할 -ㅅ-;  (0) 2011.03.31
[iOS] 센스쟁이~  (0) 2011.03.23
[XCode4] UUID mismatch detected with the loaded library  (0) 2011.03.14
Posted by 지오아빠^^

댓글을 달아 주세요

4.61GB -ㅅ-;
몇번이고 다운로드를 시도했었지만 여러가지 이유로 실패하다가 어제 밤에 겨우 받는데 성공했다.
이제 막 설치를 하고, 진행 중이던 프로젝트 소스를 열어서 Build!!

이런 망할.. 이건 뭥미?

*** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeBoolForKey:]: value for key (UIHighlighted) is not a boolean' 

처음 보는 메세지다. 동일한 소스로 XCode3까지는 문제없이 사용하고 있던 터라 당황 스러웠다.
에러가 발생한 라인의 소스 코드는 아래와 같다.

[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil];

 
음.. 이게 뭐!!! 너무 평범한 라인이잖아!!
맘속으로 샤우팅~

에러 메세지를 구글링해본 결과는 단 1건 -_  -;

http://www.iphonedevsdk.com/forum/iphone-sdk-development/62286-ios-4-1-uihighlighted-crazy-crash.html

원인을 파악 할 수 있을 만큼의 시원스러운 답변은 못되지만, 어찌되었던 Interface Builder상에서 Highlited속성을 체크 해제했다.
그리곤 Build 성공!! 잘돌아 갔다.

조...좋..았어..  그런데 원인은?
단순한 XCode4의 버그???
대규모 성형수술과 단축키, 사용성이 변한거.. 그..그래.. 내..내가 쿨하게 다 받아줄께..
하지만 이런건 아니잖아..?

XCode4의 첫인상... 드럽다 -ㅅ-;
앞으로 이녀석과 친해지는건 순탄치 못할 것 같다. 

'iOS' 카테고리의 다른 글

[iOS] UITableView의 background touch시 이벤트 받기  (0) 2011.04.21
[XCode4] 단축키  (0) 2011.04.01
[XCode4] 이런 망할 -ㅅ-;  (0) 2011.03.31
[iOS] 센스쟁이~  (0) 2011.03.23
[XCode4] UUID mismatch detected with the loaded library  (0) 2011.03.14
[iOS] #error 전처리기  (0) 2011.03.09
Posted by 지오아빠^^
TAG debug, ios, xcode

댓글을 달아 주세요

Java로 APNS 및 Feedback

Java 2011.03.24 17:04
지난번 포스팅에서 Java로 APNS 요청을 하는 방법을 다뤘었다.
이 포스팅은 지난번 포스팅의 연장선상에 있다.

 만약 APNS 요청을 했는데 사용자가 앱을 지우거나 하여 APNS를 보낼 수 없는 상태라면 어떻게 된까?
APNS 서버는 APNS Feedback 서버에 deviceToken을 등록하여 Service Provider들이 이를 확인할 수 있도록 하고 있다.

지난번 포스팅의 코드에 추가했다.

import javapns.back.PushNotificationManager;

import javapns.back.FeedbackServiceManager;

import javapns.back.SSLConnectionHelper;

import javapns.data.Device;

import javapns.data.PayLoad;


import java.util.*;


public class JavapnsTest {

public static int RUN_MODE_DEVELOPMENT = 1;

public static int RUN_MODE_PRODUCTION = 2;

public static String APNS_DEVELOPMENT_GATEWAY = "gateway.sandbox.push.apple.com";

public static String APNS_PRODUCTION_GATEWAY = "gateway.push.apple.com";

public static String APNS_DEVELOPMENT_FEEDBACK = "feedback.sandbox.push.apple.com";

public static String APNS_PRODUCTION_FEEDBACK = "feedback.push.apple.com";

// Change Here.

public static String APNS_DEVELOPMENT_KEY = "./keystore/your_apns_development_key.p12";

public static String APNS_PRODUCTION_KEY = "./keystore/your_production_key.p12";

public static String APNS_DEVELOPMENT_KEY_PASSWORD = "YOUR DEVELOPMENT PASSWORD";

public static String APNS_PRODUCTION_KEY_PASSWORD = "YOUR DEVELOPMENT PASSWORD";

public void sendApns(int runMode, String deviceToken, String alertMessage, int badgeCount, String soundFile) throws Exception {

try {

PayLoad payLoad = new PayLoad();

payLoad.addAlert(alertMessage);

payLoad.addBadge(badgeCount);

payLoad.addSound(soundFile);


PushNotificationManager pushManager = PushNotificationManager.getInstance();

pushManager.addDevice("iPhone", deviceToken);


int port = 2195;

String host = null;

String certificatePath = null;

String certificatePassword = null;

if (runMode == RUN_MODE_DEVELOPMENT) {

host = APNS_DEVELOPMENT_GATEWAY;

certificatePath = APNS_DEVELOPMENT_KEY;

certificatePassword = APNS_DEVELOPMENT_KEY_PASSWORD;

} else if (runMode == RUN_MODE_PRODUCTION) {

host = APNS_PRODUCTION_GATEWAY;

certificatePath = APNS_PRODUCTION_KEY;

certificatePassword = APNS_PRODUCTION_KEY_PASSWORD;

}

pushManager.initializeConnection(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);


Device client = pushManager.getDevice("iPhone");

pushManager.sendNotification(client, payLoad);

pushManager.stopConnection();


pushManager.removeDevice("iPhone");

} catch (Exception ex) {

ex.printStackTrace(); 

}

}

public ArrayList<String> sendFeedback(int runMode) {

ArrayList<String> deviceTokens = new ArrayList<String> ();

try {

int port = 2196;

String host = null;

String certificatePath = null;

String certificatePassword = null;

if (runMode == RUN_MODE_DEVELOPMENT) {

host = APNS_DEVELOPMENT_FEEDBACK;

certificatePath = APNS_DEVELOPMENT_KEY;

certificatePassword = APNS_DEVELOPMENT_KEY_PASSWORD;

} else if (runMode == RUN_MODE_PRODUCTION) {

host = APNS_PRODUCTION_FEEDBACK;

certificatePath = APNS_PRODUCTION_KEY;

certificatePassword = APNS_PRODUCTION_KEY_PASSWORD;

}

FeedbackServiceManager feedbackManager = FeedbackServiceManager.getInstance();

LinkedList<Device> devices = feedbackManager.getDevices(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);

if (devices.size() > 0) {

ListIterator<Device> itr = devices.listIterator();

while (itr.hasNext()) {

Device device = itr.next();

deviceTokens.add(device.getToken());

}

}

} catch (Exception ex) {

ex.printStackTrace();

}

return deviceTokens;

}

public static void main(String... args) throws Exception{

JavapnsTest apns = new JavapnsTest();

apns.sendApns(

RUN_MODE_DEVELOPMENT,

"deviceToken",

"Test~",

9999,

"default");

ArrayList<String> deviceTokens = apns.sendFeedback(RUN_MODE_DEVELOPMENT);

for (String deviceToken : deviceTokens) {

System.out.println(deviceToken);

}

}

}


 
sendFeedback을 테스트 해보기 위해서는 아래의 절차를 따라야 한다.

1. 앱을 설치한다.
2. 앱에서 APNS 사용하도록 등록한다.
3. 앱을 삭제한다.
4. 앱에 APNS 요청 : 이때 실패가 되면서 APNS서버는 APNS Feedback 서버에 요청했던 deviceToken값을 등록한다.
5. APNS Feedback 서버에서 deviceToken을 조회하여 해당 deviceToken에 더이상 APNS요청을 하지 않도록 설정한다. 

Feedback기능을 특정 APNS요청 전후로 메세지 송신여부를 알아올 수 있는 편리한 기능으로 오해하고 있었다.
인생 장밋빛 라이더스~ 흠냐.. 

Feedback 을 주기적으로 해서 받아온 deviceToken 들을 APNS요청 대상에서 제외시켜주자.
이것도 그린 컴퓨팅인가? 

 

'Java' 카테고리의 다른 글

Java7 Certificates does not conform to algorithm constraints  (0) 2014.03.22
Java APNS 인증키 생성  (0) 2011.05.31
Java로 APNS 및 Feedback  (0) 2011.03.24
Java로 애플 푸시 알림 보내기  (1) 2011.03.23
Posted by 지오아빠^^

댓글을 달아 주세요

[iOS] 센스쟁이~

iOS 2011.03.23 01:22

NSLog(@"%@", [@"Y" boolValue] ? @"YES" : @"NO"); // print YES

NSLog(@"%@", [@"N" boolValue] ? @"YES" : @"NO"); // print NO


나이샷~

'iOS' 카테고리의 다른 글

[XCode4] 단축키  (0) 2011.04.01
[XCode4] 이런 망할 -ㅅ-;  (0) 2011.03.31
[iOS] 센스쟁이~  (0) 2011.03.23
[XCode4] UUID mismatch detected with the loaded library  (0) 2011.03.14
[iOS] #error 전처리기  (0) 2011.03.09
[iOS] APNS 추가시에 동의창이 뜨지 않는 경우  (0) 2011.03.09
Posted by 지오아빠^^
TAG ios

댓글을 달아 주세요

지하 깊숙한곳부터 삽질해서 만들지는 않았다.
언제나 그렇듯 개발을 시작하기 전에는 해결하고자 하는 문제에대한 손쉬운 해결책을 검색하게 된다.
눈앞에있는 문제의 본질이 원리를 깨닫고 더 나아가는 것이 아니라면 나는 언제나 오픈소스를 활용한다.
그렇게 세이브한 시간을 좀더 재미있는 일에 투자한다. 각설하고!

http://code.google.com/p/javapns 에 가면 Java로 APNS를 보낼 수 있는  오픈소스가 있다.
예제 코드가 잘되어 있고 사용도 쉬워서 javapns를 이용하기로 결정했다.
아래는 간단히 Wrapping한 코드이다.

import javapns.back.PushNotificationManager;

import javapns.back.SSLConnectionHelper;

import javapns.data.Device;

import javapns.data.PayLoad;


public class JavapnsTest {

public static int RUN_MODE_DEVELOPMENT = 1;

public static int RUN_MODE_PRODUCTION = 2;

public void sendApns(int runMode, String deviceToken, String alertMessage, int badgeCount, String soundFile) throws Exception {

try {

PayLoad payLoad = new PayLoad();

payLoad.addAlert(alertMessage);

payLoad.addBadge(badgeCount);

payLoad.addSound(soundFile);


PushNotificationManager pushManager = PushNotificationManager.getInstance();

pushManager.addDevice("iPhone", deviceToken);


String host = null;

String certificatePath = null;

if (runMode == RUN_MODE_DEVELOPMENT) {

host = "gateway.sandbox.push.apple.com";

certificatePath = "./keystore/your_apns_development_key.p12";

} else if (runMode == RUN_MODE_PRODUCTION) {

host = "gateway.push.apple.com";

certificatePath = "./keystore/your_apns_production_key.p12";

}

int port = 2195;

String certificatePassword = "Your password";

pushManager.initializeConnection(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);


Device client = pushManager.getDevice("iPhone");

pushManager.sendNotification(client, payLoad);

pushManager.stopConnection();


pushManager.removeDevice("iPhone");

} catch (Exception ex) {

ex.printStackTrace(); 

}

}

public static void main(String... args) throws Exception{

JavapnsTest apns = new JavapnsTest();

apns.sendApns(

RUN_MODE_DEVELOPMENT,

"5c0de8bdc3414816a0eb728751f76be119e9a705e43cdbf0ed16c1772a63218a",

"Test삼~",

9999,

"default");

}

}




정말 간단하다 -ㅅ-; 굳이 설명할 가치도 못느끼겠다.
간단하게 파라미터만 설명 해보자.

1. runMode : APNS는 Development용과 Production용을 구별하고 있다. 그것에 따라서 사용해야하는 키와 게이트웨이가 다르다.

2. deviceToken : 특정 디바이스에 특정 앱에 부여되는 APNS를 위한 고유값 정도로 알아두자. 이값은 유니크하지만 불변의 값은 아니다. 64자리의 문자열 값이다. 앱에서 아래와 같은 방법으로 얻을 수 있다.

[[UIApplication sharedApplication] registerForRemoteNotificationTypes:

(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];

....

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {

#if !TARGET_IPHONE_SIMULATOR

// ' ', '<', '>' 제거

    NSString *deviceToken = [[[[devToken descriptionstringByReplacingOccurrencesOfString:@"<" withString:@""stringByReplacingOccurrencesOfString:@">" withString:@""stringByReplacingOccurrencesOfString:@" " withString:@""];

NSLog(@"deviceToken : %@", deviceToken);

#endif


3. alertMessage : 노티를 받았을 때 뜨는 알럿창의 메세지다.

4. badgeCount : 스프링보드 아이콘에 붙는 빨콩안의 숫자값이다.

5. soundFile : 노티를 받았을 때 재생되는 사운드 파일명이다. 자세한 내용은 깔끔하게 까먹었다.


APNS에 Custom key-value를 추가 할 수 있지만, 이런 부분까지는 각자의 몫으로 하자!

APNS 자체에대해서 궁금하다면 Apple의 문서를 참고하자. 
p12파일을 만드는 방법이 궁금하다면 여기를 참고하자.




'Java' 카테고리의 다른 글

Java7 Certificates does not conform to algorithm constraints  (0) 2014.03.22
Java APNS 인증키 생성  (0) 2011.05.31
Java로 APNS 및 Feedback  (0) 2011.03.24
Java로 애플 푸시 알림 보내기  (1) 2011.03.23
Posted by 지오아빠^^
TAG APNS, ios, java

댓글을 달아 주세요

  1. cara 2012.05.29 16:51  댓글주소  수정/삭제  댓글쓰기

    감사합니다.. 큰 도움이 되었습니다.. 항상 복 많이 받으세요~

iOS 4.3 업데이트 이후에 XCode에서 처음보는 에러 메세지가 찍히면서 앱이 Run되지 않았다. (Build & Run)

warning: UUID mismatch detected with the loaded library - on disk is: warning: UUID mismatch detected with the loaded library - on disk is: warning: UUID mismatch detected with the loaded library - on disk is: warning: UUID mismatch detected with the loaded library - on disk is: warning: UUID mismatch detected with the loaded library - on disk is: warning: UUID mismatch detected with the loaded library - on disk is: ..............

요런 문구가 반복적으로 주욱~
정확한 원인은 알지 못했지만 해결 방법은 검색을 통해서 알게됐다.
아래의 순서로 따라하면 된다.

Step1. XCode를 닫는다.
Step2. $project/build 폴더 안에 들어있는 모든 파일과 폴더를 삭제한다.
Step3. /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.3 폴더를 삭제한다.
Step4. XCode를 재시작한다.
Step5. Organizer를 열면 Unknown iOS detected 가 뜨면서 디버깅에 필요한 정보를 수집한다고 나온다. Collect 해준다.
Step6. Build & Run

이렇게 하면 정상적으로 테스트되는 것을 확인할 수 있다.
Posted by 지오아빠^^
TAG ios, xcode

댓글을 달아 주세요