제2외국어/iOS

[iOS] Network check and error handling

윈플. 2013. 8. 21. 17:32

자신이 만들 앱이 인터넷을 사용한다면, 인터넷이 연결되었는지를 확인하여 사용자에게 알려야합니다. 
그리고 Web Application을 생각 중이시라면, 중간 중간 Loading 부분을 인디게이터로 표현해주어야 하며,
에러에 관련된 처리는 당연한 부분입니다.

그래서 이번엔 인터넷 상태를 확인하고, 인디게이터는 언제 애니메이션을 키고 꺼야 되는지, 그리고 에러 처리는 어떻게 해야하는지 정리해봤습니다.


1. 인터넷 연결 상태 확인하기.

***Reachability

The Reachability sample application demonstrates how to use the SystemConfiguration framework to monitor the network state of an iOS device. In particular, it demonstrates how to know when IP can be routed and when traffic will be routed through a Wireless Wide Area Network (WWAN) interface such as EDGE or 3G.

: 쉽게 말해 'SystemConfiguration' framework 사용하여 인터넷 상태를 알려주는 샘플코드 되시겠습니다.


먼저 이 샘플코드를 활용하여 간단히 네트워크 상태를 체크하는 함수를 만들어봤습니다.

 
#pragma mark Check Network

- (BOOL) connectedToNetwork
{
    /*
     www.apple.com URL을 통해 인터넷 연결 상태를 확인합니다.
     ReachableViaWiFi && ReachableViaWWAN 
     : Wi-fi와 3G 둘다 안된다면 인터넷이 연결되지 않은 상태입니다.
     */
    
	Reachability *r = [Reachability reachabilityWithHostName:@"www.apple.com"];
	NetworkStatus internetStatus = [r currentReachabilityStatus];
	BOOL internet;
    
	if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN)) {
		internet = NO;
	} else {
		internet = YES;
	}
	return internet;
}


+ 물론 위 소스를 사용하기 위해서는
* SystemConfiguration.framework 를 추가하셔야 합니다.
* Reachability.h 와 
Reachability.m 소스가 프로젝트 안에 있어야 합니다.
Reachability.h 를 import 하셔야 합니다.

위 소스를 간단히 살펴보면, 'www.apple.com' 라는 url을 통하여 3G와 Wifi를 구분하지 않고 단순히 인터넷 사용 가능 유무를 검사합니다.
( 사용가능 YES, 사용불가 NO )


3G 와 Wifi 를 구분하려면?
: 당연히 &&로 묶여있는 if문을 나누어 주면 됩니다. ^_^;


2. UIWebView.

: <UIWebViewDelegate> 를 통해 아래 4개의 함수를 사용하여 에러처리 및 UIActivityIndicatorView를 처리할 예정입니다.


- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
: Delegate가 연결된 WebView안에서 요청이 있는 경우, 이 함수를 통해 어떤 url로 링크를 타는지 알 수 있습니다.
+ 예를들어 웹뷰를 통해 무언가를 검색했을 때, 검색어를 가져온다던지 기타 등등

UIWebViewNavigationType{
    UIWebViewNavigationTypeLinkClicked,            // 링크 클릭 : 0
    UIWebViewNavigationTypeFormSubmitted,      // 양식 제출 : 1
    UIWebViewNavigationTypeBackForward,         // 뒤로, 앞으로 : 2
    UIWebViewNavigationTypeReload,                  // 새로고침 :3
    UIWebViewNavigationTypeFormResubmitted,   // 양식 다시 제출 :4
    UIWebViewNavigationTypeOther                     //  기타 :5
};

- (void)webViewDidStartLoad:(UIWebView *)webView;
- (void)webViewDidFinishLoad:(UIWebView
*)webView;
: 위 두함수는 웹뷰가 시작되고, 끝났을 때 호출됩니다. 이 함수를 이용해서 
UIActivityIndicatorView 애니메이션을 언제 시작하 끝낼지 생각할 필요가 없게됬습니다.


- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
: 딱 봐도 이 함수가 error가 발생할 때 호출되는 함수입니다. 
- error.description : error 코드 포함하여 error에 대한 설명이 포함되어있습니다.
- error.code : error 코드를 알 수 있습니다. ( 아래 더보기를 통해 종류를 보시기 바랍니다. )

+ error code = -1009 인터넷이 연결안되어 있을 때 나는 코드입니다.


"Timeout" 처리하기

: 인터넷은 연결되어 있는 상태지만, 신호가 약하거나 잘못된 Wi-Fi를 물고 있는 경우 생길 수 있는 Timeout 처리에 관한 부분입니다.

( 1 ) WebView가 시작하는  webViewDidStartLoad에서 NSTimer를 지정한 시간에 함수를 호출하도록 설정합니다.
( 2 ) 
webViewDidFinishLoad에서는 NSTimer를 invalidate를 시켜줍니다. ( 정상적으로 종료되었다는 의미이므로 )


- (void)timeoutWebview
{
    NSLog(@"Timeout 20sec");
    UIAlertView *timeAlertView = [[UIAlertView alloc]initWithTitle:@"Timeout" message:@"20sec" delegate:nil cancelButtonTitle:@"cancel" otherButtonTitles:nil, nil];
    [timeAlertView show];
    // Timeout Check 20초 이상 걸린다면, 화면에 뿌려주기
}

- (void)webViewDidStartLoad:(UIWebView *)webView
{
    NSLog(@"StartLoad");
    
    // Timer시작
    timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(timeoutWebview) userInfo:nil repeats:NO];
    
    
    // Start Loading
    loadingIndicator.hidden = NO;
    [loadingIndicator startAnimating];
}



- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    NSLog(@"FinishLoad");
    
    // 정상적으로 웹이 됬다면 Timer 종료
    [timer invalidate];
    
    // Stop Loading
    [loadingIndicator stopAnimating];
    loadingIndicator.hidden = YES;
}




3. NSURLRequest

NSURL *_url = [NSURL URLWithString:URL];
NSURLRequest *request = [NSURLRequest requestWithURL:_url];

기본적으로 위와 같이 사용하지만, 

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URL]                                                                                                                      cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                                                       timeoutInterval:60.0];

이와 같이 NSMutableURLRequest를 사용해서 timeout 을 설정하는 방식을 더 많이 사용합니다.

마찬가지로 <NSURLConnectionDelegate> 를 사용해서

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
: 연결 오류가 났을 때 호출 되며 이곳에서 에러 처리를 해주시면 됩니다.
+ UIWebView에서의 Error와 코드는 같습니다.

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
: 연결 성공했을 때
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
: 연결 한 후에 데이터를 받을 때
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
: 데이터를 다 받았을 때 

- 인디게이터 부분은 연결에 성공하여서 데이터를 다 받을때까지로 할지, 아니면 연결 이후에 데이터를 받기 시작한 후 다 받을때 까지로 할지 정하시면 됩니다.


+ 추가적으로 response를 통해 Status Code를 통해 확인하는 방법입니다.
단순하게 200(Success) , 400(Bad Request)로 구분할 수 있습니다.

 
NSURLResponse *response;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
NSLog(@"return statecode : %d",[(NSHTTPURLResponse *)response statusCode]);




지금까지 앱에서 인터넷을 사용할 때, 기본적으로 처리해야 하는 부분을 봤습니다.만 아래 링크를 통해서
좀 더 알아보시기 바랍니다.


내가 만든 앱 문제는 없을까?
웹(Web) .vs 앱(APP) 어떤 것을 선택할 것인가?
- 모바일 앱 기획시 고려사항
- 애플의 하이브리드앱 제재는 정당한가?



'제2외국어 > iOS' 카테고리의 다른 글

[iOS]custom Cell - Edit 사용 시 밀리지 않는 문제  (0) 2013.06.20
[iOS]통화하기  (0) 2013.05.29
[iOS]Font 관련하여..  (0) 2013.04.26
[iOS] Multitasking : Location  (0) 2013.01.29
[iOS] Multitasking : Audio  (0) 2013.01.24