iOS에서 통신을 하는 방법은 몇가지가 있는데 가장 간편하게 사용되는 방법은 NSURLConnection을 이용해 동기적으로 통신하는 것이다. 가장 심플하다 


NSURLConnection Delegate를 이용하면 다양한 방법으로 통신을 컨트롤할 수 있긴하나 , 일단 내가 최근에 사용했던 가장 가벼운 방법부터 정리해본다. 기본적으로 POST방식으로 보내는 방법을 기준으로 설명한다.


// NSURLRequest 객체 생성 
// 통신을 Request(요청)하는 객체를 만든다
NSMutableURLRequest* request = [[NSMutableURLRequest alloc]init];

// POST 내용을 작성 
NSString *post = [NSString stringWithFormat:@"Post로 보낼내용"];

NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", (int)[postData length]];

// Request 객체에 들어갈 내용들 설정 
[request setURL:[NSURL URLWithString:@"http://www.urURL.co.kr"]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"Mozilla/4.0 (compatible;)" forHTTPHeaderField:@"User-Agent"];
[request setHTTPBody:postData];
[request setTimeoutInterval:30.0];

// 커넥션 에러를 다룰 객체를 생성
NSError *error = nil;
// NSURLConnection 객체를 이용해 동기적으로 보냄 (Response객체는 사용하지 않음)
// 돌아온 값은 NSData형으로 받는다 
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:Nil error:&error];
if(data == NULL){
    // 통신 실패 ! 
    NSLog(@"통신 실패 ! : %@",[error LocalizedDescription]);
}
else{
    // 통신 성공 
    // 받아온 정보가 스트링인 경우 
    NSString *returnStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"Return String : %@",returnStr);
}

UIAlertView는 간단한 앱을 만드는 경우 굉장히 자주 사용하는(?)요소 중 하나라고 생각하는데, 생각보다 UIAlertView를 한번 사용하려면 입력할 정보가 굉장히 많다.


게다가 UIAlertView자체를 구분해야되거나 버튼마다 다른 기능을 집어넣어줘야하는 경우, 더 복잡해지게된다. 

그럴땐 클래스를 따로 빼버리고 아래와 같은 처리를 해서 쉽게 만들어 쓰자 


   
-(void)alertView_Set:(NSString *)mesg withTaget:(id)delegate andTag:(int)tag withExtraButton:(NSArray *)buttons{
    UIAlertView *artView = [[UIAlertView alloc]
                            initWithTitle:@"타이틀" message:mesg delegate:delegate cancelButtonTitle:@"확인" otherButtonTitles:nil];
    
    // 입력받은 값을 Message , Delegate에 넣어준다. 
    // 해당 함수를 현재 AlertView를 띄울 뷰가 아닌 별도의 클래스로 분리할 경우 
    // Delegate를 넘겨주어야 한다. 

    // 추가 버튼이 필요하다면 버튼을 추가한다
    for(int idx = 0 ; idx < (int)[buttons count] ; idx++){
        [artView addButtonWithTitle:[buttons objectAtIndex:idx]];
    }
    
    // 태그를 주어 태그를 입력한다.
    [artView setTag:tag];
    [artView show];
}


위의 방법으로 별도로 분리해서 사용하면 한번에 tag, delegate 버튼추가를 해줄 수 있다. 태그 구분 및 버튼 구분은 해당 뷰컨트롤러의 헤더 파일에 UIAlertViewDelegate를 추가해준 후 아래와 같은 코드를 삽입하면된다.


-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    // Delegate 내장 함수 
    if([alertView tag] == 0){
        // AlertView의 태그가 0인 경우 
        if(buttonIndex == 0){
             // AlertView에서 첫번째 버튼을 누른경우
        }
        else{
             // 나머지 버튼을 누른경우 
        }
    }
}

개발을 하다보면 간단한 로그를 남겨두어야할 상황이 생긴다. 단순히 정보를 저장하는 방법에는 plist나 NSUserDefault같은 것을 사용할 수 있지만 오류 로그등을 남겨둘때는 파일로 저장해두는 것이 관리도 편한것같다 .


파일을 작성하고 읽어오는데는 주로 NSFileManager를 활용하게 되는데 기본은 아래와 같다. 


// 경로를 읽어온다
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);

NSString *documentDir = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"LogDirectory"];

// 파일명을 포함한 경로를 설정
NSString *filePathAndName = [documentDir stringByAppendingPathComponent:@"Log.txt"];

// FileManager를 생성
NSFileManager *fileManager = [NSFileManager defaultManager];

파일을 읽고쓰기 위한 초기화는 위와 같다. 하지만 fileManager나 NSString을 이용해 파일을 읽고 쓰기 전에, Cocoa Error같은것들을 피하기 위해서는 몇가지 처리를 해두는것이 좋다. 아래처럼




// 1. 파일을 생성할 Directory가 있는지 확인
NSError *err = NULL;
if(![fileManager isWritableFileAtPath:documentDir]){
// Directory가 없는 경우 생성해준다
     if([fileManager createDirectoryAtPath:documentDir withIntermediateDirectories:YES attributes:nil error:&err]){
         // Directory가 생성된 경우 
         NSLog(@"Log Directory Create!");
     }
else{
    // Directory 생성에 실패한 경우 
    NSLog(@"Directory Create Fails ! : %@",[err LocalizedDescription]);
    }
}

// 2. 기존에 생성할 파일이 존재하는지 확인 
if([fileManager fileExistsAtPath:logPath]){
    // 파일이 존재하는 경우 

    // 기존에 있던 파일의 내용을 불러와 뒤에 덧붙임
    NSString *logStr = [NSString StringWithFormat:@"로그 내용"];
    NSMutableString *fileStr = [NSMutableString stringWithContentsOfFile:logPath encoding:NSUTF8StringEncoding error:nil];
    // 기존 파일에서 글 내용을 읽어옴
    // 읽어올때 에러처리 생략 !

    [fileStr appendFormat:@"\n%@",logStr];
        
    if([recvErrStr writeToFile:logPath atomically:FALSE encoding:NSUTF8StringEncoding error:&err]){
        NSLog(@"Log Create!1");
    }
    else{
        NSLog(@"Log Create Err1 : %@",err);
    }
}
else{
    // 파일이 존재하지 않는 경우 
    
        NSString *logStr = [NSString stringWithFormat:@"로그 내용"];
        if([errStr writeToFile:logPath atomically:false encoding:NSUTF8StringEncoding error:&err]){
            NSLog(@"Log Create!2");
        }
        else{
            NSLog(@"Log Create Err2 : %@",err);
        }
}

위와 같은 처리를 해두면 Cocoa Eror 4. 혹은 516에러를 막을 수있다

Cocoa Error 4.는 보통 접근권한을 얻지 못했거나 디렉토리 혹은 파일이 존재하지 않을때 나타나는 오류이다

처음 NSFileManager를 사용하는 사람이라면 보통 디렉토리가 생성되어있지 않아서 발생하는 경우가 대부분이다. 그런 경우엔

위 처럼 접근권한을 얻지 못했을때 디렉토리를 만들도록 처리해두면 쉽게 해결할 수 있다. Cocoa Error 516은 사실 위의 코딩과는 상관없는 부분으로, 경로가 잘못되었을때 나타난다.


516에러가 나타난다면 경로를 제대로 작성했는지 꼭 확인해볼것 ! 나는 작업중에 작성할 스트링 내용과 주소를 바꿔쓰는 실수를 했었다..


파일을 생성한 후에 위에 사용한 fileExistsAtPath를 활용하면, 파일이 있는지 확인한 후 파일이 있으면 로그를 전송하는 식으로 사용할 수 있다.

+ Recent posts