在开发项目时,用到了UIWebView,还用到了内嵌的html页面,用到了很多的js方面的东西,oc与js进行交互,同时还用到了重定向原理,这里做一下总结:
(1)使用到的内嵌html页面,我们这里要导入html页面到工程中。由于返回的json数据里包含有网页格式,我们需要对关键字替换
//数据解析
-(void)analyzeJSONData:(NSDictionary *)jsonDic{
newsDetailInfo=[Tools parseForNewsDetailInfoJSONString:jsonDic];
[newsDetailInfo retain];
if (newsDetailInfo.appInfo!=nil) {
newsAppInfo=[Tools parseForNewsAppInfoJSONString:newsDetailInfo.appInfo];
[newsAppInfo retain];
if (IS_PHONE) {
[self replaceJSONDataWithHTML:STRATEGY_DETAIL_FILENAME];
}else{
[self replaceJSONDataWithHTML:STRATEGY_DETAIL_FILENAME_IPD];
}
}else{
if (IS_PHONE) {
[self replaceJSONDataWithHTML:NEWS_DETAIL_FILENAME];
}else{
[self replaceJSONDataWithHTML:NEWS_DETAIL_FILENAME_IPAD];
}
}
}
//替换
-(void)replaceJSONDataWithHTML:(NSString *)fileName{
NSError *error;
_fileContents=[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileName ofType:@"html"] encoding:NSUTF8StringEncoding error:&error];
NSString *resultHTMLString;
resultHTMLString=[_fileContents stringByReplacingOccurrencesOfString:@"[title]" withString:newsDetailInfo.title];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[modifyTime]" withString:newsDetailInfo.modifyTime];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[commentCount]" withString:[NSString stringWithFormat:@"%d",newsDetailInfo.commentCount]];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[author]" withString:newsDetailInfo.author];
if (pageNum==1) {
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[summary]" withString:newsDetailInfo.summary];
contentString=newsDetailInfo.summary;
}else{
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[summary]" withString:_remainResponseString];
}
if ([fileName isEqualToString:STRATEGY_DETAIL_FILENAME] || [fileName isEqualToString:STRATEGY_DETAIL_FILENAME_IPD]) {
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[icon]" withString:newsAppInfo.iconURL];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[appName]" withString:newsAppInfo.name];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[version]" withString:newsAppInfo.version];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[size]" withString:newsAppInfo.size];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"[language]" withString:newsAppInfo.language];
}
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@" " withString:@""];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"<img" withString:@"<br><img"];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"<embed" withString:@"<br><embed"];
if (IS_PHONE) {
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"width=" withString:@"width2="];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"height=" withString:@"height2="];
}
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"\t" withString:@" "];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"<br />" withString:@" "];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"<br>" withString:@" "];
for (NSString *str in sepLineArray) {
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:str withString:@""];
}
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"<img src=\"\" alt=\"\" /> " withString:@""];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"<img alt=\"\" src=\"\" height2=\"18\" width2=\"597\" />" withString:@""];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"\"ID\":id,\"isnotdeletealink\":iol,\"pageNum\":pagenum" withString:@"\"ID\":newsInfoID,\"isnotdeletealink\":\"false\",\"pageNum\":pagenum"];
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"newsInfoID" withString:[NSString stringWithFormat:@"%d",newsInfoID]];
[_contentWebView loadHTMLString:resultHTMLString baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
}
(2)在上面的替换中,需要特别注意的是
resultHTMLString=[resultHTMLString stringByReplacingOccurrencesOfString:@"\"ID\":id,\"isnotdeletealink\":iol,\"pageNum\":pagenum" withString:@"\"ID\":newsInfoID,\"isnotdeletealink\":\"false\",\"pageNum\":pagenum"];
这里主要是后面做网页加载下一页时用ajax加载处理,这里先暂时不讲(3)在获取图片的过程中,我们用到了正则表达式获取
-(NSMutableArray *)getWebViewPictureUrlString{
NSString * JsString = @"document.documentElement.innerHTML";
NSString * str = [_contentWebView stringByEvaluatingJavaScriptFromString:JsString];
NSString *regexString = @"<img [^>]*/?>";
NSArray *matchArray=[str componentsMatchedByRegex:regexString];
NSMutableArray *resultArr = [[NSMutableArray new]autorelease];
for (NSString *imgString in matchArray) {
NSArray *stringArr=[imgString componentsSeparatedByString:@"\""];
for (NSString *string in stringArr) {
if ([string rangeOfString:@"http://"].location!=NSNotFound){
if([string rangeOfString:@"Upload"].location!=NSNotFound || [string rangeOfString:@"smtpfbackend"].location!=NSNotFound) {
[resultArr addObject:string];
}
}
}
}
return resultArr;
}
//点击某张图片
-(void)imageTappedInWebView:(UITapGestureRecognizer *)sender{
self.imageURLArray=[self getWebViewPictureUrlString];
CGPoint pt = [sender locationInView:_contentWebView];
NSString *imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", pt.x, pt.y];
NSString *urlToSave = [_contentWebView stringByEvaluatingJavaScriptFromString:imgURL];
if ([urlToSave rangeOfString:@"icon"].location==NSNotFound){
if (urlToSave.length > 0) {
for (int i = 0; i < [self.imageURLArray count]; ++i) {
if ([[self.imageURLArray objectAtIndex:i] isEqualToString:urlToSave]) {
currentIndex=i;
// [self showImageTapped:sender AtIndex:currentIndex]; // 2014.7.15
break;
}
}
}
}
}
(5)重定向用的太多了,在webView的代理响应里头很杂乱,值得注意的是loadnextpage这个重定向
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType{
NSString *requestString=[[[request URL]absoluteString]stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
if ([requestString hasPrefix:@"testapp://"]) {
[self entryIntoGameAppDetail];
}
if ([requestString hasPrefix:@"setting:"]) {
NSArray *components=[requestString componentsSeparatedByString:@":"];
[self setTappedRectFromTappedImage:components];
[self showImageTapped:nil AtIndex:currentIndex];
}
if ([requestString hasPrefix:@"testappnewsid:"]) {
NSArray *components=[requestString componentsSeparatedByString:@":"];
NSInteger newsId=[[components objectAtIndex:1]integerValue];
[self entryIntoGameAppDetail:newsId];
}
if ([requestString hasPrefix:@"loadnextpage://"]) {
if(IS_PHONE){
NSInteger preIndex=[self.imageURLArray count];
self.imageURLArray=[self getWebViewPictureUrlString]; //下一次请求后 图片会增多
dispatch_queue_t queue=dispatch_queue_create("imagedownloadNextPage", NULL);
dispatch_async(queue, ^{
[self asynRequestForImageArr:self.imageURLArray fromIndex:preIndex];
});
}
}
if ([requestString hasPrefix:@"returnsetting:"]) {
[self removeImageAnimationWithCGRectString:requestString];
}
return YES;
}
在html页面中,这里主要是定义协议,写js方法,可以对照看是对应哪个协议的重定向
<script type="text/javascript" src="jquery-1.8.0.min.js"></script>
<script type="text/javascript">
var id="",iol="",pagenum=2,
fact=true,essen=true;
function entryIntoGameAppDetail(){
document.location = 'testapp://';
}
function loadata()
{
totalheight = parseFloat($(window).height()) + parseFloat($(window).scrollTop());
var kk={"ID":id,"isnotdeletealink":iol,"pageNum":pagenum,"type":"pageData","version":510};
if ($(document).height() <= totalheight)
{
if(fact==true){
fact=false;
$.ajax({
type: 'POST',
url: "http://api.ios.d.cn/api-news/NewsInfoByJson.ashx",
data: kk,
dataType: 'html',
success: function (data) {
document.location='loadnextpage://';
fact=true;
$("div.body").append(data);
pagenum++;
set();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
}
}
}
$(window).scroll( function() {
loadata();
});
function set(){
$("body img").unbind("click");
$("body img").bind("click",function(e){
var y=$(this).offset().top,
x=$(this).offset().left,
w=$(this).width(),
h=$(this).height();
document.location = 'setting:'+x+':'+y+':'+w+':'+h;
})
}
function reset(e){
e="\""+e+"\"";
var that=$("img[src="+e+"]");
var y=that.offset().top,
x=that.offset().left,
w=that.width(),
h=that.height();
document.location ='returnsetting:'+x+':'+y+':'+w+':'+h;
}
set();
function showAlert() {
alert($);
}
</script>
这里reset(e)是对应的获取某一张链接图片在webView中的originx,originy,width,height,以便做图片的动画效果处理,set()是点击某一张图片时,返回对应的在 webView中的originx,originy,width,height。webView滚动的过程中,采用ajax进行加载下一页接口数据。(6)做图片的点开和缩回动画,这里没写好,效果应该相差不多
-(void)showImageAnimation:(UIImage *)tappedImage atIndex:(NSInteger)index{
NSMutableArray *imageRectArr=[self getTappedRectForTappedImage];
float originX=[imageRectArr[0]floatValue]+6;
float originY=[imageRectArr[1]floatValue]-_contentWebView.scrollView.contentOffset.y+6;
float width=[imageRectArr[2]floatValue];
float height=[imageRectArr[3]floatValue];
CGRect imageRect=CGRectMake(originX, originY, width, height);
[_imageScrollView tappedSelectedImageIndex:index beforeAnimation:imageRect];
UIColor *bgColor=_imageScrollView.backgroundColor;
[_imageScrollView setBackgroundColor:[bgColor colorWithAlphaComponent:0]];
[UIView animateWithDuration:0.25 animations:^{
[_imageScrollView tappedSelectedImageIndex:index animation:YES];
[[MainVC sharedMe].view addSubview:_imageScrollView];
UIColor *bgColor=_imageScrollView.backgroundColor;
[_imageScrollView setBackgroundColor:[bgColor colorWithAlphaComponent:1]];
} completion:^(BOOL finished){
}];
}
-(void)removeImageAnimationWithCGRectString:(NSString *)rectStr{
NSArray *components=[rectStr componentsSeparatedByString:@":"];
float originX=[components[1] floatValue]+6;
float originY=[components[2] floatValue]+6;
float width=[components[3] floatValue];
float height=[components[4] floatValue];
float scrollToY=originY-(_contentWebView.frame.size.height/2-height/2);
if (originY<_contentWebView.scrollView.contentOffset.y-height || originY>_contentWebView.scrollView.contentOffset.y+_contentWebView.frame.size.height) {
[_contentWebView.scrollView scrollRectToVisible:CGRectMake(0, scrollToY, _contentWebView.frame.size.width, _contentWebView.frame.size.height) animated:NO];
}
CGRect imgInScrollViewRect=[_imageScrollView setImageFrame:[imageDownloaded objectAtIndex:removeImageIndex]]; //在scrollView中image的rect
CGRect imageRect=CGRectMake(originX, originY-_contentWebView.scrollView.contentOffset.y, width, height); //在webview中的img的rect
[UIView beginAnimations:@"newsimage_disappear_Animation" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.3];
[UIView setAnimationDelegate:self];
float scale1=imageRect.size.width/imgInScrollViewRect.size.width;
float scale2=imageRect.size.height/imgInScrollViewRect.size.height;
MNZoomScrollView *view=(MNZoomScrollView *)[_imageScrollView subviews][removeImageIndex];
UIImageView *imgView=(UIImageView *)[view subviews][0];
imgView.frame=imgInScrollViewRect;
UIImage *image=[imageDownloaded objectAtIndex:removeImageIndex];
imgView.image=image;
CGAffineTransform currentTransform=imgView.transform;
CGAffineTransform newTransform=CGAffineTransformScale(currentTransform, scale1, scale2);
[imgView setTransform:newTransform];
imgView.frame=imageRect;
UIColor *bgColor=_imageScrollView.backgroundColor;
[_imageScrollView setBackgroundColor:[bgColor colorWithAlphaComponent:0.5]];
[UIView setAnimationDidStopSelector:@selector(animationStopRomove)];
[UIView commitAnimations];
}
-(void)animationStopRomove{
MNZoomScrollView *view=(MNZoomScrollView *)[_imageScrollView subviews][removeImageIndex];
UIImage *image=[imageDownloaded objectAtIndex:removeImageIndex];
CGRect imgRect=[_imageScrollView setImageFrame:image];
UIImageView *imgView=(UIImageView *)[view subviews][0];
[imgView setFrame:imgRect];
UIColor *bgColor=_imageScrollView.backgroundColor;
[_imageScrollView setBackgroundColor:[bgColor colorWithAlphaComponent:0]];
[_imageScrollView removeFromSuperview];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView{
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"WebKitCacheModelPreferenceKey"];
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDiskImageCacheEnabled"];//自己添加的,原文没有提到。
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitOfflineWebApplicationCacheEnabled"];//自己添加的,原文没有提到。
[[NSUserDefaults standardUserDefaults] synchronize];
if (IS_PHONE) {
self.imageURLArray=[[NSMutableArray alloc]initWithArray:[self getWebViewPictureUrlString]];
dispatch_queue_t queue=dispatch_queue_create("imagedownload", NULL);
dispatch_async(queue, ^{
[self asynRequestForImageArr:self.imageURLArray fromIndex:0];
});
}
}
-(void)asynRequestForImageArr:(NSMutableArray *)imageURLArr fromIndex:(NSInteger)index{
NSInteger count=0;
if (!_imageScrollView) {
_imageScrollView=[[RequestImageScrollView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) imageURLArray:self.imageURLArray];
_imageScrollView.removeDeleate=self;
}else{
[_imageScrollView setImageURLArray:imageURLArr];
}
if (!imageArray) {
imageArray=[[NSMutableArray alloc]initWithArray:imageURLArr];
}else{
[imageArray removeAllObjects];
[imageArray addObjectsFromArray:imageURLArr];
[imageArray replaceObjectsInRange:NSMakeRange(0, index) withObjectsFromArray:imageDownloaded range:NSMakeRange(0, [imageDownloaded count])];
}
__block NSMutableArray *tmpImageArray=imageArray;
__block NSInteger tmpCoun=count;
__block NSMutableArray *tmpImageDownloaded=imageDownloaded;
for (int i=index; i<[imageURLArr count]; i++) {
NSString *imageURLString=[imageURLArr objectAtIndex:i];
__block NSInteger tmpI=i;
NSURLRequest *request=[[NSURLRequest alloc]initWithURL:[NSURL URLWithString:imageURLString]];
imageRequestOperation=[AFImageRequestOperation imageRequestOperationWithRequest:request imageProcessingBlock:nil success:^(NSURLRequest *request,NSHTTPURLResponse *response,UIImage *image){
[tmpImageArray replaceObjectAtIndex:tmpI withObject:image];
tmpCoun++;
if (tmpCoun==[imageURLArr count]-index) {
NSLog(@"success!");
[_imageScrollView getDownloadedImageArray:tmpImageArray fromIndex:index];
[tmpImageDownloaded removeAllObjects];
[tmpImageDownloaded addObjectsFromArray:tmpImageArray];
NSMutableDictionary *imageDownloadedDic=[[[NSMutableDictionary alloc]initWithObjectsAndKeys:imageURLArr,@"imageURLArr", nil]autorelease];
[[NSNotificationCenter defaultCenter]postNotificationName:@"d.cnfinishimageDownloaded" object:nil userInfo:imageDownloadedDic];
}
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
}];
[imageRequestOperation start];
}
}