본문 바로가기

Log (Computer)/프로그래밍

아이폰 프로그래밍 스터디 예제3

이번이 세번째이다.  이번엔 xml(rss)파싱에 도전해보기로 한다.

뉴스가 있는 rss 정보를 파싱해오고 덧붙여 테이블뷰에 내용을 추가버튼을 구현하여

추가창을 모달뷰로 띄우고 저장된 내용이 테이블뷰에 다시 업데이트 되는 앱이다.

그리고 그 셀을 클릭시 해당되는 뉴스기사들이 테이블뷰로 쫙 뿌려지는 앱이다.

이앱을 기반으로 뉴스 앱을 만들 수 있을 것이다.


메인화면이다 우선 세가지정도의 뉴스 싸이트를 미리 저장해 두었다. 이건 전 예제에서 했던 거라 어렵지 

않았다.  그러나 추가를 구현하기 위해서는 DB 나 pList로 데이터를 구현해야 했는데 여기선

pList로 구현해보았다. 

리소스에 plist 파일을 하나 생성하고 코드에

- (void)viewDidLoad {

    [super viewDidLoad];

NSString *path = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"plist"];

NSMutableArray * tmpArray = [[NSMutableArray alloc] initWithContentsOfFile:path];

newsPaper = tmpArray;

NSDictionary * newDic1 = [NSDictionary dictionaryWithObjectsAndKeys:@"조선일보", @"name", @"http://www.chosun.com/site/data/rss/rss.xml", @"address", nil];

[newsPaper addObject:newDic1]; 

NSDictionary * newDic2 = [NSDictionary dictionaryWithObjectsAndKeys:@"동아일보", @"name", @"http://rss.donga.com/total.xml", @"address", nil];

[newsPaper addObject:newDic2];

NSDictionary * newDic3 = [NSDictionary dictionaryWithObjectsAndKeys:@"노컷뉴스", @"name", @"http://rss.cbs.co.kr/nocutnews.xml", @"address", nil];

[newsPaper addObject:newDic3];

[newsPaper retain];

self.navigationItem.rightBarButtonItem = self.addButton;

self.title = @"NEWS";


    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.

    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

}

이런식으로 패스를 지정하고 해당하는 array와 연결 시켜서 구현한다. 

그리고 추가 버튼에

- (IBAction) addButton: (id)sender {

add *Add = [[add alloc] initWithNibName:@"add" bundle:nil];

Add.addNews = self.newsPaper;

[self presentModalViewController:Add animated:YES];

[Add release];

}


루트에서 가지고 있는 배열정보의 주소를 추가뷰에 넘겨주고

- (IBAction) save: (id) sender

{

//NSString *name = nameTextField.text;

//NSString *address = addressTextField.text;

NSMutableDictionary * newsAdd = [[NSMutableDictionary alloc] init];

[newsAdd setValue:nameTextField.text forKey:@"name"];

[newsAdd setValue:addressTextField.text forKey:@"address"];

[addNews addObject: newsAdd];

[newsAdd release];

[self dismissModalViewControllerAnimated:YES];

NSLog(@"f");

}


추가 뷰에서 그 배열에 새로운 정보를 추가하는 소스르르 구현하였다. 뷰는 모달뷰를 이용하였다.



해당하는 셀을 누르면 해당 뉴스의 rss 주소를 파싱해와서 테이블 뷰에 뿌려주는 모습이다.

rss 파싱에는 맥부기 및 여러 사이트를 돌며 알아보았다. 아직도 정말 살짝 맛보기만 알뿐이다.

xmlPraser 를 이용한 파싱방법이다.

- (void)awakeFromNib {

xmlConnection = [[NSURLConnection alloc

initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[newsName objectForKey:@"address"]]]

delegate:self];

if (xmlConnection == nil)

NSLog(@"Connect error");

else

[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

xmlParseData = [[NSMutableArray alloc] init];

xmlValue = [[NSMutableString alloc] init];

currectItem = [[NSMutableDictionary alloc] init];

receiveData = [[NSMutableData alloc] init];

}


#pragma mark URLConnection delegate methods


- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

NSLog(@"Receive: %@, %@, %d"

  [response URL],

  [response MIMEType],

  [response expectedContentLength]);

}


- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {

NSLog(@"%@", [error localizedDescription]);

[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;  

}


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

[receiveData appendData:data];

}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

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

    [parser setDelegate:self];

    [parser parse];

[parser release];

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

[xmlConnection release];

[receiveData release];

UITableView *tableView = (UITableView *)[self view];

[tableView reloadData];

}


#pragma mark XMLParse delegate methods


- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {

if ([elementName isEqualToString:@"item"]) 

elementType = etItem;

[xmlValue setString:@""];

}


- (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]];

}

NSLog(@"dd");

}


- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {

if (elementType == etItem) {

[xmlValue appendString:string];

}

}


#pragma mark Table view methods


- (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;

}


이 방법으로 해당하는  rss의 정보를 가져와서 테이블뷰에 뿌려주는 방법이다.

사실 위 코드는 아직 완벽히 분석하지 못했다. 더 연구를 해보아야겠다만...

그리고 뉴스 정보를 누르면 웹뷰가 뉴스브라우져를 띄우는 구조로 되어있다.

이전에 썼었으니... 패스