'분류 전체보기'에 해당되는 글 653건

  1. 2011.08.12 [WCF] IIS에서 WCF 서비스 설치
  2. 2011.08.09 [iphone] 맥용 SVN Client SCPlugin
  3. 2011.07.28 [iphone] modalviewcontroller의 parentviewcontroller 에서 reload하기
  4. 2011.07.27 [iphone] IB 를 이용해서 Custom TableViewCell 만들기
  5. 2011.07.27 [iphone] Instruments를 이용해서 메모리 체크를 하자
  6. 2011.07.27 [iphone] 예전에 올린 XML Parsing 소스 Upgrade
  7. 2011.07.26 [iphone] exc_bad_access 에러 났을때 Xcode4에서 활용법
  8. 2011.07.26 [iphone] ModelViewController를 사용해서 뷰위에 뷰를 올려보자
  9. 2011.07.25 [iphone] UIViewController안에 UITableView Insert하기
  10. 2011.07.25 [iphone] UIScrollView 이용하기
  11. 2011.07.22 [iphone] WCF Rest Service로 HttpRequest하는법과 한글 인코딩
  12. 2011.07.22 [iphone] tableview에서 cell을 표시할때 KeyValue쓰지 않고 표시하기
  13. 2011.07.21 [Iphone] NSXMLParser를 이용하여 Xml을 파싱해보자.
  14. 2011.07.19 [iphone] navigationItemButton 추가하는법
  15. 2011.07.18 [iphone] NSMutableArray may not respond to ObjectForKey란 에러메세지
  16. 2011.07.18 [iphone] UITabbarController에서 탭을 선택했을때 항상 Reload, Refresh하기
  17. 2011.07.14 [iphone] string append하기
  18. 2011.07.14 [iphone] Singletone Class만들기
  19. 2011.07.13 [iphone] UITableView에 Data를 넣어보자.
  20. 2011.07.12 [xcode] 간단하게 UITableView를 써보자.
  21. 2011.07.12 바람 입력기와 ecto 블러그 writer
  22. 2011.06.23 [object-c] 컬렉션 사용하기 NSValue NSMutableArray 를 이용
  23. 2011.06.21 [Mac] 맥에서 Home/End 키 사용하기
  24. 2011.06.17 [xcode] 아이폰에서 버튼 이벤트 발생시키기 2
  25. 2011.06.16 [wcf] Service Trace Viewer를 이용하여 디버깅하기
  26. 2011.06.16 [WCF] WCF Rest 에서 Image File Upload 하기 2
  27. 2011.05.31 [wcf] c#에서 프로시저 실행하기
  28. 2011.05.31 [db] 간단한 프로시저 만들기
  29. 2011.05.27 [WP7] Toast Notification 만드는법 4 (Mango Ver)
  30. 2011.05.27 [WP7] Toast Notification 만드는법 3 (Mango Ver)
wcf2011. 8. 12. 14:04

일단 프로그램 추가 삭제에서 필요한거 asp.net wcf와 관련된것들을 다  체크 하고 설치를 하고


iis에서도 applciation pool 2.0으로 되어 있는것을 4.0으로 바꾸었으나


자꾸

HTTP Error 404.0 - Not Found

The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

이런 에러가 났었다. ㅡ.ㅡ;;


검색해보니

If ASP.NET v2.0.xxx does not appear in Web Services do:

start/Run/cmd:

cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727

(where Windows is your windows directory and .50727 is your .NET version)

aspnet_regiis –ir


이렇게 하란다고 해서 했더니 바로 됨 ㅡ.ㅡ;; 예전에도 이렇게 했었는데 까먹었음 

난 4.0이니 저위에 폴더를 4.0으로 가야 한다.

Posted by 동동(이재동)
iPhone App2011. 8. 9. 13:06

서버는 그냥 윈도우에서 편하게 쓸수 있는 virtual svn을 깔았다.

그리고 클라이언트는 거북이 svn client랑 비슷한

맥용 SVN Client SCplungin을 설치하였다.

하지만 checkout을 할려고 했지만 잘되지 않았다.

SCPlugin giving the message "Server certificate verification failed: certificate issued for a different hostname, issuer is not trusted" on first checkout

이런 에러가 났던것이다.

해결법은

1. Open Terminal (in Utilities, in Applications)

2. Type some svn command against your repository, say "svn ls https://82.100.10.110/svn/Superscout"

3. You'll get a text prompt about the server's certificate, asking you what to do

4. Type "p" (and return), meaning "permanently accept this certificate anyway"

이렇게 터미널 널어서 저렇게 쓰고 p를 누르면 된다. 권한 문제인듯하다

참고 : http://old.nabble.com/SCPlugin-giving-the-message-%22Server-certificate-verification-failed%3A--certificate-issued-for-a-different-hostname,-issuer-is-not-trusted%22-on-first--checkout-td25809151.html

Posted by 동동(이재동)
iPhone App2011. 7. 28. 13:48

내가 하고 싶엇던것은 글쓰기 댓글달기 창을 modal 뷰로 띄우고 저장하면 창이 없어지면서 tableview가 refresh되기를 원했었다.

아직 잘모르겠따

http://stackoverflow.com/questions/2412688/uiviewcontroller-parentviewcontroller-access-properties

여기랑

상위view에서 하위view 만들때 delegate를 이용하자

self.downViewController = [[DownViewController alloc]

initWithNibName:@"DownView" bundle:nil];

self.downViewController.delegate = self;

...

하위view에서 상위view의 Controller사용

[delegate presentModalViewController:self.downTwoViewController animated:YES];

이래 하면 delegate가 상위view의 Controller가 됨  

이걸 참조해보자.

http://liebus.tistory.com/entry/상위-view-의-Controller를-사용하고자-할때

---------------------------------------------------------------------------------------------------

새롭게 해보자.

목적: child navigation 메뉴에서 Save를 눌렀을때 parent navgationViewControoler의 Table을 Reload 하는 메소드를 호출하는것

일단 팝업이나 네비게이션 된 자식 헤더에

@property (nonatomic,retain) HugeBoardViewController *hugeboardViewController;


이렇게 parentController를 추가하고


저장버튼에

hugeboardViewController = [self.navigationController.viewControllers objectAtIndex:0];

hugeboardViewController ReloadBoardData];


이렇게 구현했다.

Posted by 동동(이재동)
iPhone App2011. 7. 27. 17:18

일단 UITableViewCell Class를 하나 만들고 Empty Xib 파일도 만든다.

201107271711.jpg

일단 뷰에 UITableViewCell을 추가하고

그뒤 저렇게 Files'Owner에서 class를 UIViewController로 바꾼다.

이번에는 UITableViewCell에 가서


201107271715.jpg

이렇게 바꾸고


201107271716.jpg

identifer도 바꾼다. 바꾸면 이렇게 된다.


201107271716.jpg

자 이제 클래스 파일을 수정하자

헤더파일이다

#import <UIKit/UIKit.h>


#define HugeBoardCellIdentifier @"HugeBoardCellIdentifier"


@interface HugeBoardCell : UITableViewCell {

IBOutlet UILabel *titleLabel;

IBOutlet UILabel *idxLabel;

}


@property (nonatomic,retain) IBOutlet UILabel *titleLabel;

@property (nonatomic,retain) IBOutlet UILabel *idxLabel;

+ (id)cellWithNib;


@end


딴건 중요하지 않고 cellWithNib이 중요하다
실제 구현부에

+ (id)cellWithNib

{

HugeBoardCell *cell;

UIViewController *controller = [[UIViewController alloc] initWithNibName:@"HugeBoardCell" bundle:nil];

cell = (HugeBoardCell *)controller.view;

[controller release];

return cell;

}


이렇게 추가한다.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

  HugeBoardCell *cell = (HugeBoardCell *)[tableView dequeueReusableCellWithIdentifier:HugeBoardCellIdentifier];

  

if (cell == nil) {   

cell = [HugeBoardCell cellWithNib];   

}

HugeBoardData* hd = [boardData objectAtIndex:indexPath.row];

cell.titleLabel.text = [NSString stringWithFormat:@"%@", hd.title];

cell.idxLabel.text= [NSString stringWithFormat:@"%@ : ", hd.idx];


실제 사용하는부분에 이렇게 사용했다 ,
Posted by 동동(이재동)
iPhone App2011. 7. 27. 11:35

일단 xcode 4를 위주로 설명하겠다.

지금까지 메모리 관리가 엉망이었다. 메모리 관리를 철저하게 하지 안흐면

계속 사용할때마다 메모리를 먹기때문에 나중에 문제가 생긴다.

그래서 코딩후 항상 체크하는 습관을 가지면 좋다.

일단 prouct의 profile을 클릭한다 단축키가 더 편하다 커맨드+I

201107271128.jpg  

Leaks를 선택한다.

그러면 시뮬레이터가 뜨고 막 이리저리 사용해본다.


201107271132.jpg

그러면 이렇게 뜨는데 snapshot interval이 기본은 10으로 되어있는데 좀더 세밀하게 관찰하기 위해서 좀더 줄인다 나는 5정도로 했다.

그리고 leaks를 클릭 해서 보면 저렇게 메모리 관련 오류가 나온다 그쪽에서 responsible Library를 클릭하면 프로젝트 별로 죽 뜨는데

그쪽에서 현재 자기가 진행하는 프로젝트 이름만 보면 된다.

그뒤 더블 클릭하면 오류가 난 코드가 있는쪽으로 바로간다. 그쪽에서 혹시 메모리관리를 잘못했는지 확인해보자.

Posted by 동동(이재동)
iPhone App2011. 7. 27. 11:19

저번에 XML에 파싱 부분을 올렸었다 소스를 올렸지만 그렇게 되면 메모리 관리가 제대로 안돼서 다시 만들었다.

일단 지난 번 코드를 보자

-(NSMutableArray*) parseContent:(NSURL*) url

{

NSXMLParser* xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

[xmlParser setDelegate:self];

  

_hugeBoardDataArray =[NSMutableArray arrayWithCapacity:1024];

_elementStack = [NSMutableArray arrayWithCapacity:1024];

[xmlParser parse];

return _hugeBoardDataArray;

}

@end

보면 엉망이다 일단 arrayWithCapacity를 마땅히 쓸필요가 없고 _hugeBoardDataArray와 ElementStack을

- (id) init

{

if((self = [super init]) != nil)

{

_hugeBoardDataArray = [[NSMutableArray alloc] init];

_elementStack = [[NSMutableArray alloc] init];

}

  

return self;

}

생성자에서 이렇게 처리 하였다.


그리고 이부분은

-(NSMutableArray*) parseContent:(NSURL*) url

{

NSXMLParser* xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

[xmlParser setDelegate:self];

[xmlParser parse];

[xmlParser release];

  

return [NSMutableArray arrayWithArray:_hugeBoardDataArray];

}

이렇게 고쳤다.

return 부분이 포인트다 무언가를 리턴할때 꼭 autoRelase로 만들어서 리턴해야 한다는 것을 깨달았다.

arraywitharray를 쓴이유다 만약 그냥 _hugeBoardDataArray를 리턴하게 되면 release를 해줘야 하는 타입임으로

저렇게 넣어서 했다.


그리고 data쪽도 new로 받았었는데

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

{

if([elementName isEqualToString:@”HugeBoardInfo”] == TRUE)

{

HugeBoardData *data = [[HugeBoardData alloc] init];

[_elementStack addObject:data];

[data release];

}

else if([elementName isEqualToString:@”idx”] || [elementName isEqualToString:@”Name”] || [elementName isEqualToString:@”Title”] || [elementName isEqualToString:@”Description” ] || [elementName isEqualToString:@”Date”])

{

NSString *element = [NSString stringWithString:elementName];

[_elementStack addObject:element];

}

}

저렇게 alloc로 받도록 수정하였다.


마지막으로

-(void) dealloc

{

[super dealloc];

[_hugeBoardDataArray release];

[_elementStack release];

}

이렇게 메모리 해제는 꼭 해줘야 한다.




Posted by 동동(이재동)
iPhone App2011. 7. 26. 16:13

product창을 클릭후 Edit Scheme를 클릭



201107261612.jpg

이렇게 app에 가서 Arguments에 간후 NSZombieEnabled와 NSDebugEnabled를 YES로 하면

메모리 오류가 날시 어디서 에러가 났는지 알려준다.

참고한곳 http://mellang.tistory.com/12

Posted by 동동(이재동)
iPhone App2011. 7. 26. 14:17

네이버 카페 어플 이나 기타 글쓰는 어플 보면 네비게이션 보다는 ModelView를 이용해서 현재 뷰위에 뷰를 띄우는 방식을

이용을 많이 사용했다.

그래서 나도 리플을 다는곳에 그냥 ModelView를 이용해 보았다.

너무 쉬웠다. 애플이 참 sdk를 잘만들었구나 싶은 생각이 들었다.

-(void)WriteReply{

ReplyEditView* replyEditView = [[[ReplyEditView alloc]init] initWithNibName:@"ReplyEditView" bundle:nil];

[self presentModalViewController:replyEditView animated:YES];

[replyEditView release];

}


그냥 이부분만 넣으면 된다.

[self presentModalViewController:replyEditView animated:YES];


그럼 닫고 싶을때는 어떻게?


-(void)cancel

{

[self dismissModalViewControllerAnimated:YES];

}



참고한곳 : http://blog.daum.net/urilove0314/8033115

Posted by 동동(이재동)
iPhone App2011. 7. 25. 18:31

대부분 책들은 UIViewController를 만들지 않고 바로 UITableViewController를 바로 상속받아서 사용하였다.

지금은 UIBiewController 에 여러 컨트롤들과 함께 UITableView를 Insert하는 형식으로 만들어보자.

일단 xib view에 TableView를 하나 만들어서 넣자

@interface DetailView : UIViewController <UITableViewDelegate,UITableViewDataSource>{

   IBOutlet UITableView *descriptionTableView;  

NSMutableArray *data;

}


그뒤 UITableViewDelegate,UITableViewDataSource 프로토콜을 이용하자


- (void)viewDidLoad

{

[super viewDidLoad];

descriptionTableView.delegate = self;

descriptionTableView.dataSource = self;

}


viewdidload에 이렇게 추가하고


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath


필수 2개 델리게이트를 구현하면 된다 끝~


참고한곳 : http://iwoohaha.tistory.com/156





Posted by 동동(이재동)
iPhone App2011. 7. 25. 18:23

iphone에서 이용하기 위해서는 일단 xib에 UIScrollVier

201107251821.jpg

이런식으로 넣고

ViewDIDLoad에

- (void)viewDidLoad

{

[super viewDidLoad];

// Do any additional setup after loading the view from its nib.

  

descriptionTextView.text = hugeBoardData.description;

  

  

   scrollview.frame = CGRectMake(0, 0, 320, 460);

scrollview.contentSize = CGSizeMake(320, 800);


이렇게 rect를 만든다.그러면 화면이 스크롤이 된다.
참고한곳 : http://www.roseindia.net/tutorial/iphone/tutorial/iphone/UIScrollView-Example-iPhone.html
Posted by 동동(이재동)
iPhone App2011. 7. 22. 18:51

일단 내가 하고 싶었던것은 GET방식의 URL을 HttpRequest 를 해서 WCF에 전송하게 한뒤 글을 쓰게 만드는것이 목표였다.

일단 헤더에 NSMutableData를 만들고

-(void) save{

responseData = [NSMutableData new];

NSString *serviceURL = [NSString stringWithFormat:@"http://192.168.10.3:9090/hugeboardservice/write?name=%@&title=%@&description=%@",

[self encodeString:nameTextField.text],

[self encodeString:titleTextField.text],

[self encodeString:descriptionTextView.text]];


NSURL *url = [NSURL URLWithString:serviceURL];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];

  

[request setHTTPMethod:@"GET"];

  

[[NSURLConnection alloc] initWithRequest:request delegate:self];

[self.navigationController popViewControllerAnimated:YES];

}


이렇게 했다 저기 위에 보면 NSURLConnectino을 delegate 받았다.


그래서 추가적으로 4개의 델리게이트 메소드를 만들었다.


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

[responseData setLength:0];

}


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

[responseData appendData:data];

}


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

[connection release];

  

NSString* responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];

NSLog(@"the html from google was %@", responseString);

  

[responseString release];

}


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

NSLog(@"something very bad happened here");

}


참고한곳은 http://toranbillups.com/blog/archive/2011/04/10/Writing-your-first-http-request-in-objective-c


여기이다.

하지만 이렇게 하다보니 문제가 생겼다 한글을 파라미터로 하면 오류가 났던것이다. 아마 인코딩을 안해서 그렇다고 생각해서


//한글떄문에 엔코딩하기 위해서 만든 메소드

-(NSString *)encodeString: (NSString*) unencodedString{

NSString *temp = (NSString *)CFURLCreateStringByAddingPercentEscapes(

NULL,

(CFStringRef)unencodedString,

NULL,

(CFStringRef)@"!*'();:@&=+$,/?%#[]",

kCFStringEncodingUTF8 );

  

return temp;

}


이런 메소드를 추가로 만들었다
만드는데 참고한 사이트는
http://simonwoodside.com/weblog/2009/4/22/how_to_really_url_encode/


***추가***

save를 하고 뒤로 가기 위해서 save메소드에 

[self.navigationController popViewControllerAnimated:YES];

이걸 넣었는데

여기에 넣는게 아니라 

- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { [responseData setLength:0]; [self.navigationController popViewControllerAnimated:YES]; }

이쪽에 넣는것이 맞다. 한마디로 작업이 완료가 되면 뒤로 넘어가야지 바로 넘어가면 안되는것이다.

참고 : http://www.pcraft.kr/101


Posted by 동동(이재동)
iPhone App2011. 7. 22. 15:28

이것참... 역시 책으로 공부하면 안되는것이다.

책에서 tableview에 내용을 넣을때 array에 넣고 안에 딕션널리 컬렉션류를 넣어서 항상 forkey를 이용하게 했었다.

그래서 이번에 xml을 파싱하여 tableview로 보여줬어야 했는데 NSObject 클래스로 만들어서 안에 있는 내용을 보여줄려고 해서

key를 쓸려니까 잘안되었다.

말로는 설명이 힘드니 직접 코드를 보자..

@interface HugeBoardData : NSObject {

NSString* _idx;

NSString* _name;

NSString* _title;

NSString* _description;

NSString* _date;

}


@property(nonatomic,retain) NSString* idx;

@property(nonatomic,retain) NSString* name;

@property(nonatomic,retain) NSString* title;

@property(nonatomic,retain) NSString* description;

@property(nonatomic,retain) NSString* date;

이런 데이터 구조를 가진 object class가 있다 여기에 데이터를 집어넣고

HugeBoardData *data = (HugeBoardData*)parentElement;

if([element isEqualToString:@"idx"])

{

data.idx = trimmedValue;

}

else if([element isEqualToString:@"Name"])

{

data.name = trimmedValue;

}

else if([element isEqualToString:@"Title"])

{

data.title = trimmedValue;

}

else if([element isEqualToString:@"Description"])

{

data.description = trimmedValue;

}

else if([element isEqualToString:@"Date"])

{

data.date = trimmedValue;

}

이런식으로 집어넣고 tableiew delegate에서

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

  

static NSString *CellIdentifier = @"Cell";

  

//UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];

  

if (cell == nil) {

cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

}


HugeBoardData* hd = [data objectAtIndex:indexPath.row];

  

cell.textLabel.text = [NSString stringWithFormat:@"%@. %@", hd.idx, hd.title];

cell.detailTextLabel.text = [NSString stringWithFormat:@"%@", hd.name];


return cell;

}


이렇게

HugeBoardData* hd = [data objectAtIndex:indexPath.row];

하고 하나씩 꺼내 쓰면 된다 그러면 원하는 idx,title,name등을 골라서 뽑아 쓰면 된다.

막상 인터넷에도 없고 책에는 다 딕셔널리로 되어 있어서 상당히 헷갈렸던 부분이다.

앞으로 array안에 꼭 데이터를 저렇게 넣고 빼서 써야겠다 어찌보면 간단한건데 헷갈렸던것이다.


Posted by 동동(이재동)
iPhone App2011. 7. 21. 18:15

아이폰에서 XML을 파싱하기 위해서는 여러가지 방법이 있다.

라이브러리를 이용하는 방법(touchXML,KISSXML등등)과 NSXMLParser를 이용하는 방법이 있다.

아이폰이 아닌 그냥 맥개발에서는 NSXMLDocument가 있어서 편하게 쓸수 있다고 하는데 아무튼.. 그냥 힘든방법으로 가자.

c#으로 개발했을때는 시리얼라이즈가 있어서 클래스만 만들면 자동으로 xml을 만들고 파싱하고 아주 편했다.

하지만 Iphone Objective-C는........ㅠ.ㅠ

일단 WCF Rest서비스를 만들어서 DB내용을 XML로 동적으로 뿌려주기 위한 서비스를 만들었다.

그래서 파싱할 xml은 이렇다.

<ArrayOfHugeBoardInfo xmlns="http://schemas.datacontract.org/2004/07/HugeBoardService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

<HugeBoardInfo>

<Date>2010-02-02T00:00:00</Date>

<Description>hi</Description>

<Name>leejaedong</Name>

<Title>hi</Title>

<idx>1</idx>

</HugeBoardInfo>

일단 이 데이터를 저장할 클래스부터 만들자 C#이랑 비슷하다 여기까지는

@interface HugeBoardData : NSObject {

NSString* _idx;

NSString* _name;

NSString* _title;

NSString* _description;

NSString* _date;

}


@property(copy) NSString* idx;

@property(copy) NSString* name;

@property(copy) NSString* title;

@property(copy) NSString* description;

@property(copy) NSString* date;



@end

헤더에 이렇게 넣고

@implementation HugeBoardData

@synthesize idx= _idx;

@synthesize name= _name;

@synthesize title= _title;

@synthesize description = _description;

@synthesize date= _date;

@end


구현부에 구현을 하자

그다음 일단 Xml을 파싱을 전문적으로 하는 class를 만들자.

@interface HugeBoardXmlParser : NSObject<NSXMLParserDelegate> {

NSXMLParser *parser;

NSMutableArray *_hugeBoardDataArray;

NSMutableArray *_elementStack;

}


@property (nonatomic,retain) NSXMLParser *parser;

-(NSMutableArray*)parseContent: (NSURL*) url;

@end


이름을 HugeBoardXmlParser라 만들고 NSXMLParser 델리게이트를 참조 하였다.그리고 XML을 parser할 NSXMLParser와 xml파일의 모든 데이터를 저장할 hugeboardDataArray그리고 elementStack이라고 해서 한줄한줄 읽을때마다 저장해서 이게 어떤 노드에 있고 어떤값지를 임시로 저장해놓는 array이다

#import "HugeBoardXmlParser.h"

#import "HugeBoardData.h"


@implementation HugeBoardXmlParser


@synthesize parser;


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

{

if([elementName isEqualToString:@"HugeBoardInfo"] == TRUE)

{

HugeBoardData *data = [HugeBoardData new];

[_elementStack addObject:data];

}

else if([elementName isEqualToString:@"idx"] || [elementName isEqualToString:@"Name"] || [elementName isEqualToString:@"Title"] || [elementName isEqualToString:@"Description" ] || [elementName isEqualToString:@"Date"])

{

NSString *element = [NSString stringWithString:elementName];

[_elementStack addObject:element];

}

}


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName

{

if([elementName isEqualToString:@"HugeBoardInfo"] == TRUE)

{

HugeBoardData *data =(HugeBoardData*)[_elementStack lastObject];

[_hugeBoardDataArray addObject:data];

[_elementStack removeLastObject];

}

else if([elementName isEqualToString:@"idx"] || [elementName isEqualToString:@"Name"] || [elementName isEqualToString:@"Title"] || [elementName isEqualToString:@"Description" ] || [elementName isEqualToString:@"Date"])

{

[_elementStack removeLastObject];

}

  

}


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

{

//trim 쓰자면 이걸 쓰고 안하면 그냥 string 값을 넣어도 된다.

NSCharacterSet *characterSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];

NSString *trimmedValue = [string stringByTrimmingCharactersInSet:characterSet];

if([trimmedValue length] == 0)

{

return;

}

  

id element = [_elementStack lastObject];

if([element isKindOfClass:[NSString class]])

{

NSUInteger count = [_elementStack count];

NSUInteger index = count -2;

id parentElement = [_elementStack objectAtIndex:index];


HugeBoardData *data = (HugeBoardData*)parentElement;

if([element isEqualToString:@"idx"])

{

data.idx = trimmedValue;

}

else if([element isEqualToString:@"Name"])

{

data.name = trimmedValue;

}

else if([element isEqualToString:@"Title"])

{

data.title = trimmedValue;

}

else if([element isEqualToString:@"Description"])

{

data.description = trimmedValue;

}

else if([element isEqualToString:@"Date"])

{

data.date = trimmedValue;

}

}

}

-(NSMutableArray*) parseContent:(NSURL*) url

{

NSXMLParser* xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

[xmlParser setDelegate:self];

  

_hugeBoardDataArray =[NSMutableArray arrayWithCapacity:1024];

_elementStack = [NSMutableArray arrayWithCapacity:1024];

[xmlParser parse];

return _hugeBoardDataArray;

}

@end


이것은 구현부이다.
하나씩 알아보자.일단 파싱을 하기 위해서 필요한 3가지 델리게이트가 있다.첫째 이부분이다.

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

{

if([elementName isEqualToString:@"HugeBoardInfo"] == TRUE)

{

HugeBoardData *data = [HugeBoardData new];

[_elementStack addObject:data];

}

else if([elementName isEqualToString:@"idx"] || [elementName isEqualToString:@"Name"] || [elementName isEqualToString:@"Title"] || [elementName isEqualToString:@"Description" ] || [elementName isEqualToString:@"Date"])

{

NSString *element = [NSString stringWithString:elementName];

[_elementStack addObject:element];

}

}

초반 엘리먼트를 읽는다. 우린 이것을 일단 모두 저장한다. 어디에? elementStack에

그다음 호출되는것은 이거다

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

{

//trim 쓰자면 이걸 쓰고 안하면 그냥 string 값을 넣어도 된다.

NSCharacterSet *characterSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];

NSString *trimmedValue = [string stringByTrimmingCharactersInSet:characterSet];

if([trimmedValue length] == 0)

{

return;

}

  

id element = [_elementStack lastObject];

if([element isKindOfClass:[NSString class]])

{

NSUInteger count = [_elementStack count];

NSUInteger index = count -2;

id parentElement = [_elementStack objectAtIndex:index];


HugeBoardData *data = (HugeBoardData*)parentElement;

if([element isEqualToString:@"idx"])

{

data.idx = trimmedValue;

}

else if([element isEqualToString:@"Name"])

{

data.name = trimmedValue;

}

else if([element isEqualToString:@"Title"])

{

data.title = trimmedValue;

}

else if([element isEqualToString:@"Description"])

{

data.description = trimmedValue;

}

else if([element isEqualToString:@"Date"])

{

data.date = trimmedValue;

}

}

}


실제 Value값을 여기서 얻을수가 있는데 아까 처음에 _elementStack에 저장했던 값을 분석해서 HugeBoardData라는 아까 만든 저장형 클래스에 담는다. trimmedValiue대신에 string을 넣어도 된다.
마지막으로 호출되는것은 이것이다.

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName

{

if([elementName isEqualToString:@"HugeBoardInfo"] == TRUE)

{

HugeBoardData *data =(HugeBoardData*)[_elementStack lastObject];

[_hugeBoardDataArray addObject:data];

[_elementStack removeLastObject];

}

else if([elementName isEqualToString:@"idx"] || [elementName isEqualToString:@"Name"] || [elementName isEqualToString:@"Title"] || [elementName isEqualToString:@"Description" ] || [elementName isEqualToString:@"Date"])

{

[_elementStack removeLastObject];

}

}


여기서하는것은 아까 foundCharacters에서 저장한 HugeBoardData를 _HugeBoardDataArray에 저장한다. 여기까지가 한텀이 끝난것이다. 이제 아마 같은 방식으로 계속 한텀한텀씩 저장해서 모든 xml데이터를 _hugeBoardDataArray에 저장할것이다.한텀이 끝났으면 다음텀을 위해서 _elementStack을 삭제한다. 이렇게 3개의 델리게이트 메소드가 계속 호출되면서 반복된다.
이제 이 모든기능을 작동되게 만드는 외부에서 호출 당하는 메소드를 보자

-(NSMutableArray*) parseContent:(NSURL*) url

{

NSXMLParser* xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

[xmlParser setDelegate:self];

  

_hugeBoardDataArray =[NSMutableArray arrayWithCapacity:1024];

_elementStack = [NSMutableArray arrayWithCapacity:1024];

[xmlParser parse];

return _hugeBoardDataArray;

}


여기보면 xmlParser를 작동되게 하고 모든 xmlData를 포함하는 _hugeBoardDataArray를 리턴한다.
그래서 외부에서 사용할려면

NSURL *XMLURL =[NSURL URLWithString:@"http://192.168.10.3:9090/hugeboardService/getboardinfo"];

HugeBoardXmlParser* parser = [[HugeBoardXmlParser alloc] init];

NSMutableArray *hugeboardArr = [parser parseContent:XMLURL];


이렇게 하면 된다. 그럼 hugeBoardArr에 모든 데이터가 저장될것이다.



참고 한 사이트 : http://kiipos.delimount.net/1084

Posted by 동동(이재동)
iPhone App2011. 7. 19. 16:26

viewdidload에 이런식으로 추가하고


action쪽에 onadd를 등록했다.


- (void)viewDidLoad

{

[super viewDidLoad];

  

UIBarButtonItem* toAdd=[[UIBarButtonItem alloc] initWithTitle:@"음식 추가" style:UIBarButtonItemStylePlain target:self action:@selector(onAdd)];

self.navigationItem.rightBarButtonItem = toAdd;

   [toAdd release];

.

.

}

그리고 이렇게 아까 action에 쓴 onAdd 메소드를 구현하면 된다.

- (void)onAdd

{

NSLog(@"hi");

}

Posted by 동동(이재동)
iPhone App2011. 7. 18. 14:58

코딩을 하다보니 이런 경고가 계속 떠서 짜증났다.

이런 경고를 없애기 위해서 인터넷 찾아보니

for문 in을 쓸때(c#에서는 foreach) NSmutableArray 컬렉션으로

   for(NSMutableArray *item in afd.foodData)

{

NSNumber *calrorie = [NSNumber numberWithInt:[[item objectForKey:@"calrorie"] intValue]];

count = [NSNumber numberWithInt:[count intValue]+[calrorie intValue]];

NSString *name = [NSString stringWithString:[item objectForKey:@"name"]];

[totalName appendFormat:@"%@ (%d) Cal \n",name,[calrorie intValue]];

}


이런식으로 하니 경고가 발생했다 그래서

   for(NSMutableDictionary *item in afd.foodData)

{

NSNumber *calrorie = [NSNumber numberWithInt:[[item objectForKey:@"calrorie"] intValue]];

count = [NSNumber numberWithInt:[count intValue]+[calrorie intValue]];

NSString *name = [NSString stringWithString:[item objectForKey:@"name"]];

[totalName appendFormat:@"%@ (%d) Cal \n",name,[calrorie intValue]];

}


이렇게 수정하니 경고가 사라졌다.
참고 : http://stackoverflow.com/questions/6196688/how-to-resolve-nsmutablearray-may-not-respond-to-objectforkey
Posted by 동동(이재동)
iPhone App2011. 7. 18. 13:39

샘플로 칼로리 계산기를 만들면서 Tab을 클릭하면 항상 새로운 데이터를 다시 로드하는 것을 하고 싶었다.

인터넷 찾아보니

- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {

NSLog(@"didSelectViewController : %@",viewController);

}


이런 delegate를 사용하란다. 이것을 호출하기 위해서 헤더에 프로토콜을 추가하고 이렇게

interface CalrorieCalAppDelegate : NSObject <UIApplicationDelegate,UITabBarControllerDelegate> {


IBOutlet UITabBarController *tabBar;

}


이 delegate를 꼭 추가해준다 구현부에
[self.tabBar setDelegate:self];
추가한 곳은 아래와 같다.    

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

{

// Override point for customization after application launch.

//self.window.rootViewController = self.viewController;

self.window.rootViewController = self.tabBar;

[self.tabBar setDelegate:self];

[self.window makeKeyAndVisible];

return YES;

}



하지만 이것보다 더 좋은 방법이 있다. 바로


-(void) viewWillAppear:(BOOL)animated


이걸 이용한 방법이다. view에서 override 해서 쓴다.

tab을 읽기전에 항상 호출된다.


자 이곳에서 refresh를 해주자.


-(void) viewWillAppear:(BOOL)animated

{

AteFoodData* afd = [AteFoodData sharedSingletonClass];

count = [[NSNumber alloc] init];

NSMutableString *totalName = [NSMutableString stringWithString:@"음식 이름\n\n"];

for(NSArray *item in afd.foodData)

{

NSNumber *calrorie = [NSNumber numberWithInt:[[item objectForKey:@"calrorie"] intValue]];

count = [NSNumber numberWithInt:[count intValue]+[calrorie intValue]];

NSString *name = [NSString stringWithString:[item objectForKey:@"name"]];

[totalName appendFormat:@"%@ (%d) Cal \n",name,[calrorie intValue]];

}

  

resultTextView.text = [NSString stringWithFormat:totalName];

resultLabel.text = [NSString stringWithFormat:@"당신이 섭취한 칼로리는? (%d칼로리)",[count intValue]];

}


이렇게 하면 탭을 눌렀을때 항상 값을 읽어온다.
여담이지만 여기서 메모리 에러가 나서 고생했었는데 count를 전역변수로 해서 쓰는데 header에서 NSNumber로 해서정의했지만
count = [[NSNumber alloc] init];

이렇게 count를 초기화를 안해줘서 메모리 에러가 났었다. 항상 초기화를 해주자.!!






Posted by 동동(이재동)
iPhone App2011. 7. 14. 17:07

스트링을 append할때

NSString에 stringAppendingString인가 를 쓰니까 안붙어져서

NSMutableString을 쓰니까 잘 된다.

NSString *name = [NSString stringWithString:[item objectForKey:@"name"]];

[totalName appendFormat:@"%@ "name];


이런식으로
appendFormat을 이용하자
그리고 줄 바꿀려면 \n 을 이용하면 된다.
Posted by 동동(이재동)
iPhone App2011. 7. 14. 11:29

요즘 다이어트 시대를 맞이해 연습차 칼로리 계산기를 만들어 보았다.

근데 칼로리를 지속적으로 저장해야 하는데 c# 같은경우는 그냥 static class 하나 만들어서 저장을 했는데

objective c에서도 있었다.

// SingletonClass.h

#import <Foundation/Foundation.h>

@interface SingletonClass : NSObject

{

}

+ (SingletonClass *)sharedSingletonClass;

@end

일단 이렇게 헤더 class를 만들고

// SingletonClass.m

#import "SingletonClass.h"

@implementation SingletonClass

+ (SingletonClass *)sharedSingletonClass

{

   static SingletonClass *singletonClass = nil;

  

   if(singletonClass == nil)

   {

   @synchronized(self)

   {

   if(singletonClass == nil)

   {

   singletonClass = [[self alloc] init];

   }

   }

   }

  

   return singletonClass;

}

@end

구현부에 이렇게 하면 된다.

사용은

SingletonClass *s = [SingletonClass sharedSingletonClass];

이렇게 하면 된다.

이렇게 하면 클래스 인스턴스를 한번만 생성되어서 어디서나 클래스를 만들어도

스태틱한 class가 되는것이다.

참고 : http://b4you.net/blog/210

Posted by 동동(이재동)
iPhone App2011. 7. 13. 11:10

값을 넣는대는 프로퍼티를 이용해서 값을 return 해주는방법과

- (void)viewDidLoad

{

[super viewDidLoad];

if (data==nil) {

data = [[[NSMutableArray alloc] init ]retain];

[data addObject:[NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"핫식스",[NSNumber numberWithInt:7000], nil] forKeys:KEYS]];

}

}


이렇게 view가 로드되고 넣어주는 방법이 있다.


내생각에는 후자가 메모리 관리상 나을것 같다.


그뒤에 row를 보여주는곳에는


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

   }

  


cell.textLabel.text = [NSString stringWithFormat:@"%@ (%d칼로리)",

[[data objectAtIndex:indexPath.row] objectForKey:@"name"],

   [[[data objectAtIndex:indexPath.row] objectForKey:@"price"] intValue]];

  


return cell;

}



이렇게 하자.


Posted by 동동(이재동)
iPhone App2011. 7. 12. 18:07

맥은 참 나를 힘들게하는거 같다.

이번에 xcode 4를 깔았는데 이게 더 나은거 같다. 이건 중요하지 않고

일단 xib 에서 tableView를 하나 만들고.. 기존에 View가 있으면 지우고 만든다.

그다음에 오른쪽 버튼으로 연결후

헤더에서

#import <UIKit/UIKit.h>


@interface CalrorieCalViewController : UITableViewController {

NSMutableArray *data;

}


@property (nonatomic, retain) NSMutableArray* data;

@end


이런식으로 바꾼다.


그뒤에


-(NSMutableArray*) data {

if (data==nil) {

data = [[NSMutableArray alloc] init];

[data addObject:[NSMutableDictionary dictionaryWithObject:@"핫식스" forKey:@"name"]];

[data addObject:[NSMutableDictionary dictionaryWithObject:@"NF소나타" forKey:@"name"]];

  

}

return data;

}


이렇게 data를 만들고


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {


return [self.data 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];

}

  

cell.textLabel.text = [[self.data objectAtIndex:indexPath.row] objectForKey:@"name"];

return cell;

}


이렇게 row를 돌면서 데이터를 뿌려준다.
마지막으로

- (void)viewDidUnload

{

[super viewDidUnload];

self.data = nil;

// Release any retained subviews of the main view.

// e.g. self.myOutlet = nil;

}


이렇게 해제하자


Posted by 동동(이재동)
Mac2011. 7. 12. 13:05

최근 shift+space 로 한영을 전환하기 위해 별도의 셋팅 없이 바람 입력기로

된다고 해서 깔았다. 최신버전 베타를 깔아야만 했다 레오파드 였기때문에

그리고 지금 쓰고 있는건 블러그 writer ecto이다..

머 그럭저럭 쓸만하다.

계정만들때 MovableType으로 선택하고 그냥 쭉 하면 된다.

Posted by 동동(이재동)
iPhone App2011. 6. 23. 15:02

반 구조체 같은 경우 컬렉션에 넣을수 없다.

예를 들면 NSRect같은것은 바로 array에 addObject로 넣으면 안들어가기때문에 NSValue로 한번 감싸서 넣어준다.

물론 숫자 int,float등도 바로 넣을수 없기떄문에 NSNumber로 한번 감싸서 넣어준다.

NSMutableArray *mutableArray= [NSMutableArray arrayWithCapacity:2];

NSRect rect = NSMakeRect (1, 2, 30, 40);

NSValue *value;

value = [NSValue valueWithBytes:&rect objCType: @encode(NSRect)];

[mutableArray addObject: value];

NSValue *value2; NSRect rect2;

value2 = [mutableArray objectAtIndex: 0];

[value2 getValue: &rect2];

NSLog(@"Data %f %f",rect2.size.width,rect2.size.height); 

Posted by 동동(이재동)
Mac2011. 6. 21. 16:48

맥에서는 기본적으로 사용이 되지 않는다 

매일 그냥 커맨드+ 화살표로 깔짝깔짝 되었는데

검색해보니 방법이 있더라...

url만 써 놓자

http://delpini.egloos.com/2259297



Posted by 동동(이재동)
iPhone App2011. 6. 17. 14:34

음 이것저것 해보았지만 역시 잘 정리된 사이트가 별로 없었다.

 

자 내가 한번 해보자.

 

이번 목표는 버튼을 클릭했을 때 웹 페이지를 띄우는 것과 Label Text를 변경하는 것이다.

 

일단 난 돈이 없어서 xcode 3.2로 했다. xcode4 빨리 받아야 될텐데

 

일단 하는법은 View-based Application으로 프로젝트를 하나 만든후

 

확장자가 xib가 되어있는 것을 더블 클릭한다. 그러면 View가 뜰것이다.

 

여기서 Label이랑 Button을 하나씩 추가 한다.

 

자 이제 ViewController.h 헤더 파일에서 label과 button을 설정한다.

 

#import <UIKit/UIKit.h>
 
@interface TestHelloWorldViewController : UIViewController {
    IBOutlet UILabel  *myLabel;        
}
@property (nonatomic,retain) IBOutlet UILabel *myLabel;
 
-(IBAction) onGotoTest;
@end

 

인터페이스에 IBoutlet UILabel 에 myLabel이라는 것을 하나 설정하고

@property로 똑같이 하나 잡는다.

 

Label은 이걸로 끝~

 

버튼은 더 간단하다

-(IBAction) onGotoTest로 버튼 이벤트? Action을 정한다.

 

자 코딩을 마쳤으면 다시 View로 돌아가자 View로 돌아가서 헤더에서 만든것을 연결해보자.

 

xib를 클릭하여 view를 보고 일단 내가 만든 버튼에서 오른쪽 버튼을 누르면 Rounded Rect Button이라는 팝업창이 하나 뜬다. 여기서 우리는 터치를할것이니 Touch Up inside에 옆에 동그라미를 마우스로 끌어서 File’s Owner에 집어 넣자

그럼 아까 내가 헤더에서 만든 onGotoTest Button Action을 선택할수 있다. 그러면  끝이다.

 

이번에는 라벨을 컨트롤 하기 위해서 label에서 오른쪽 버튼을 누른후 new referenciong Outlet 옆에 있는 동그라미를 끌어서 file's Owner에 집어 넣는다. 그러면 다시 헤더에서 만들었던 myLabel이 보일것이다 선택하면 두개의 연결은 끝~

 

자이제 실제로 Controller.m에 직접 코딩을 해보자.

 

@synthesize myLabel;
 
-(IBAction)onGotoTest{
    //NSURL *url = [NSURL URLWithString:@"http://www.naver.com"];
//    [[UIApplication sharedApplication] openURL:url];
    myLabel.text=@"jaedong";
     
}

 

@synthesize로 myLabel을 정의 한후

onGotoTest이벤트가 발생하면 즉 버튼이 클릭되면 myLabel 의 Text를 바꾸 었다.

 

흠… 쓰다보니 기초지식이 너무 없네… 일단 object-c부터 파야겠다.

 

아무튼 20분만에 첫 예제 프로그램을 만들어서 기쁘다…!!

 

참고: http://iphoneappsmaker.tistory.com/713

Posted by 동동(이재동)
wcf2011. 6. 16. 15:57

내가 처한 사항은 이랬다.

 

모든것을 WCF Rest서비스로 구축하고 마지막으로 파일 업로드 를 구현하여 로컬에서 서비스를 돌려서

 

했더니 파일 업로드가 잘 작동 되었다.

 

근데 이게 왜 안되는지 IIS에만 서비스를 올리면 WebRequestError 400 Request 에러가 나는것이였다.

 

구글링을 했지만 너무 많은 경우에 수라 포기… 그렇다면 디버깅은 혹시 될까?

 

예전에 iis process(w3wp)를 잡아서 디버깅을 해본적이 있던터라 그걸로 해볼려고 했지만 까먹어서 실패 ㅋㅋ

 

그러다가 우연히 Microsoft Service Trace Viewer를 보게 되었다.

 

참고 :http://blogs.msdn.com/b/aszego/archive/2010/02/01/tool-of-the-month-servicemodeltraceviewer.aspx

 

이걸 사용하면 서비스에서 어떤일이 일어나는지 자세하게 알수 있겠구나 해서 실행을 해보았다.

 

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\SvcTraceViewer.exe에서 실행하면 된다(윈7)

 

자 실행을 하고 open을 할려니 svclog 확장자를 가진 파일이 필요하다.. 아이게 로그 파일이구나라고 순식간에 직감했다.

 

일단 web.config 에 이 부분을 추가한다.

<system.diagnostics>
    <sources>
      <source name="System.ServiceModel" switchValue="Information,ActivityTracing"
          propagateActivity="true">
        <listeners>
          <add name="ServiceModelTraceListener"/>
        </listeners>
      </source>
      <source name="System.Net.Sockets" switchValue="Information">
        <listeners>
          <add name="ServiceModelTraceListener"/>
        </listeners>
      </source>
      <source name="System.Net" switchValue="Information">
        <listeners>
          <add name="ServiceModelTraceListener"/>
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add initializeData="d:\client_tracelog.svclog"
          type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
          name="ServiceModelTraceListener" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack"/>
    </sharedListeners>
    <trace autoflush="true" />
  </system.diagnostics>

 

추가 가 끝나면 저위에 경로 d:\client_tracelog.svclog에 기록될것이다.

 

이것을 open 하면 된다. 그럼 이렇게 에러를 잡을수 있다.

 

 

image

 

내가 왜 파일 업로드가 안되었는지 IIS에서만!!! 확인해보니 폴더 권한이 없었던 것이다!!

 

그래서 폴더 권한을 준후 다시 실행하니 잘되었다.

Posted by 동동(이재동)
wcf2011. 6. 16. 11:55

일단 WCF에서 보자

[WebInvoke(UriTemplate = "FileUpload?FileName={fileName}", Method = "PUT")]
       public void FileUpLoad(string fileName, Stream fileStream)
       {
           FileStream fileToupload = new FileStream("d:\\" + fileName, FileMode.Create);
 
           byte[] byteArray = new byte[10000];
           int byteRead, totalByteRead = 0;
           do
           {
               byteRead = fileStream.Read(byteArray, 0, byteArray.Length);
               totalByteRead += byteRead;
           } while (byteRead > 0);
 
           fileToupload.Write(byteArray, 0, byteArray.Length);
           fileToupload.Close();
           fileToupload.Dispose();
       }

 

일단 이렇게 메소드를 작성해서 file 이름과 stream을 받아서 파일을 경로에 쓴다.

 

method는 put으로 한다.

 

자 이제 끝이다. 이제 WPF에서 호출해보자.

 

 

 

public void ImageUpload(string fileName, string filePath)
        {
            using (WebClient webclient = new WebClient())
            {
                webclient.UploadData(new Uri(string.Format(serverUri + "/FileUpload?FileName={0}",fileName)), "put", GetData(filePath));
            }
        }
 
        private byte[] GetData(string filePath)
        {
            FileStream stream = File.OpenRead(filePath);
 
            byte[] data = new byte[stream.Length];
 
            stream.Read(data, 0, data.Length);
 
            stream.Close();
 
            return data;
        }

 

이렇게 filename과 byte로 변환된 스트림을 WCF로 날려주기만 하면 된다.

Posted by 동동(이재동)
wcf2011. 5. 31. 15:45

프로시저를 만들고 이제 WCF 서비스에서 프로시저를 실행을 하기 위해서 DB 연동을 해야 한다.

 

그냥 프로젝트에서 new item 후 Data 에 linq to sql classes를 선택 한다.

image

 

 

그뒤에 생성된 dbml에 Table과 프로시저를 드래그앤 드랍하면 끝~

image

 

호출은 이렇게 하면 된다.

 

public void InsertSubScriber()
        {
            using (DataClassesDataContext context = new DataClassesDataContext())
            {                
                context.sp_WP7Subscribers_Insert(1,"himan",DateTime.Now);
            }
        }

 

쉽다

Posted by 동동(이재동)
database2011. 5. 31. 15:40
USE [WP7NotificationServer]
GO
/****** Object:  StoredProcedure [dbo].[sp_HugeFlowAppManifest_List_Select]    Script Date: 05/31/2011 14:35:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*
Developer : test
Date : 2010/11/18
Desc : test
*/
 
CREATE proc [dbo].[sp_WP7NotificationServer_List_Select]
    @AppID int
AS
BEGIN
    SELECT [Idx]
      ,[Subscriber]
      ,[SubScribeDate]
    From [WP7NotificationServer] 
END
GO

 

이건 그냥 단순한 list select

 

이건 insert

USE [WP7NotificationServer]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
 
Create proc [dbo].[sp_WP7NotificationServer_Insert]
@AppID int
,@SubScriber VARCHAR(255)
,@SubScribeDate datetime
AS
INSERT INTO WP7NotificationSever_Subscribers(AppID , SubScriber, SubScribeDate) VALUES (@AppID , @Subscriber,@SubScribeDate)

 

 

머 이런식으로 하면 된다 쉽다.

'database' 카테고리의 다른 글

[db] DECIMAL 형식이란?  (0) 2010.04.19
[db] DECLARE로 정의한 함수 보기  (0) 2010.04.19
[DB] JOIN에 대한 것  (0) 2010.04.13
[db] query문 에서 변수 설정및 for문 형변환 이용하기  (0) 2010.01.07
[db] db 정보 확인  (1) 2010.01.07
Posted by 동동(이재동)
Windows Phone 72011. 5. 27. 18:43

마지막이다.

 

이제 메세지를 보낼 UI를 만들어보자 관리자를 위한 프로그램이다

 

난 그냥 쉬운 WPF로 만들었다.

 

일단 버튼 하나 만들고

 

private void ToastButton_Click(object sender, RoutedEventArgs e)
      {
          string appId = "1";
          //string baseUri = string.Format("http://localhost:19976/Notifications/GetSubscribers?appId={0}", appId);
          string baseUri = string.Format("http://192.168.10.174:6060/Notifications/GetSubscribers?appId={0}", appId);
 
          GetSubscribers(baseUri);
          
      }

 

 

private void GetSubscribers(string baseUri)
     {
         WebClient webclient = new WebClient();
         webclient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(webclient_DownloadDataCompleted);
         webclient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webclient_DownloadStringCompleted);
         webclient.DownloadStringAsync(new Uri(baseUri));
     }

 

이렇게 WCF 를 호출해서 사용자 URI들을 받는다. (10명이 등록 되어 있으면 서버가 10개가 들어 있는 List를 보내줌)

 

void webclient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
       {                           
           MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(e.Result));
           DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<Uri>));
           deserializedListUri = serializer.ReadObject(ms) as List<Uri>;
 
           SendToast();
       }

 

자 다운이 다 되면 List로  Deserialize 한후

 

private void SendToast()
       {
 
           HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(deserializedListUri[0]);
 
           // We will create a HTTPWebRequest that posts the toast notification to the Microsoft Push Notification Service.
           // HTTP POST is the only allowed method to send the notification.
           sendNotificationRequest.Method = "POST";
 
           // The optional custom header X-MessageID uniquely identifies a notification message. 
           // If it is present, the // same value is returned in the notification response. It must be a string that contains a UUID.
           // sendNotificationRequest.Headers.Add("X-MessageID", "<UUID>");
 
           var title = "test Title";
           var subtitle = "test SubTitle";
           // Create the toast message.
 
 
           string toastMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
           "<wp:Notification xmlns:wp=\"WPNotification\">" +
              "<wp:Toast>" +
                   "<wp:Text1>" + title + "</wp:Text1>" +
                   "<wp:Text2>" + subtitle + "</wp:Text2>" +
              "</wp:Toast> " +
           "</wp:Notification>";
 
           // Sets the notification payload to send.
           byte[] notificationMessage = Encoding.Default.GetBytes(toastMessage);
 
           // Sets the web request content length.
           sendNotificationRequest.ContentLength = notificationMessage.Length;
           sendNotificationRequest.ContentType = "text/xml";
           sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast");
           sendNotificationRequest.Headers.Add("X-NotificationClass", "2");
 
           using (Stream requestStream = sendNotificationRequest.GetRequestStream())
           {
               requestStream.Write(notificationMessage, 0, notificationMessage.Length);
           }
 
           // Send the notification and get the response.
           HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
           string notificationStatus = response.Headers["X-NotificationStatus"];
           string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
           string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];
 
           // Display the response from the Microsoft Push Notification Service.  
           // Normally, error handling code would be here.  In the real world, because data connections are not always available,
           // notifications may need to be throttled back if the device cannot be reached.
 
           resultTextBlock.Text = notificationStatus + " | " + deviceConnectionStatus + " | " + notificationChannelStatus;
       }
 
이렇게 보낸다 xml 형식으로 만들어서 보내면 되며
 
상태들도 header정보를 받아서 볼수 있다.

Posted by 동동(이재동)
Windows Phone 72011. 5. 27. 18:37

자 이번에는 WCF Rest Service를 만들어 보자.

 

이것도 역시 WCF Rest Service 프로젝트 생성해서

 

[ServiceContract]
   [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
   [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
   public class Notifications
   {
       private static Dictionary<string,List<Uri>> subscribers = new Dictionary<string,List<Uri>>();
       private static object obj = new object();
 
       [WebInvoke(UriTemplate = "register?uri={uri}&appId={appId}", ResponseFormat = WebMessageFormat.Xml, Method = "GET")]
       public void Register(string uri,string appId)
       {            
           Uri channelUri = new Uri(uri, UriKind.Absolute);
           Subscribe(channelUri,appId);
       }
 
       private void Subscribe(Uri channelUri,string appId )
       {
           lock (obj)
           {
               if (subscribers.ContainsKey(appId) == false)
               {
                   subscribers.Add(appId, new List<Uri>());
               }
 
 
               if (!subscribers[appId].Exists((u) => u == channelUri))
               {
                   subscribers[appId].Add(channelUri);
               }
           }
           //OnSubscribed(channelUri, true);
       }
 
       [WebInvoke(UriTemplate = "GetSubscribers?appId={appId}", ResponseFormat = WebMessageFormat.Json, Method = "GET")]
       public List<Uri> GetSubscribers(string AppId)
       {
           return subscribers[AppId];
       }

 

귀찮아서 소스만 썻다 보면 알듯이

클라이언트가 Register 메소드를 호출하여 URI와 AppID(구분을 위해)

를 주면 그걸 그냥 List에 저장하는 형식이다.

나중에 이걸 DB로 저장하게 바꾸기만 하면 된다.



 

 

Posted by 동동(이재동)