iOS2012. 8. 22. 11:46

http://sonnyparlin.com/2011/12/pulltorefresh-ios-5-and-arc-tutorial/

Posted by 다오나무
iOS2012. 8. 22. 09:56

아이폰이나 안드로이드 프로젝트를 하다보면 처음에 가장 신경쓰이는 부분이 UI구성입니다.

디자인에 따라 배경이나 버튼 이미지, 간격등을 고려해서 구성해야 되는데 책이나 기본 강좌에서는 이런 내용을 잘 다루지 않죠.
기획안에 따라서 기능적으로는 UINavigationController를 사용해야 되는데 화면의 특성에 따라서 UINavigationController를 숨기거나 수정해야되는 경우가 생깁니다. 

UINavigationController에서 배경색을 바꾸고 배경이미지를 넣고 상황에 따라 타이틀을 바꾸고 하는 등의 작업을 간단히 정리해 보도록 하겠습니다.

1. 코드를 이용해 UINavigationController 만들기
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {     
 RootViewController * rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];

 UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];

 [self.window addSubview:navigationController.view];
 [self.window makeKeyAndVisible];
 return YES;
}
이것은 코드를 통해 만들수 있다는 한가지 예일 뿐이고 실제 interface builder를 이용해서 만드셔도 상관 없죠.
 
2.Title 바꾸기
- (void)viewDidLoad 
{
    [super viewDidLoad];
    self.title = @"My Title";
}
화면별로 각각의 ViewController에 따라서 Title을 변경해야 될 떄 사용 되겠죠.

3.Navigation Bar 숨기기 & 보이기
- (void)viewDidLoad 
{
    [super viewDidLoad];
     self.title = @"My Title";
     self.navigationController.navigationBarHidden = YES; //YES : 숨기기, NO : 보이기
}
위 코드는 Navigation Bar를 숨기는 코드 입니다. 이처럼 ViewController에 따라서 보여줄수도 있고 숨길수 있습니다.
다시 보이게 하려면 self.navigationController.navigationBarHidden값을 NO로 하시면 되겠습니다.

4. Navigation Bar 배경색 바꾸기 (Background Color) 
- (void)viewDidLoad 
{
    [super viewDidLoad];
    self.title = @"My Title";
    self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:255.0/255 
                                                                                  green:10.0/255 blue:100.0/255 alpha:1];

}

5. Navigation Bar Style 바꾸기
- (void)viewDidLoad 
{
   super viewDidLoad];
   self.title = @"My Title";
   self.navigationController.navigationBar.barStyle = UIBarStyleBlack; //스타일 적용
   self.navigationController.navigationBar.translucent = YES; // 반투명 효과 주기
}
스타일에는 기본적으로 UIBarStyleBlack, UIBarStyleBlackOpaque, UIBarStyleBlackTranslucent, UIBarStyleDefault이 있죠.

6. Navigation Bar 배경이미지 넣기 (Background image)
@implementation UINavigationBar (UINavigationBarCategory)
- (void)drawRect:(CGRect)rect
{
   UIImage *bgImage = [UIImage imageNamed:@"background.png"];
   [bgImage drawInRect:rect];
}
@end
UInavigationBar 서브클래스를 만들어서 구현합니다.

7. Navigation Bar Back 버튼의 Text 변경 하기
- (void)viewDidLoad 
{
    [super viewDidLoad];
    self.title = @"My title";
    self.navigationController.navigationBar.backItem.title = @"뒤로가기";
}
본래 "Back"이라는 Text가 들어가는데 "뒤로가기" 라고 바꿔 주었습니다.
위 코드는 상황에 따라 적용되지 않을 수 있습니다. 
가령 UITabbarController와 UINavigationController를 같이 사용하면서 pushViewController를 이용해 뷰를 이동할 때 안되더군요.

이때는 다음과 같이 해결 합니다.
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
                                    initWithTitle: @"Back"
                                    style: UIBarButtonItemStyleBordered
                                    target:nil action:nil];
[[self navigationItem] setBackBarButtonItem: backButton];

UINavigationController *homeNav = self.navigationController;
LoginView * loginView = [[LoginView alloc] initWithNibName:@"LoginView" bundle:nil];
[homeNav pushViewController:loginView animated:YES];

위 코드는 이동하고자 하는 뷰(LoginView)를 push하는 뷰 컨트롤러에서 백버튼을 재설정한 후에 뷰를 push하는 방법 입니다.
즉 뷰를 이동하고 나서 처리하는 것이 아니라 이동하기 전에 백버튼을 설정하고 이동하는 처리 입니다.

여기서 하나 더 알아봅시다.
NavigationController에서 화면 전환시 이전 화면으로 이동하고자 할 때 바로 이전 화면이 아닌 자신이 원하는 이전 화면으로 이동하고 싶을 때 처리는 어떻게 할까요. 

다음을 보시죠
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0] animated:YES];
위처럼 objectAtIndex값을 설정해서 이전의 원하는 컨트롤러로 이동할 수 있습니다.

8.Navigation Bar 오른쪽의 버튼 아이템 추가하기
- (void)viewDidLoad 
{
    [super viewDidLoad];
    self.title = @"My Title";
    UIBarButtonItem *loginButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Log in" 
                                                            style:UIBarButtonItemStylePlain target:self  

                                                            action:@selecter(ActLogin)];
    self.navigationItem.rightBarButtonItem = loginButtonItem;
    [loginButtonItem release];
}

//버튼을 눌렀을 때 이벤트 처리
-(IBAction) ActLogin:(id)sender
{
     NSLog(@"Log-in Action");
}
Navigation Bar 오른쪽 영역에 버튼을 추가하는 코드 입니다. 여기서는 버튼을 눌렀을 때 이벤트 메소드 ActLotin 메소드도 정의 했습니다.
버튼의 종류나 여러가지 옵션은 상황에 맞게 처리하시면 되겠습니다.

일단 NavigationController 커스터마이징은 여기까지 정리해 놓겠습니다. 
추가적으로 필요한 내용은 주기적으로 업데이트 하겠습니다.

Posted by 다오나무
iOS2012. 8. 20. 17:11

copyright www.irontop.com All rights reserved.

This Example show to you that communication with iPhone App, iPhone UIWebView each other 
There is two ways for commucation.
One is the [webView:shouldStartLoadWithRequest:navigationType:]UIWebViewDelegate 
The other is the [stringByEvaluatingJavaScriptFromString:] WebView

You can use "shouldStartLoadWithRequest" to commucate UIWebView 2 APP
You can use "stringByEvaluatingJavaScriptFromString" to commucate APP 2 UIWebView 

유관업체에서 앱과 웹뷰간의 통신 예제를 작성해달라고 해서.
간단히 만들어 보았다.

웹뷰에는 자바스크립트의 머리를 깎아줄 수 있는 api를 제공하기 때문에(eval)
자바스크립트를 잘 이해하고 있다면, 팝업을 포함하여 거의 모든 기능을 훼이크로 구현이 가능하다.

아래는 주요 코드 부분이다.

APP에서 WebView로 값을 보내는 부분

 71 (IBAction)toWeb:(id)sender {
 72     NSString *strScript = [NSString stringWithFormat:
 73                            @"var fromApp = document.getElementById('fromApp');\
 74                            fromApp.value = '%@';"self.txtToWebView.text];
 75     [webView stringByEvaluatingJavaScriptFromString:strScript];
 76 }


input 요소를 id로 찾아서 값을 세팅하는 자바스크립트를 생성한 후에
webView에 밀어 넣고 있다.

WebView로부터 APP로 보내지는 값을 획득하는 부분
 83 (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
 84     
 85     NSString *strUrl = [[request URL] absoluteString];
 86     if ([strUrl hasPrefix:@"toAPP://"]) {
 87         NSString *strRequest = [[strUrl componentsSeparatedByString:@"://"] objectAtIndex:1];
 88         NSArray *arrRequest = [strRequest componentsSeparatedByString:@"?"];
 89         NSString *strCmd = [arrRequest objectAtIndex:0];
 90 
 91         if (YES == [@"toAppCmd" isEqualToString:strCmd]) {
 92             // code to set Your Application communication
 93             self.txtFromWebView.text = [arrRequest objectAtIndex:1];
 94         }
 95         
 96         // toApp protocol do not StartLoad
 97         return NO;
 98     }
 99     
100     // other protocol do StartLoad
101     return YES;
102 }


form GET Action을 사용하였고,
action-url을 "toApp://toAppCmd?toApp=abc" 형식이 되도록 하였다.
즉, 로드할 url을 가로채서 "toAPP" 로 시작하는 경우에는 NO 를 리턴하여 실제로 로드되지 않도록 하고,
url을 파싱하여 toApp 의 값을 획득하도록 하였다.
여기서 strCmd 를 명령으로 사용하는 예제이므로 toAppCmd 를 다른 값으로 바꾸고,
구분하여 처리하는 것으로 처리할 종류(명령)을 구분할 수 있는 구조로 확장도 가능하다.

자세하는 것은 첨부된 예제 파일을 참조하자.~~

Posted by 다오나무
iOS2012. 8. 20. 13:21

1. 밖에서 안으로
당연한 이야기지만
[webView stringByEvaluatingJavaScriptFromString:@"alert('aa')"];

이런게 가능하다.
외부(ex:push notification)로부터 해당 웹뷰 안에다가 Javascript를 실행하게 할 수 있다.
2. 안에서 밖으로
document.location = "iOS:checkParams:" + param1;
javascript 에서 custom protocol (여기선 iOS라는 이름)
마찬가지로

-(BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

NSString *URL = [[request URLabsoluteString];

NSLog(@"requested URL :%@", URL);

// URL 특정 문자열과 매치하면

if ([URL isEqualToString:@"iOS:checkParams:"]) {

// 처리

return NO;

}

return YES;

}

커스텀 프로토콜을 지정할 수 있다. 말이 거창해서 커스텀 프로토콜이지 그냥 문자열 지지는 것으로 보면 쉽다.

Posted by 다오나무
iOS2012. 8. 20. 13:10

모달 뷰 (Modal View) 란?

모달 뷰(Modal View)란 iOS(iPhoneOS) 에서 제공하는 여러 개의 뷰를 전환하기 위한 아주 기본적인 뷰 관리 기법 중 하나입니다. 특히 모달 뷰 컨트롤러(Modal View Controller)는 현재 어플리케이션 흐름을 잠시 중단하고 사용자에게 무언가를 입력을 받게 하거나 표시한 후에 다시 원래의 흐름으로 되돌아가도록 흐름을 변경할 때 사용됩니다. 그림을 보며 설명하겠습니다. 아래 표시된 All Calendar / Add Event 간의 관계가 전형적인 모달 뷰 관계로 볼 수 있습니다.



 

일정을 하나 추가하기 위해서는 다음과 같은 절차가 필요합니다.

  • Calender 화면에서 추가하기 버튼을 터치하여 Add Event 화면을 띄웁니다.
  • Add Event 화면에서 일정을 입력합니다.
  • Done 버튼을 터치하여 Add Event 를 종료시킵니다.
  • Calender 화면으로 되돌아 옵니다.


위와 같이 사용자가 일정을 관리하다가  현재의 흐름을 잠시 중단하고 원래의 흐름으로 다시 되돌아 오도록 애플리케이션의 흐름을 구현하고자 할때 모달 뷰를 사용하는 것입니다. 참고로 모달 뷰 모델에서는 호출자(Caller)와 피호출자(Callee)간의 부모(Parent)와 자식(Child) 관계가 생깁니다.

모달 뷰 컨트롤러 띄우기
현재 애플리케이션 흐름에서 모달 뷰 컨트롤러를 띄우기 위해서는 부모 뷰의 인터랙션 내 아래와 같이 구현합니다. 

- (IBAction) buttonPressed:(id)sender
  {
      
SecondViewController *viewController = [[SecondViewController alloc] init];    // 새롭게 띄울 뷰 컨트롤러 생성
      [self presentModalViewController:viewController animated:YES];  // 새로운 뷰 컨트롤러를 모달로 표시
  }
 


모달 뷰 컨트롤러 닫기
모달 뷰를 닫고 원래의 흐름으로 되돌아 가기 위해서는 모달 뷰의 인터랙션 내 아래와 같이 구현합니다.

- (IBAction) buttonPressed:(id)sender
  {
      
[self dismissModalViewControllerAnimated:YES];  // 현재 모달로 띄워진 뷰 컨트롤러를 닫음
  
}



모달 뷰 컨트롤러 전환시 효과주기
iOS에서는 기본적으로 모달 뷰를 전환하기 위한 기본적인 전환 애니메이션을 제공합니다.
 모달 뷰를 전환하기 위한 애니메이션 효과는 setModalTransitionStyle을 이용하여 아래와 같이 값을 설정하면 전환시 효과가 적용됩니다.

  -(IBAction)buttonPressed:(id)sender
   {
      SecondViewController *viewController = [[SecondViewController alloc] init];
      [viewController setModalTransitionStyle:UIModalTransitionStylePartialCurl];
      [self presentModalViewController:viewController animated:YES];
   }

  // UIModalTransitionStyleCoverVertical : 모달 뷰가 아래서 위로 덮으며 전환됩니다. (기본값)

  // 
UIModalTransitionStyleFlipHorizontal : 앞면의 부모 뷰가 회전되어 뒷면의 모달 뷰로 전환됩니다
  // UIModalTransitionStyleCrossDissolve : 부모 뷰가 서서히 사라짐과 동시에 모달 뷰로 전환됩니다.

  // UIModalTransitionStylePartialCurl : 부모 뷰가 종이처럼 휘어지며 모달 뷰로 전환됩니다. 


실행화면 - UIModalTransitionPartialCurl

















Posted by 다오나무
iOS2012. 8. 1. 08:21

UDID 대체 방법 -> MAC 어드레스 얻기

올해 3월이었죠. 애플이 개인정보 유출을 막고자 UDID를 쓰는 앱에 대해 단계적으로 심사하겠다고 했습니다.

지금은 IOS 5.0 이상에서는 UDID를 추출하는

NSString *udid = [[UIDevice currentDeviceuniqueIdentifier];


메소드를 쓰면 안된다고 하네요. 


그래서 나온 대안 중, MAC 어드레스 값을 추출하는 방법입니다.


일종의 PC의 랜카드 고유번호(?)라고 하는데 아이폰에서는 네트워크 접속 이더넷카드 시리얼 넘버라고 보시면 되요.


구글에서 떠도는 소스는 3G와 WI-FI 환경에서 값이 다르게 추출된다고 하네요.


형식은 FF:FF:FF:FF:FF:FF 이런식으로 나와요

그 문제를 해결한 소스입니다. 저도 어디서 구한 소스구요 ㅋ

개발자님들 대단하다.


구현 방법입니다.



Macaddress.h


char*  getMacAddress(char* macAddress, char* ifName);


Macaddress.c


#include <sys/types.h>

#include <stdio.h>

#include <string.h>

#include <sys/socket.h>

#include <net/if_dl.h>

#include <ifaddrs.h>


char*  getMacAddress(char* macAddress, char* ifName) {

    

    int  success;

    struct ifaddrs * addrs;

    struct ifaddrs * cursor;

    const struct sockaddr_dl * dlAddr;

    const unsigned char* base;

    int i;

    

    success = getifaddrs(&addrs) == 0;

    if (success) {

        cursor = addrs;

        while (cursor != 0) {

            if ( (cursor->ifa_addr->sa_family == AF_LINK)

                && (((const struct sockaddr_dl *) cursor->ifa_addr)->sdl_type == 0x06) && strcmp(ifName,  cursor->ifa_name)==0 ) {

                dlAddr = (const struct sockaddr_dl *) cursor->ifa_addr;

                base = (const unsigned char*) &dlAddr->sdl_data[dlAddr->sdl_nlen];

                strcpy(macAddress, ""); 

                for (i = 0; i < dlAddr->sdl_alen; i++) {

                    if (i != 0) {

                        strcat(macAddress, ":");

                    }

                    char partialAddr[3];

                    sprintf(partialAddr, "%02X", base[i]);

                    strcat(macAddress, partialAddr);

                    

                }

            }

            cursor = cursor->ifa_next;

        }

        

        freeifaddrs(addrs);

    }    

    return macAddress;

}



갖다 쓰실 때는 이런식으로 


#import "MacAddress.h"


char* macAddressString= (char*)malloc(18);

    NSString *macAddress= [[NSString allocinitWithCString:getMacAddress(macAddressString,"en0")

                                                   encoding:NSMacOSRomanStringEncoding];

    NSLog(@" %@ ", macAddress);


 

Posted by 다오나무
iOS2012. 7. 10. 18:42

어제 클리앙 모두의 공원 게시판은 NSString 관련 메소드만 가지고 파싱을 해 보았는데요. 코드도 꽤 길어지고 굉장히 무식한 방법이었습니다. 어제 포스팅 마지막에 언급했던대로 좀 더 편한 방법들을 살펴보려고 하는데요. hpple라는 API가 있습니다. 나온지도 오래되었고(업데이트 된지도...), 제가 원래 외부API를 잘 사용안하는데요. 뭐 대체제가 없다보니 써 보겠습니다.


일단 아래 주소에서 받으실 수 있구요.

https://github.com/topfunky/hpple


프로젝트에 6개의 파일을 포함시켜 주시면 됩니다.

TFHpple.h

TFHpple.m

TFHppleElement.h

TFHppleElement.m

XPathQuery.h

XPathQuery.m


그리고 환경설정을 두개 해 주셔야 하는데 PROJECT환경설정에서(Build Settings) All을 누르시면 여러가지 설정들을 찾아보실 수 있는데요. 설정해야될 것은 아래와 같습니다.

Header Search Paths  : ${SDKROOT}/usr/include/libxml2

Other Linker Flags : -lxml2


그리고 마지막으로 html파싱이 이루어지는 프로젝트에 TFHpple.h를 import 시켜주시면 설정은 다 끝났습니다.


프로젝트에 포함시킨 소스파일들을 한번 살펴보면 실제 파싱은 XPathQuery에서 이루어 지고 있음을 확인할 수 있습니다. 다른 소스들도 복잡하지 않으니 한번 살펴보시면 좋을것 같고요.


어제 클리앙 모공을 파싱했던 부분 기억나시나요. 가져온 데이터가 게시물제목, 링크, 아이디, 조회수, 글쓴시간이었는데요. 실제 데이터 파싱하는 부분만 구현 해 보겠습니다.


// 클리앙 모공

NSString * path = @"";

NSError * error;

NSString * stringFromURL = [[NSString allocinitWithContentsOfURL:[NSURLURLWithString:@"http://clien.career.co.kr/cs2/bbs/board.php?bo_table=park"encoding:NSUTF8StringEncodingerror:&error];

    

if(stringFromURL == nil)

{

    NSLog(@"Error reading URL at %@\n%@", path, [error localizedFailureReason]);

}

윗 부분은 어제 했던 부분과 동일하고요.


NSData * data = [stringFromURL dataUsingEncoding:NSUnicodeStringEncoding];

        

// Create parser

TFHpple * xpathParser = [[TFHpple allocinitWithHTMLData:data];

        

// 타이틀 & URL

NSArray * elements = [xpathParser searchWithXPathQuery:@"//tr//td[2]//a"];

for(int i = 0 ; i < [elements count] ; i++)

{

    NSLog(@"%@", [[elements objectAtIndex:i] content]);                             // 타이틀

    NSLog(@"%@", [[[elements objectAtIndex:i] attributes] valueForKey:@"href"]);    // URL

}

타이틀과 URL을 파싱해서 가져오는 방법입니다. 오렌지색으로 하이라이트 된 부분과 일치하는 형태를 찾아서 elements에 배열형태로 넣는 방법인데요. tr태그 내부에 td태그가 2번 나온 뒤 a태그가 나오는 형태를 찾으라는 말인데요.


<tr class="mytr">

<td>10816621</td>

<td class="post_subject">&nbsp;&nbsp;<a href='../bbs/board.php?bo_table=park&wr_id=10816621' >[차단공시]삭제요청에 의한 차단공시</a></td>

<td class="post_name"><img src='../data/member/ci/cipher.gif' width='54' height='16' align='absmiddle' border='0'></td>

<td><span title="2012-02-15 17:25:24">17:25</a></td>

<td>1</td>

</tr>

<tr class="mytr">

<td>10816618</td>

<td class="post_subject">&nbsp;&nbsp;<a href='../bbs/board.php?bo_table=park&wr_id=10816618' >초고도 근시인데 라섹했습니다</a></td>

<td class="post_name"><img src='../data/member/hi/hikari.gif' width='60' height='16' align='absmiddle' border='0'></td>

<td><span title="2012-02-15 17:25:11">17:25</a></td>

<td>10</td>

</tr>

<tr class="mytr">

<td>10816613</td>

<td class="post_subject">&nbsp;&nbsp;<a href='../bbs/board.php?bo_table=park&wr_id=10816613' >암스텔담에선 자전거 뒤에 타려면  정도 운동 신경은 가져야...</a></td>

<td class="post_name"><span class='member'>Guylian</span></td>

<td><span title="2012-02-15 17:25:01">17:25</a></td>

<td>36</td>

</tr>

위의 html 중 색칠해진 부분들이 배열에 들어가게 됩니다. 여기서 한가지 보셔야 할 것은..


content의 경우 해당 태그가 열리고 닫힌 사이의 값, 즉 아래에서 색칠된 부분입니다.

<tr class="mytr">

<td>10816618</td>

<td class="post_subject">&nbsp;&nbsp;<a href='../bbs/board.php?bo_table=park&wr_id=10816618' >초고도 근시인데 라섹했습니다</a>

<a 태그가 열리고, </a>로 닫힌 사이의 값입니다.


attribute의 경우 해당 태그 내부에서 key=value 형태로 저장된 값입니다. NSDictionary형의 값이기 때문에 태그의 key가 딕셔너리의 키가 되고 태그의 value가 딕셔너리의 value가 됩니다.

<tr class="mytr">

<td>10816618</td>

<td class="post_subject">&nbsp;&nbsp;<a href='../bbs/board.php?bo_table=park&wr_id=10816618' >초고도 근시인데 라섹했습니다</a>

여기에서는 오렌지색이 key가 되고  청록색이 value가 되기 때문에 

[[[elements objectAtIndex:i] attributes] valueForKey:@"href"]


이런식으로 value를 가져올 수 있었습니다.


그럼 아이디를 가져오는 방법을 살펴볼텐데요. 아이디의 경우 두가지 형태가 있기 때문에 조금 복잡합니다. 일단 html 로 아이디가 스트링인 경우와 아이디가 이미지인 경우를 살펴보면요.

<tr class="mytr">

<td>10816618</td>

<td class="post_subject">&nbsp;&nbsp;<a href='../bbs/board.php?bo_table=park&wr_id=10816618' >초고도 근시인데 라섹했습니다</a></td>

<td class="post_name"><img src='../data/member/hi/hikari.gif' width='60' height='16' align='absmiddle' border='0'></td>

<td><span title="2012-02-15 17:25:11">17:25</a></td>

<td>10</td>

</tr>


<tr class="mytr">

<td>10816613</td>

<td class="post_subject">&nbsp;&nbsp;<a href='../bbs/board.php?bo_table=park&wr_id=10816613' >암스텔담에선 자전거 뒤에 타려면  정도 운동 신경은 가져야...</a></td>

<td class="post_name"><span class='member'>Guylian</span></td>

<td><span title="2012-02-15 17:25:01">17:25</a></td>

<td>36</td>

</tr>

3번째 td의 다음 element가 달라지는 것을 알 수 있는데요. 몇가지 방법이 떠오르긴 합니다만 직관적으로 스트링을 가져와서 nil이면 이미지로 판단해서 처리하는 방법으로 진행하겠습니다.

// 아이디

elements = [xpathParser searchWithXPathQuery:@"//tr//td[3]"];


for (int i = 0; i < [elements count]; i++) 

{

    if(((NSString *)[[[[elements objectAtIndex:i] childrenobjectAtIndex:0]content]) != nil)

    {

        // 아이디가 스트링이면 스트링 출력

        NSLog(@"%@" , ((NSString *)[[[[elements objectAtIndex:i] childrenobjectAtIndex:0content]) ) ;

        

    }else

    {

        // 아이디가 이미지이면 링크 출력

        NSLog(@"%@", ((NSString *)[[[[[elements objectAtIndex:i] childrenobjectAtIndex:0attributes]valueForKey:@"src" ]));

    }

}

위에서 한 방법과 똑같은 방법이기 때문에 따로 상세설명은 안하겠습니다. 이 코드 위쪽에 첨부된 html부분과 잘 비교해 보세요.


뭐 여기까지 왔다면 글 작성시간과 조회수는 쉽습니다.

// 글작성시간

elements = [xpathParser searchWithXPathQuery:@"//tr//td[4]//span"];

NSLog(@"%@", [[elements objectAtIndex:0content]);

        

// 조회수

elements = [xpathParser searchWithXPathQuery:@"//tr//td[5]"];

NSLog(@"%@", [[elements objectAtIndex:0content]);

이렇게 필요한 정보를 다 가져올 수 있었습니다. 다음번에는 정규식을 이용한 파싱을 해 보겠습니다.


Stack overflow에서 보니 절대 html파싱은 정규식으로 하지 말라는 말이 많이 보입니다. 정규식이 다 좋은데 익숙해지지 않으면 읽기가 쉽지 않기때문에 그런데요. 사실 저도 정규식에는 근본없는 배움인지라...


Posted by 다오나무
iOS2012. 6. 21. 18:32

@interface TESTAppDelegate : NSObject <UIApplicationDelegate> {

 

 

NSString *DBNAME;

NSString *DBPATH;

 

}


-- m파일 

    NSFileManager *fileManager = [NSFileManager defaultManager];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectoryNSUserDomainMaskYES);

    NSString *documentsDirectory = [paths objectAtIndex:0];    

    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent@"Store.sqlite"];

self.DBPATH = writableDBPath;

NSLog(@"writableDBPath is %@", writableDBPath);

    

    BOOL dbexits = [fileManager fileExistsAtPath:writableDBPath];

    if (!dbexits) 

    {

NSLog(@"데이터베이스 카피");

        // 데이터베이스가 존재하지 않으면어플리케이션 Resource아래에서 복사를 한다

        NSString *defaultDBPath = [[[NSBundle mainBundleresourcePathstringByAppendingPathComponent:@"Store.sqlite"];

        NSError *error;

        BOOL success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];

    }    

   else {

NSLog(@"이미 패스가 잇음");

    }

아 별짓다했네... 3시간동안 강제로 Path따서 햇지만 읽히는건 읽혀지지만... insert가 안되서...
완전 제일 중요한거!!! 앱/Documents <--요놈안에있는놈만 수정이 가능하다!!

Posted by 다오나무
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 다오나무