-
[iOS] 웹뷰로 하이브리드앱 구현 시작하기. Building a Hybrid App with UIWebView.앱등이에게 살충제를 뿌린다./iOS 2015. 11. 27. 10:09
소스 다운로드 > https://github.com/cpromise/HybridAppIOS
웹뷰띄워 하이브리드앱 만들어보기
웹앱, 하이브리드앱.. 각 단어가 정확히 어떤 정의를 갖는지 모르겠지만!!
웹뷰로 iOS앱을 만드는 법에 대해서 알아봅시다.
샘플코드및 동영상은 맨 아래에
웹뷰를 통해 HTTP URL요청하기
NSURLRequest객체를 만든 뒤 UIWebView의 loadRequest메소드를 통해 호출할 수 있다. NSURL요청을할 때, HTTP요청인 경우에는 헤더에 원하듣 필드와 값을 지정하여 전달할 수 있다.
UIWebView *webview = [[UIWebView alloc] init] ;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLwithString:@""] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0f];
[webview loadRequest:request];
델리게이트를 통해서 Response를 확인할 수 있다.
webView: shouldStartLoadWithRequest: navigationType:
- 웹뷰가 로딩을 시작하기 전에 호출된다.
- 추후에 Javascript - Objective-C와의 통신에도 사용된다.
webViewDidStartLoad:
webViewDidFinishLoad:
webView: didFailLoadWithError:
- 웹뷰가 데이터를 로딩하는데 실패하면 호출된다.
- error를 통해 원인을 파악할 수 있다. (ex:
NSLog(@"%@",error.description);
)
iOS9부터 SSL(TLS)을 지원하지 않는 서버는 요청을 권장하지 않고 있다.
HTTPS가 아닌 HTTP요청을 시도하면 webView: didFailLoadWithError: 메소드가 호출되고 error파라미터는 The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.를 포함하는 메시지를 전달한다. HTTP호출의 제한을 명시적으로 해제하려면 info.plist파일을 수정하여 HTTP 호출을 시도할 수 있다.
Javascript와 Objective-C가 통신할 수 있다.
웹뷰 내에 있는 Javascript코드를 통해 Objective-C를 호출하거나 Objective-C코드를 통해 Javascript코드를 호출할 수 있다.
1. Javascript코드에서 Objective-C코드 호출
<input type="button" onClick="callNative()" value="샘플버튼"/>
이런 태그가 있다고 가정할 때, 버튼을 누르면 Javascript에 구현된 callNative()라는 메소드가 실행될 것이다.
<script>
var callNative = function(){
window.location = "appscheme://callNative";
}
</script>
callNative는 이렇게 App의 URL scheme을 호출하는 역할만 해줄뿐!!
**참고
iOS에서 웹브라우저에서 앱을 열때는 보통 이렇게 URL을 통해 호출합니다. 예를들면 신한앱카드, 카카오페이로 결제하기가 있습니다.
앱이 없을 때 앱스토어로 이동하는 방식 역시 이 안에서 if문으로 분기처리하여 앱이 없다면 앱스토어로 연결되는 방식으로 구현됩니다.
이렇게 하면 네이티브 코드에서는 아래 메소드가 호출됩니다.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
이 메소드는 리턴타입에서 볼 수 있듯 웹뷰에서 온 요청을 수행할 것인지 말 것인지를 결정하여 BOOL타입을 리턴합니다.
//예시구현
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
if ([[[request URL] absoluteString] hasPrefix:@"appscheme:"]) {
NSString *requestString = [[request URL] absoluteString];
NSArray *components = [requestString componentsSeparatedByString:@"://"];
NSString *functionName = [components objectAtIndex:1];
[self performSelector:NSSelectorFromString(functionName)];
return NO;
} else{
return YES;
}
}
-(void)callNative{
NSLog(@"%s called.",__FUNCTION__);
}
"appscheme://callNative"라는 문자열이 들어왔고, appscheme이라는 문자열과 callNative라는 문자열로 분리했습니다. 그리고 appscheme이 앱과 일치한다면 callNative라는 selector를 실행하게 되는 구조입니다. Javascript에서 전달한 함수이름이 Objective-C와 같지 않아도 원하는 Objective-C의 메소드를 실행할 수 있다는 점이 눈에 띕니다.
**참고 : request 파라미터에는 웹뷰에 로드된 컨텐츠에서 어떤 리퀘스트가 있을 때 들어오는 변수인데 아래와 같이 구성되어 있습니다.
- absoluteString – An absolute string for the URL. Creating by resolving the receiver’s string against its base.
- absoluteURL – An absolute URL that refers to the same resource as the receiver. If the receiver is already absolute, returns self.
- baseURL – The base URL of the receiver. If the receiver is an absolute URL, returns nil.
- host – The host of the URL.
- parameterString – The parameter string of the URL.
- password – The password of the URL (i.e. http://user:pass@www.test.com would return pass)
- path – Returns the path of a URL.
- port – The port number of the URL.
- query – The query string of the URL.
- relativePath – The relative path of the URL without resolving against the base URL. If the receiver is an absolute URL, this method returns the same value as path.
- relativeString – string representation of the relative portion of the URL. If the receiver is an absolute URL this method returns the same value as absoluteString.
- scheme – The resource specifier of the URL (i.e. http, https, file, ftp, etc).
- user – The user portion of the URL.
2. Objective-C에서 Javascript코드 호출
- (NSString * _Nullable)stringByEvaluatingJavaScriptFromString:(NSString * _Nonnull)script
이 메소드를 통해서 웹뷰에 로드된 페이지의 Javascript에 접근할 수 있습니다.
사용법은 아래와 같습니다.
//웹페이지의 타이틀 값 알아보기 <title>태그
- (IBAction)btn1:(id)sender {
NSString *title = [webview stringByEvaluatingJavaScriptFromString:@"document.title"];
NSLog(@"Document Title : %@",title);
}
//웹페이지의 Javascript 메소드 실행하기
- (IBAction)btn2:(id)sender {
[webview stringByEvaluatingJavaScriptFromString:@"functionFromObjc()"];
//Javascript에 구현되어 있는 functionFromObjc메소드가 실행됩니다.
}
샘플코드
<!-- html파일 -->
<html>
<head>
<meta charset="utf-8" />
<title>테스트용 로컬 html문서</title>
<script>
var jsFuncFromObjc = function(){
alert("func1 is called.");
}
var objcFuncFromJS = function(){
window.location = "hybrid://objcFuncFromJS";
}
var sampleMethod = function(){
alert("method is called");
}
var changeDocument = function(){
var titleList = ["Hello world","Bye world"];
var title = document.getElementById("titleName");
var curTitle = title.innerText;
if(curTitle == titleList[0]){
title.innerText = titleList[1];
} else{
title.innerText = titleList[0];
}
}
</script>
</head>
<body>
<p>웹페이지</p>
<p id="titleName">Hello world</p>
<input type="button" value="버튼1" onClick="objcFuncFromJS()"/>
</body>
</html>
이 앱을 실행시킨 동영상
찹쌀도우너츠전임스타일의 아날로그감성을 담아 직접촬영으로 올립니다.
웹뷰는 빨간 테두리부분이고 아랫쪽 레이블은 네이티브입니다.
'앱등이에게 살충제를 뿌린다. > iOS' 카테고리의 다른 글