출처 :  http://mystria.egloos.com/4387235

 

 

kabook 추가 : 압축 및 작업은 Mac에서 해야함

 

간략하게 정리..

1. 구현한 프로젝트를 "Simulator|Debug"가 아니라 "Device|Release"로 변경. Build를 수행함.

2. Project폴더의 "build > Release-iphoneos"에 들어가면 "프로젝트명.app"파일이 있는데 확장자는 표시되지 않음. 실제 Device와 연결이 되지 않아서인지 수행 불가 표시가 붙어있음.

3. 임의의 폴더를 생성하고, 그 안에 Payload라는 폴더를 생성. "프로젝트명.app"파일을 Payload폴더에 넣는다. "iTunesArtwork"는 "512*512"크기의 일반 png파일인데 아이튠즈를 실행시켰을때 표시되는 아이콘 모양인것 같다. iPhone에 올렸을 때 보여지는 아이콘은 따로 프로젝트에서 설정되는듯 하며, 따라서 "프로젝트명.app"파일 안에 포함되게 된다. "iTunesMetadata.plist"는 아이튠즈에 올렸을 때 표시되는 카테고리라든지 제작자같은 정보이다. 없어도 무방하다.
이 3개 중에 Payload폴더와 app파일만 있으면 된다.

4. 위 3가지 파일을 압축하게 되면 "Archive.zip"이 생성되는데, 이를 "아무이름.ipa"로 바꾸면 ipa파일 생성완료이다.

5. 이것을 iPhone에 올리는 것은 탈옥한 폰이어야 가능하며, 아이튠즈에 드래그하여 추가 후 동기화 시키는 방법과, "iPhone > var > mobile > Library > Downloads"에 복사 후 "Installous"를 이용해 설치하는 방법등을 통해 설치가 가능하다.

6. 완성

 

 



출처 : http://blog.naver.com/PostView.nhn?blogId=kabook&logNo=80122590217
Posted by 오늘마감
XCODE2011.04.09 11:08

Xcode 로 파일을 생성하면 소스 코드 상단의 주석에 __MyCompanyName__ 가 계속 보인다. 이를 수정하는 방법은 다음과 같다.


* 터미널을 실행한다.

* 아래의 명령을 실행한다.


# defaults write com.apple.Xcode PBXCustomTemplateMacroDefinitions -dict ORGANIZATIONNAME "Company Name"


맥북을 사고 처음으로 쓰는 포스트군요. ^^



출처 : http://blog.naver.com/PostView.nhn?blogId=websearch&logNo=70096929676
Posted by 오늘마감
XCODE2011.03.12 17:13
NSMutableArray 에서 Deep copy 시  FOR 문을 이용한 Copy는 비효율적 이다 
그래서 아래의 코드를 
-deepMuCopy : (NSMutableArray*) array 
    toNewArray : (NSMutableArray*) arrayNew {

    [arrayNew removeAllObjects];//ensure it's clean

    for (int y = 0; y<9; y++) {
        [arrayNew addObject:[NSMutableArray new]];
        for (int x = 0; x<9; x++) {
                [[arrayNew objectAtIndex:y] addObject:[NSMutableArray new]];

                NSMutableArray *aDomain = [[array objectAtIndex:y] objectAtIndex:x];
                for (int i = 0; i<[aDomain count]; i++) {

                        //copy object by object
                        NSNumber* n = [NSNumber numberWithInt:[[aDomain objectAtIndex:i] intValue]];
                        [[[arrayNew objectAtIndex:y] objectAtIndex:x] addObject:n];
               }
        }
    }
}

간단하게 나타 낼 수 있다...

NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:oldArray copyItems:YES];




출처 : http://blog.naver.com/PostView.nhn?blogId=coderider&logNo=50096223938
Posted by 오늘마감
[아이폰 앱 개발] 아이폰 어플에서 RSS 읽는 방법

RSS를 읽어 오는 간단한 리더기를 만들어 보겠습니다. 맥에서는 NSXMLDocument란 편리한 클래스가 있지만 아이폰 SDK에는 포함되어 있지 않습니다. 그렇기 때문에 NSXMLParser를 사용해서 RSS xml을 읽어오는 간단한 샘플을 만들어 보겠습니다.

인터넷을 통해 데이터를 가져오는 부분은 이전  "NSURLConnection으로 웹페이지 내용 가져오기"란 포스팅을 참고 하시기 바랍니다. 여기서는 파싱하는 부분만 간단히 살펴보겠습니다. 


1. NSXMLParser 생성
xml 데이터 파싱은 네트워크로 데이터 수신이 완료된 후 불려지는 connectionDidFinishLoading 메소드에서 아래와 같이 처리합니다. 

NSXMLParser *parser = [[NSXMLParser alloc] initWithData:receiveData];

[parser setDelegate:self];
[parser parse];
[parser release];


NSXMLParser 오브젝트를 수신된 데이터가 저장된 NSData 타입의 receiveData를 인자로 초기화를 합니다. setDelegate 메소드로 현재 오브젝트를 NSXMLParser의 딜리케이트로 지정합니다. 지정된 오브젝트는 요소별로 파싱의 시작/종료와 파싱된 스트링을 받을 수 있는 메소드를 구현해야 합니다. 

parse 메소드로 파싱이 시작됩니다. 파싱은 자동으로 처리되지 않으며, 각 단계별로 딜리게이트된 메소드를 구현하여 필요와 형식에 맞게 직접 처리해야 합니다.

2. Delegate 메소드 구현
NSXMLParser에는 많은 딜리게이트 메소드가 있지만 가장 중요하고 거의 반드시 구현해야될 메소드는 parser:didStartElement, parser:foundCharacters, parser:didEndElement입니다. 

parser:didStartElement로 한 요소의 파싱이 시작됨을 알수 있습니다. parser:foundCharacters로 해당 문자열들이 넘어 옵니다. 토큰 단위로 넘어 오기 때문에 넘어 오는 문자열들을 계속 저장해야 합니다. parser:didEndElement가 실행되면 비로소 한 요소의 파싱이 끝난 것을 알 수 있습니다. 이 메소드에서 해당 요소에 따른 필요한 처리를 합니다. 

1) 시작 메소드 구현

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    if ([elementName isEqualToString:@"item"]) 
        elementType = etItem;
    
    [xmlValue setString:@""];
}


두번째 인자인 elementName으로 해당요소의 이름이 전달됩니다. 세번째와 네번째 인자는 네임스페이스와 관련된 uri와 전체이름이 전달됩니다. 만약 해당 xml이 네임스페이스를 사용한다면 이전에 [parser setShouldProcessNamespaces:YES];로 네임스페이스를 처리하도록 설정해야 합니다. NSXMLParser의 shouldProcessANamespace의 기본값은 NO 입니다.

마지막 인자인 attributeDict에는 해당 요소의 속성들이 전달됩니다. 만약 와 같이 되어 있다면 attributeDict 딕셔너리에 key가 'lang', value가 'ko'로 저장되어 전달됩니다.

여기서는 다른 인자들은 무시하고 item이란 이름의 요소가 시작될때 부터 데이터들을 저장하도록 요소이름이 item인지만 확인합니다. 그리고 xmlValue에 새로운 데이터를 저장하기 위해 이전에 저장된 값들을 초기화합니다. 

2) 데이터 저장 메소드 구현

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if (elementType == etItem) {
        [xmlValue appendString:string];
    }
}

토큰별로 넘어오는 문자열을 xmlValue에 저장합니다.

3) 종료 메소드 구현

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if (elementType != etItem)
        return;

    if ([elementName isEqualToString:@"title"]) {
        [currectItem setValue:[NSString stringWithString:xmlValue] forKey:elementName];
    } else if ([elementName isEqualToString:@"link"]) {
        [currectItem setValue:[NSString stringWithString:xmlValue] forKey:elementName];
    } else if ([elementName isEqualToString:@"description"]) {
        [currectItem setValue:[NSString stringWithString:xmlValue] forKey:elementName];
    } else if ([elementName isEqualToString:@"category"]) {
        [currectItem setValue:[NSString stringWithString:xmlValue] forKey:elementName];
    } else if ([elementName isEqualToString:@"pubDate"]) {
        [currectItem setValue:[NSString stringWithString:xmlValue] forKey:elementName];
    } else if ([elementName isEqualToString:@"item"]) {
        [xmlParseData addObject:[NSDictionary dictionaryWithDictionary:currectItem]];
    }
}


한 요소가 끝날때 호출됩니다. 여기서는 RSS의 title, link, description, category, pubData 항목들만 currentItem 딕셔너리에 저장합니다. 한 포스팅의 마지막 요소인 일 경우에는 xmlParseData에 현재 딕셔너리를 추가합니다.

3. 테이블뷰 출력

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [xmlParseData count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    
    NSDictionary *dict = [xmlParseData objectAtIndex:indexPath.row];
    [[cell textLabel] setText:[dict objectForKey:@"title"]];
    
    return cell;
}


여기서 테이블뷰는 아무 동작을 하지않으며 xmlParseData에 저장된 해당 title만 출력합니다. 빌드 후 실행하면 아래와 같이 해당 RSS의 제목이 출력되는 것을 확인할 수 있습니다.

 

Posted by 오늘마감
[아이폰 앱 개발] NSURLConnection을 이용한 웹페이지 내용 가져오는 방법

SURLConnection을 이용하면 간단하게 해당 웹서버의 html, xml등의 내용을 쉽게 가져올 수 있습니다.

1. 연결

connection = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.cocoadev.co.kr/rss]] delegate:self];

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

대상 URL을 인자로 NSURLConnection을 생성합니다. 위는 이 블로그의 rss를 주소로 생성하는 예입니다. delegate는 self로 현제 오브젝트로 지정합니다. delegate로 지정된 오브젝트는 NSURLConnection의 delegate 메소드를 구현하고 메시지를 받을 수 있습니다.

UIApplication의 networkActivityIndicatorVisible을 YES로 하여 데이터 수신 시 좌측과 같이 상단 상태바에 인디케이터가 회전하는 에니메이션으로 사용자에게 데이터 수신중임을 알려줍니다. 기본값은 NO로 되어 있습니다.

2. delegate 메소드 구현
NSURLConnection 생성시 delegate로 지정된 클래스에서는 해당 이벤트 처리 메소드를 구현해야 합니다. 가장 자주 사용되는 delegate 메소드는 데이터 수신, 연결 종료, 오류발생등에 관련된 것들입니다.

1) 데이터 수신 
* connection:didReceiveData:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
   [receiveData appendData:data];
}
데이터가 수신될 때 불려지면 웹서버로 부터 받은 데이터가 NSData 형태로 넘어 옵니다. NSMutableData의 appendData 메소드를 이용하여 수신되는 데이터들을 차례대로 저장합니다.

2) 연결 종료
* connectionDidFinishLoading:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
   NSString *str = [[NSString alloc] initWithData:receiveData 
encoding: NSUTF8StringEncoding];
   NSLog(@"%@", str);
   [str release];

   [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}
데이터가 모두 수신되어 웹서버와의 연결이 종료되었을 때 호출됩니다. 이곳에서 원하는 작업을 하거나 다른 오브젝트가 처리하도록 할 수 있습니다. 위는 NSData로 저장된 데이터를 NSString으로 변환하여 출력하는 예입니다. xml이라면 NSXMLParser를 사용하여 데이터를 처리할 수 있습니다.

3) 오류 발생
* connection:didFailWithError:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
   NSLog(@"Connect error: %@", [error localizedDescription]);    

  [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}
네트워크가 연결되지 않았을 경우등 오류가 발생하였을 때 호출되는 메소드 입니다. 해당 페이지가 없음을 나타내는 404 오류등은 이 메소드가 호출되지 않습니다.
Posted by 오늘마감
[아이폰 앱 개발] webView를 이용해서 간단한 웹브라우져 만드는 방법

iPhone Coding – Learning About UIWebViews by Creating a Web Browser

Wow! It has been a long time since my last tutorial… As I wrote in my last post, I had to take a break due to my wife having our baby.  But, now I’m back and have a great tutorial for you guys.  

Today I will be showing you how to work with a  UIWebview to create a basic web browser.  Here is a screenshot of the app we are going to create.

Create a View-Based Application

Ok, so let’s get started.  Start by opening up Xcode and click File -> New Project.  Next select View-Based Application and click Choose… Name this project something like iCodeBrowser and click Save.  

Now we are ready to begin coding…

Create IBOutlets and IBActions

Before we create the interface for our web browser, we need to establish the IBOutles and Actions to interface with the UI elements in code.  Start by opening up iCodeBrowserViewController.h and add the following code:

Let’s take a look at this code line by line.  The first thing we added was the  to the end of our interface declaration.  This is telling the app that this class will be the delegate for our UIWebview.  

What does it mean to be the delegate you ask? Great question… A delegate is like a handler.  It is responsible for implementing certain methods in order to handle events sent by the object they are the delegate for.  So in our example, we are simply saying that we will implement some of the functionality of the UIWebView.  This is needed so we can capture certain actions of the UIWebView such as a click on a link or so we can tell when a page has started/finished loading.  If it’s still unclear, ask me clarifying questions in the comments section.

Next, we see our 3 lines of declaring IBOutlets.  These are the UI elements that we will be interacting with.  In case you didn’t know, the UIActivityIndicator is the little spinner/loading animation that you see on various apps when content is loading.  We will be using this to show that a page is currently loading.

Following this code, there are 3 IBActions.  IBActions are functions that get called in response to a user interaction with the application (such as tapping a button).  For our basic browser, we are only offering 3 types of functionality.  gotoAddress which will take a user to the address they type in the address bar and goBack/Forward should be pretty self explanatory.  

Creating the User Interface 

Now, let’s create the interface using Interface Builder.  I am going to be showing you how to do this in the video below.

 

Implementing the IBActions

Now that we have our interface, let’s make the app function.  We need to implement our methods.  Open up iCodeBrowserViewController.m and add the following code.

We need to synthesize our properties to allow us to interact with them.  Synthesizing automatically creates “getter” and “setter” methods for our properties.  Next, let’s implement the viewDidLoad method.  This is where we will be loading our “homepage”.  Add the following code to the viewDidLoad method.

The viewDidLoad method gets called automatically by our application whenever this view first loads.  We can know for sure that it will get called, so we can put our initialization code here.

ADVERTISEMENT

 

The first thing we see is the urlAddress string.  This will be our “homepage”.   You can change this to any address you wish to start with.  Next, we build a URL object with our string.  We need to do this so we can make a web request.  Following this, we build our web request and load it into the webView.  This will display the homepage inside of our webview.  Finally, we set the text of the address bar to the homepage address.  This part is more for aesthetics to let the user know what page they are on.

Next, we implement the method that we connected to the UITextField’s DidEndOnExit method gotoAddress.  Add the following code:

This is similar to the code we wrote in the viewDidLoad method, except for the fact that we are getting our URL string from the address bar.  This method gets called when the user presses the “Go” button on the keyboard.  The last thing to note here is we call the [addressBar resignFirstResponder] method.  This simply tells the app to hide the keyboard when this method gets called.

The implementation of our Back and Forward methods are pretty easy.  Go ahead and add the following code.

UIWebViews are pretty cool because of the functionality they offer us built right in to them.  We simply call[webView goBAck] to go back and [webView goForward] to go forward.  This greatly simplifies the interactions with the webview.  If we were to code that functionality from scratch, we would have to create a stack of URLs and continually push and pop them off the stack to keep track of where we need to go.  Thanks Apple for not making us implement this.

Finally, we need to implement the delegate methods for UIWebview.  These methods allow us to write our own code to respond to actions by the UIWebview.  The first methods we will implement are the webViewDidStartLoad and the webViewDidFinishLoad methods.  We will use these to show and hide the activity indicator. Add the following code:

So when the request is first made for a ULR (before the page starts loading) the webViewDidStartLoad method gets called automatically.  We use this opportunity to start our activity indicator to let the user know the page is loading.  If you don’t have something like this, it simply feels like the app is frozen when in fact, it’s just loading the page.  Finally, the webViewDidFinishLoad method gets called when the page is fully loaded.  After this, we can stop the indicator (and it automatically hides itself).

The very last thing we need to do is define what happens when a user clicks on a link. Add the following method:

This method gets called automatically whenever the user clicks a link.  This method can be very useful if you want to make a native iPhone application that integrates with a web app.  You can use this method to trap the user’s clicks and have your application respond to web links that get clicked.  In our case, we need it to do 2 things.  The first is to set the text of the address bar to the URL of the link that was clicked on and to load that address into the webview.

One thing to make note of: We do a check to see if the URL scheme is “http”. This is to ensure that the user typed http before their URL.  You can add an else statement here that auto prepends the http if the user did not add it.  This would allow you to type in a url such as “icodeblog.com” rather than having to type “http://www.icodeblog.com”.  I chose to omit it for this tutorial.

Remember, all of this added functionality of a UIWebView can only be gotten if you tell your class that it implements the UIWebViewDelegate protocol as we did in our .h file.

The app should be complete! Click on Build and Go to see this baby in action.  Remember, you must put “http://” in front of your URL’s.  

I hope you have enjoyed this tutorial.  If you have any questions or comments, feel free to leave them in the comments section of this post.  You can download the source here . Happy iCoding!

 

 

This entry was posted in Interface BuilderiPhone Programming Tutorials and tagged . Bookmark the permalinkPost a comment or leave a trackback: Trackback URL.
Posted by 오늘마감
화면 잠기는것 막는 방법
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
Posted by 오늘마감
테이블뷰와 테이블뷰셀을 수정하는 방법

First you have to create the UITableViewCell class that will contain your delegate function.

This delegate function is responsible for passing data back to your class ... for example, - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath function that you definitely have to know :) is a delegate method as well ... its passing the information abou what row you have selected back from the table view intor class.

Code for the EditFieldCell.h:

  1. //
  2. //  EditFieldCell.h
  3. //  iBlog
  4. //
  5. //  Created by Ondrej Rafaj on 12.11.09.
  6. //  Copyright 2009 Home. All rights reserved.
  7. //
  8. #import 
  9. @class EditFieldCell;  
  10. @protocol EditFieldCellDelegate   
  11. // we will make one function mandatory to include
  12. - (void)editDidFinish:(NSMutableDictionary *)result;  
  13. @optional  
  14. // and the other one is optional (this function has not been used in this tutorial)
  15. - (void)editStarted:(UITextField *)field;  
  16. @end  
  17. @interface EditFieldCell : UITableViewCell  {  
  18.     IBOutlet UITextField *textField;  
  19.     id  delegate;  
  20.     NSString *key;  
  21. }  
  22. @property (nonatomic, retain) IBOutlet UITextField *textField;  
  23. @property (nonatomic, assign) id  delegate;  
  24. @property (nonatomic, retain) NSString *key;  
  25. @end  

Code for the EditFieldCell.m:

  1. //
  2. //  EditFieldCell.m
  3. //  iBlog
  4. //
  5. //  Created by Ondrej Rafaj on 12.11.09.
  6. //  Copyright 2009 Home. All rights reserved.
  7. //
  8. #import "EditFieldCell.h"
  9. @implementation EditFieldCell  
  10. @synthesize textField, delegate, key;  
  11. - (void)textFieldDidBeginEditing:(UITextField *)tf {  
  12.     [[self delegate] editStarted:tf];  
  13. }  
  14. - (void)dealloc {  
  15.     [textField, key release];  
  16.     [super dealloc];  
  17. }  
  18. @end  

You have to of course create a new cell view in the Interface Builder and assign all the necessary variables onto your class :) ... I assume that you already know that stuff when you are reading a tutorial about delegate methods :))

and this is how to set the delegate in the main view:

  1. @interface EditBlogController : BasicTableController   

And we can't forget the function that will receive your data:

  1. - (void)editDidFinish:(NSMutableDictionary *)result {  
  2.     NSString *key = [result objectForKey:@"key"];  
  3.     NSString *value = [result objectForKey:@"text"];  
  4. }  

And finally here we have the cellForRowAtIndexPath function:

  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {  
  2.     static NSString *CellIdentifier = @"MyCell";  
  3.     EditFieldCell *cell = (EditFieldCell *) [super.table dequeueReusableCellWithIdentifier:CellIdentifier];  
  4.     if (cell == nil){  
  5.         NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"EditFieldCell" owner:nil options:nil];  
  6.         for(id currentObject in topLevelObjects) {  
  7.             if([currentObject isKindOfClass:[EditFieldCell class]]) {  
  8.                 cell = (EditFieldCell *) currentObject;  
  9.                 break;  
  10.             }  
  11.         }  
  12.     }  
  13.     int index = [indexPath indexAtPosition: [indexPath length] - 1];  
  14.     // next line is very important ... 
  15.     // you have to set the delegate from the cell back to this class
  16.     [cell setDelegate:self];  
  17.     // I am using the key to identify what field is user editing
  18.     NSString *key = @"key_for_your_value";  
  19.     NSString *placeholder = @"Your placeholder";  
  20.     cell.key = key;  
  21.     cell.textField.text = [blogData objectForKey:key];  
  22.     cell.textField.placeholder = placeholder;  
  23.     return cell;  
  24. }  

As I said before, I'm assuming that you already know how to create a table view and display data in it, but if you'll have any question please feel free to post a comment, I'll be happy to help you with that :).

Cheers,

Ondrej


We had to disable comments till the problem with spam will be solved, sorry for any inconvenience caused.

http://www.xprogress.com/post-41-editing-uitextview-in-uitableviewcell-via-delegate-method/

Posted by 오늘마감
JSON을 NSArray나 NSDictionary에 넣는 방법

In this project we will be using very useful set of libraries from the json-framework project which is an open-source project available for free on the internet.

Please download source files for JSON framework library project here:

http://code.google.com/p/json-framework/

or you can download and open the example projech available on this page and copy those source files from this project. Files are located Classes/JSON/ folder in this example.

Don't even try to use the framework which is located in the original project on Google Code as any thirdparty framework is not permitted on iPhone platform.

Ok, let's assume you've created a new for example Navigation or Window based project, and you have the neccessary libraries already included in it. Try to build the project (you can use the Cmd + B shortcut) to see that everything is allright and we can move on to the more interesting part.

Now you have to declare IBOutlet for your textview (UITextView) and your buttons (UIButton) IBAction that will carry all the functionality after pressing the button.

  1. IBOutlet UITextView *logWindow;  

And

  1. // our text field window
  2. @property (nonatomic, retain) IBOutlet UITextView *logWindow;  
  3. // action we'll use after pressing the button to start parsing the file
  4. - (IBAction)startParser:(UIButton *)sender;  

the entire source code for your controller's header file (.h) is here:

  1. //
  2. //  TutorialProjectViewController.h
  3. //  TutorialProject
  4. //
  5. //  Created by Ondrej Rafaj on 5.8.09.
  6. //  Copyright Home 2009. All rights reserved.
  7. //
  8. #import 
  9. #import "SBJSON.h"
  10. @interface TutorialProjectViewController : UIViewController {  
  11.     // ------ Tutorial code starts here ------
  12.     // our text field window
  13.     IBOutlet UITextView *logWindow;  
  14.     // ------ Tutorial code ends here ------
  15. }  
  16. // ------ Tutorial code starts here ------
  17. // our text field window
  18. @property (nonatomic, retain) IBOutlet UITextView *logWindow;  
  19. // action we'll use after pressing the button to start parsing the file
  20. - (IBAction)startParser:(UIButton *)sender;  
  21. // ------ Tutorial code ends here ------
  22. // This function is for button which takes you to the xprogress.com website
  23. - (IBAction) runXprogressComButton: (id) sender;  
  24. @end  

Now we have to edit the .m file. First synthesize the logWindow variable:

  1. @synthesize logWindow;  

and than, don't forget to release this variable in the dealloc function:

  1. [logWindow release];  

Start the IBAction for your button which is called startParser:

  1. - (IBAction)startParser:(UIButton *)sender {  
  2. }  

And start coding :)

You have to find your file in the application bundle (I'll show you how to load this file properly from the internet next time, today you have to inlude the json file into your resources folder), I assume that the json file is called data.json. We will be using just some random jsom file I found on the internet, content looks like that:

  1. {  
  2.     "menu": {  
  3.         "header""xProgress SVG Viewer",  
  4.         "items": [  
  5.             {  
  6.                 "id""Open"
  7.             },  
  8.             {  
  9.                 "id""OpenNew",  
  10.                 "label""Open New"
  11.             },  
  12.             null,  
  13.             {  
  14.                 "id""ZoomIn",  
  15.                 "label""Zoom In"
  16.             },  
  17.             {  
  18.                 "id""ZoomOut",  
  19.                 "label""Zoom Out"
  20.             },  
  21.             {  
  22.                 "id""OriginalView",  
  23.                 "label""Original View"
  24.             },  
  25.             null,  
  26.             {  
  27.                 "id""Quality"
  28.             },  
  29.             {  
  30.                 "id""Pause"
  31.             },  
  32.             {  
  33.                 "id""Mute"
  34.             },  
  35.             null,  
  36.             {  
  37.                 "id""Find",  
  38.                 "label""Find..."
  39.             },  
  40.             {  
  41.                 "id""FindAgain",  
  42.                 "label""Find Again"
  43.             },  
  44.             {  
  45.                 "id""Copy"
  46.             },  
  47.             {  
  48.                 "id""CopyAgain",  
  49.                 "label""Copy Again"
  50.             },  
  51.             {  
  52.                 "id""CopySVG",  
  53.                 "label""Copy SVG"
  54.             },  
  55.             {  
  56.                 "id""ViewSVG",  
  57.                 "label""View SVG"
  58.             },  
  59.             {  
  60.                 "id""ViewSource",  
  61.                 "label""View Source"
  62.             },  
  63.             {  
  64.                 "id""SaveAs",  
  65.                 "label""Save As"
  66.             },  
  67.             null,  
  68.             {  
  69.                 "id""Help"
  70.             },  
  71.             {  
  72.                 "id""About",  
  73.                 "label""About xProgress CVG Viewer..."
  74.             }   
  75.         ]  
  76.     }  
  77. }  

You can create new file by right-clicking the Resources folder and selecting Add -> New file -> Other (Under Mac OS X) -> Empty file. The XML equivalent will look like that:

  1.   
  2.      xProgress Viewer  
  3.     "Open" id="Open">Open  
  4.     "OpenNew" id="OpenNew">Open New  
  5.     "ZoomIn" id="ZoomIn">Zoom In  
  6.     "ZoomOut" id="ZoomOut">Zoom Out  
  7.     "OriginalView" id="OriginalView">Original View  
  8.     "Quality" id="Quality">Quality  
  9.     "Pause" id="Pause">Pause  
  10.     "Mute" id="Mute">Mute  
  11.     "Find" id="Find">Find...  
  12.     "FindAgain" id="FindAgain">Find Again  
  13.     "Copy" id="Copy">Copy  
  14.     "CopyAgain" id="CopyAgain">Copy Again  
  15.     "CopySVG" id="CopySVG">Copy SVG  
  16.     "ViewSVG" id="ViewSVG">View SVG  
  17.     "ViewSource" id="ViewSource">View Source  
  18.     "SaveAs" id="SaveAs">Save As  
  19.     "Help" id="Help">Help  
  20.     "About" id="About">About xProgress Viewer...  
  21.   

Ok, now we are going to get the path to the file data.json:

  1. NSString *filePath = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"json"];  

Than you have to load contents of this file:

  1. NSString *fileContent = [[NSString alloc] initWithContentsOfFile:filePath];  

Allocate new instance of your json parser:

  1. SBJSON *parser = [[SBJSON alloc] init];  

And parse the first level of the file:

  1. NSDictionary *data = (NSDictionary *) [parser objectWithString:fileContent error:nil];  
  2. // getting the data from inside of "menu"
  3. NSDictionary *menu = (NSDictionary *) [data objectForKey:@"menu"];  

NSDictionary is something like an array, which has numeric keys but you can use for example strings as a key.

This new NSDictionary is taken from the data dictionary by selecting the only key on this level, which is menu [data objectForKey:@"menu"].

Now we can get some more data , like the content of header as a string (NSString):

  1. NSString *header = (NSString *) [menu objectForKey:@"header"];  

And an array that is in the json file enclosed into the square brackets.

  1. NSArray *items = (NSArray *) [menu objectForKey:@"items"];  

Now you want to go trough the array and do something with the data init. You can do something like that:

  1. for (id *item in items) {  
  2.         // if the item is NSDictionary (in this case ... different json file will probably have a different class)
  3.         NSLog(@"One item: %@", [NSString stringWithFormat:@"Item -> %@", (NSDictionary *) item]);  
  4. }  

On the end of the function don't forget to release the json data parser:

[parser release];

This file in the example is slightly different as I've used a separated function to add results into the UITextView we've created earlier.

This function is not doing anything else than adding new records on the top of the logWindow:

  1. - (void)addRowToLogWindow:(id)data {  
  2.     logWindow.text = [NSString stringWithFormat:@"Adding data: %@  
  3. %@", data, logWindow.text]; // adding new row + 2x new line "
  4. "  
  5. }  

Code for the entire .m file is here:

  1. //
  2. //  TutorialProjectViewController.m
  3. //  TutorialProject
  4. //
  5. //  Created by Ondrej Rafaj on 5.8.09.
  6. //  Copyright Home 2009. All rights reserved.
  7. //
  8. #import "TutorialProjectViewController.h"
  9. @implementation TutorialProjectViewController  
  10. // ------ Tutorial code starts here ------
  11. @synthesize logWindow;  
  12. // function for adding an 
  13. - (void)addRowToLogWindow:(id)data {  
  14.     logWindow.text = [NSString stringWithFormat:@"Adding data: %@  
  15. %@", data, logWindow.text]; // adding new row + 2x new line "
  16. "  
  17. }  
  18. - (IBAction)startParser:(UIButton *)sender {  
  19.     // getting path to the file
  20.     NSString *filePath = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"json"];  
  21.     NSLog(@"Path: %@", filePath);  
  22.     // reading content of the file, don't use the [NSString stringWithContentsOfFile:@"/Your/Filepath/"]; as this is deprecated since iPhone SDK 3.0
  23.     NSString *fileContent = [[NSString alloc] initWithContentsOfFile:filePath];  
  24.     //NSLog(@"File content: %@", fileContent);
  25.     // creating new parser
  26.     SBJSON *parser = [[SBJSON alloc] init];  
  27.     // parsing the first level
  28.     NSDictionary *data = (NSDictionary *) [parser objectWithString:fileContent error:nil];  
  29.     // getting the data from inside of "menu"
  30.     NSDictionary *menu = (NSDictionary *) [data objectForKey:@"menu"];  
  31.     // getting the first value which is stored in the header
  32.     NSString *header = (NSString *) [menu objectForKey:@"header"];  
  33.     [self addRowToLogWindow:[NSString stringWithFormat:@"Header -> %@", header]];  
  34.     // parsing all the items in to the NSArray
  35.     NSArray *items = (NSArray *) [menu objectForKey:@"items"];  
  36.     // reading all the items in the array one by one
  37.     for (id *item in items) {  
  38.         // if the item is NSDictionary (in this case ... different json file will probably have a different class)
  39.         [self addRowToLogWindow:[NSString stringWithFormat:@"Item -> %@", (NSDictionary *) item]];  
  40.     }  
  41.     for (id *item in items) {  
  42.         // if the item is NSDictionary (in this case ... different json file will probably have a different class)
  43.         NSLog(@"One item: %@", [NSString stringWithFormat:@"Item -> %@", (NSDictionary *) item]);  
  44.     }  
  45.     // releasing parser
  46.     [parser release];  
  47. }  
  48. // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
  49. - (void)viewDidLoad {  
  50.     // removing the default data from our UITextView
  51.     logWindow.text = @"";  
  52.     [super viewDidLoad];  
  53. }  
  54. // ------ Tutorial code ends here ------
  55. /* 
  56. // The designated initializer. Override to perform setup that is required before the view is loaded. 
  57. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 
  58.     if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 
  59.         // Custom initialization 
  60.     } 
  61.     return self; 
  62. } 
  63. */
  64. /* 
  65. // Implement loadView to create a view hierarchy programmatically, without using a nib. 
  66. - (void)loadView { 
  67. } 
  68. */
  69. /* 
  70. // Override to allow orientations other than the default portrait orientation. 
  71. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
  72.     // Return YES for supported orientations 
  73.     return (interfaceOrientation == UIInterfaceOrientationPortrait); 
  74. } 
  75. */
  76. - (void)didReceiveMemoryWarning {  
  77.     // Releases the view if it doesn't have a superview.
  78.     [super didReceiveMemoryWarning];  
  79.     // Release any cached data, images, etc that aren't in use.
  80. }  
  81. - (void)viewDidUnload {  
  82.     // Release any retained subviews of the main view.
  83.     // e.g. self.myOutlet = nil;
  84. }  
  85. // This function is for button which takes you to the xprogress.com website
  86. - (IBAction) runXprogressComButton: (id) sender {  
  87.     NSURL *url = [[[NSURL alloc] initWithString: @"http://www.xprogress.com/"] autorelease];  
  88.     [[UIApplication sharedApplication] openURL:url];  
  89. }  
  90. - (void)dealloc {  
  91.     // ------ Tutorial code starts here ------
  92.     [logWindow release];  
  93.     // ------ Tutorial code ends here ------
  94.     [super dealloc];  
  95. }  
  96. @end  

Now you have to connect your button and textview in Interface Builder to the IBAction for the button and logWindow outlet to the UITextView.

Now you can try to run the application and see if the data are parsed properly into the logWindow.

http://www.xprogress.com/post-44-how-to-parse-json-files-on-iphone-in-objective-c-into-nsarray-and-nsdictionary/

Posted by 오늘마감
오브젝트C2010.10.12 03:58
자바보다 훨씬 직관적인 object-c 의 간단한 NSThread 사용 방법

자바보다 훨씬 직관적이다. import할 클래스나 delegate도없다.

- (IBAction) startThreadButtonPressed:(UIButton *)sender {

threadStartButton.hidden = YES;
threadValueLabel.text = @"0";
threadProgressView.progress = 0.0;
[NSThreaddetachNewThreadSelector:@selector(startTheBackgroundJob) toTarget:selfwithObject:nil];

}

- (void)startTheBackgroundJob {

NSAutoreleasePool *pool = [[NSAutoreleasePoolalloc] init];
// wait for 3 seconds before starting the thread, you don't have to do that. This is just an example how to stop the NSThread for some time
[NSThreadsleepForTimeInterval:3];
    [selfperformSelectorOnMainThread:@selector(makeMyProgressBarMoving) withObject:nilwaitUntilDone:NO];
    [pool release];

}

- (voidmakeMyProgressBarMoving{
    
float actual = [threadProgressViewprogress];
threadValueLabel.text = [NSStringstringWithFormat:@"%.2f", actual];
if (actual < 1) {
threadProgressView.progress = actual + 0.01;
[NSTimerscheduledTimerWithTimeInterval:0.5target:selfselector:@selector(makeMyProgressBarMoving) userInfo:nilrepeats:NO];
}
elsethreadStartButton.hidden = NO;

}


1.버튼을 누르면 아래의 스레드가 실행된다. 자바에서 start()와 같은 역할.
[NSThreaddetachNewThreadSelector:@selector(startTheBackgroundJobtoTarget:selfwithObject:nil];
2. 콜백으르 startTheBackgroundJob가 있고 위에 정의된 함수가 콜백된다. 자바의 run()과같은 역할
2.1 스레드에의해 콜백되는 함수는 
    NSAutoreleasePool *pool = [[NSAutoreleasePoolallocinit];로 시작하고

    [pool release];로 끝나야한다.

    시작점과 끝점사이 실제실행하고싶은 코드나 함수호출코드를 집어넣으면 된다.


2.2 위의 콜백함수는 타이머에

NSAutoreleasePool *pool = [[NSAutoreleasePoolallocinit];

// wait for 3 seconds before starting the thread, you don't have to do that. This is just an example how to stop the NSThread for some time

[NSThreadsleepForTimeInterval:3];

    [selfperformSelectorOnMainThread:@selector(makeMyProgressBarMovingwithObject:nil

     waitUntilDone:NO];





출처 : http://blog.naver.com/PostList.nhn?blogId=philipousys¤tPage=151
Posted by 오늘마감