图片 2

IOS_二十十六线程_ASI_AFN_UIWebView

By admin in 澳门新葡亰官网app on 2019年8月20日

H:/0730/00_多线程4种售票_ViewController.h

[iOS 多线程 & 网络,ios多线程

A.AFN基本知识 1.概念

  • AFNetworking
  • 是对NSURLConnection的封装
  • 运行效率没有ASI高(因为ASI基于CFNetwork),但是使用简单
  • AFN支持ARC

    B.基本请求使用 1.基本使用 (1)头文件 AFNetworking.h
(2)管理者类:AFHTTPRequestOperationManager
(3)“GET”方法发送GET请求,使用“POST”方法发送POST请求
(4)使用字典发送参数 (5)block处理请求成功/失败  

 1 /** 发送 GET/POST 请求 */
 2 - (void) sendNormalRequest {
 3     // 1.创建请求 管理者
 4     AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
 5    
 6     // 2.设置参数
 7     NSMutableDictionary *param = [NSMutableDictionary dictionary];
 8     param[@"user"] = @"tom";
 9     param[@"password"] = @"123";
10    
11     // 3.发送请求
12 //    // 3.1 GET请求
13 //    [manager GET:@"http://192.168.0.21:8080/MyTestServer/login" parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {
14 //        NSLog(@"请求成功");
15 //        NSLog(@"%@", responseObject);
16 //    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
17 //        NSLog(@"请求失败");
18 //        NSLog(@"%@", error);
19 //    }];
20    
21     // 3.2 POST请求
22     [manager POST:@"http://192.168.0.21:8080/MyTestServer/login" parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {
23         NSLog(@"请求成功");
24         NSLog(@"%@", responseObject);
25     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
26         NSLog(@"请求失败");
27         NSLog(@"%@", error);
28     }];
29 }

  2.为了方便查看服务器返回的中文数据,给数组和字典增加一个分类,支持中文

 1 #import <Foundation/Foundation.h>
 2 
 3 @implementation NSDictionary (Log)
 4 
 5 /** 本地化显示 */
 6 - (NSString *)descriptionWithLocale:(id)locale {
 7     NSMutableString *str = [NSMutableString string];
 8    
 9     [str appendString:@"{\n"];
10    
11     // 遍历字典
12     [self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
13         [str appendFormat:@"\t%@ = %@,\n", key, obj];
14     }];
15    
16     [str appendString:@"}"];
17    
18     // 取出最后一个“,”
19     NSRange range = [str rangeOfString:@"," options:NSBackwardsSearch];
20     [str deleteCharactersInRange:range];
21    
22     return str;
23 }
24 
25 @end
26 
27 @implementation NSArray (Log)
28 
29 - (NSString *)descriptionWithLocale:(id)locale {
30     NSMutableString *str = [NSMutableString string];
31    
32     [str appendString:@"[\n"];
33    
34     // 遍历数组所有元素
35     [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
36         [str appendFormat:@"%@, \n", obj];
37     }];
38    
39     [str appendString:@"]"];
40    
41     return str;
42 }
43 
44 @end

    3.解析返回的json数据

  • AFHTTPRequestOperationManager
    依靠设置序列化器来自动识别、解析返回的数据
  • 默认使用的就是json解析,可以不用设置序列化器
  • 会把json自动转换成为字典或者数组输出

 1 /** 返回json数据 */
 2 - (void) getJson {
 3     // 1.创建请求 管理者
 4     AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
 5    
 6     // 设置序列化器
 7 //    [manager setResponseSerializer:[AFJSONResponseSerializer serializer]];//默认
 8  
 9     // 2.设置参数
10     NSMutableDictionary *param = [NSMutableDictionary dictionary];
11     param[@"type"] = @"json";
12    
13     // 3.发送请求
14     [manager GET:@"http://192.168.0.21:8080/MyTestServer/video" parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {
15         NSLog(@"请求成功");
16         NSLog(@"返回的数据类型是:%@", [responseObject class]);
17         NSLog(@"%@", responseObject);
18     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
19         NSLog(@"请求失败");
20         NSLog(@"%@", error);
21     }];
22 }

  output: 2015-01-30 03:34:14.817
AFNBasicDemo[1889:192783]
 请求成功
2015-01-30 03:34:14.817
AFNBasicDemo[1889:192783]
 返回的数据类型是:__NSCFDictionary
2015-01-30 03:34:14.818 AFNBasicDemo[1889:192783] {
videos = [
{
name =
 驯龙高手1,
video = videos/1.MP4,
length = 16秒,
image = images/[20150124-180852-0].PNG
},    
4.解析返回的xml数据
设置使用xml序列化器,也可以自动将xml数据转换成为字典或者数组
如果不设置xml序列化器,处理返回数据会失败  

 1 /** 返回xml数据 */
 2 - (void) getXml{
 3     // 1.创建请求 管理者
 4     AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
 5    
 6     // 设置序列化器
 7     [manager setResponseSerializer:[AFXMLParserResponseSerializer serializer]];
 8    
 9     // 2.设置参数
10     NSMutableDictionary *param = [NSMutableDictionary dictionary];
11     param[@"type"] = @"xml";
12    
13    
14     // 3.发送请求
15     __weak typeof(self) vc = self;
16     [manager GET:@"http://192.168.0.21:8080/MyTestServer/video" parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {
17         NSLog(@"请求成功");
18         NSLog(@"返回的数据类型是:%@", [responseObject class]);
19        
20         NSXMLParser *parser = (NSXMLParser *) responseObject;
21         parser.delegate = vc;
22         [parser parse];
23     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
24         NSLog(@"请求失败");
25         NSLog(@"%@", error);
26     }];
27 }

    C.文件下载/上传 1.文件下载

  • 也是简单发送请求
  • 但是没有ASI那样的监听功能

 1 - (void) downloadFile {
 2     // 1.创建请求管理者
 3     AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
 4    
 5     // 设置序列化器
 6     [manager setResponseSerializer:[AFHTTPResponseSerializer serializer]]; // 使用二进制数据序列化
 7    
 8     // 3.发送请求
 9     [manager GET:@"http://192.168.0.21:8080/MyTestServer/images/images.zip" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
10        
11         NSLog(@"请求成功");
12         NSLog(@"返回的数据类型是:%@", [responseObject class]);
13        
14         NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
15         NSString *filePath = [cachePath stringByAppendingPathComponent:@"download.zip"];
16         NSData *data = (NSData *) responseObject;
17         [data writeToFile:filePath atomically:YES];
18        
19     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
20         NSLog(@"请求失败");
21         NSLog(@"%@", error);
22     }];
23 }

    2.文件上传

  • 使用POST请求,带formData的post方法
  • 要区分普通参数和文件参数,把文件数据放在普通参数中上传是不行的
  • 文件放在block参数中赋值

(1)把文件转换成二进制数据 (2)拼接文件参数  

 1 /** 上传文件 */
 2 - (void) uploadFile {
 3     // 1.创建请求管理者
 4     AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
 5    
 6     // 2.设置参数
 7     NSMutableDictionary *param = [NSMutableDictionary dictionary];
 8     param[@"user"] = @"uploader";
 9    
10     // 3.设置上传文件
11     NSString *filePath = [[NSBundle mainBundle] pathForResource:@"M2.jpg" ofType:nil];
12     NSData *fileData = [NSData dataWithContentsOfFile:filePath];
13    
14     // 4.上传文件
15     __weak typeof(fileData) uploadData = fileData;
16    
17     [manager POST:@"http://192.168.0.21:8080/MyTestServer/upload" parameters:param constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
18        
19         // 拼接文件数据
20         [formData appendPartWithFileData:uploadData name:@"uploadedFile" fileName:@"my_pic.jpg" mimeType:@"image/jpg"];
21        
22     } success:^(AFHTTPRequestOperation *operation, id responseObject) {
23         NSLog(@"上传成功 ---- %@", responseObject);
24     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
25         NSLog(@"上传失败 ---- %@", error);
26     }];
27 }

    D.网络状态监控 AFNetworkReachabilityManager
(1)创建网络监控管理者 (2)设置监控网络状态变化 (3)开启监控
(4)也可以主动去获取网络状态  

 1 - (IBAction)monitorNetwork:(UIButton *)sender {
 2     // 1.创建网络状态监控管理者
 3     AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
 4    
 5     // 2.网络状态改变事件(被动检测)
 6     [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
 7         switch (status) {
 8             case AFNetworkReachabilityStatusUnknown:
 9                 NSLog(@"转换为未知网络");
10                 break;
11             case AFNetworkReachabilityStatusReachableViaWWAN:
12                 NSLog(@"转换为手机网络");
13                 break;
14             case AFNetworkReachabilityStatusReachableViaWiFi:
15                 NSLog(@"转换为WIFI网络");
16                 break;
17             case AFNetworkReachabilityStatusNotReachable:
18                 NSLog(@"转换为没有网络");
19                 break;
20                
21             default:
22                 break;
23         }
24     }];
25    
26     // 开启监控
27     [manager startMonitoring];
28    
29     // 主动检测
30     if ([manager isReachable]) {
31         NSLog(@"现在有网络");
32     } else if ([manager isReachableViaWiFi]) {
33         NSLog(@"现在是通过wifi上网");
34     } else if ([manager isReachableViaWWAN]) {
35         NSLog(@"现在是通过手机网络上网");
36     } else {
37         NSLog(@"现在没有网络");
38     }
39 }

 

多线程 网络,ios多线程 A.AFN基本知识 1.概念
AFNetworking 是对NSURLConnection的封装
运行效率没有ASI高(因为ASI基于CFNetwork),但是使用简单…

本篇文章基于UIWebView进行介绍,详细demo在这里。在开发过程中避免不了使用网页进行数据展示和操作,JS与OC的交互就起到了很大的作用。WKWebView是在ios8.0以后出现的,在下一篇文章,会介绍关于WKWebView中JS与OC之间的交互。

//
//  ViewController.h
//  卖票
//
//  Created by apple on 13-7-29.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import 

@interface ViewController : UIViewController

// 多行文本提示框
@property (weak, nonatomic) IBOutlet UITextView *infoTextView;

// NSThread售票
- (IBAction)threadSales:(id)sender;

// NSInvocationOperation售票
- (IBAction)invocationSales:(id)sender;

// NSBlockOperation售票
- (IBAction)blockSales:(id)sender;

// GCD售票
- (IBAction)gcdSales:(id)sender;

@end

JS与OC的交互是双向的。

H:/0730/00_多线程4种售票_ViewController.m

第一步,OC调用JS

NSString *js_str = [NSString stringWithFormat:@"alert", @"oc调用js"]; //准备执行的js代码 [webPageView stringByEvaluatingJavaScriptFromString:js_str];

图片 1image.png

//  ViewController.m
//  卖票
//  Created by apple on 13-7-29.
#import "ViewController.h"
@interface ViewController ()
{
    NSInteger   _tickets;
    // 线程锁NSLock,必须是成员变量,不能是局部变量
    NSLock      *_lock;
}
// 下面的atomic成员,结合同步代码块使用,@synchronized (self) {}
@property (assign, atomic) NSInteger tickets;
/*
 1. 在做多线程NSOperation和GCD技术的时候,抢夺的内存资源必须是“原子属性”——atomic
 2. 抢夺的资源在使用的时候,
  //一定要用属性的self.xxx或者object.xxx,这样才getter,才atomic发挥作用
 3. 要在Operation和GCD中抢夺资源,需要使用到“同步锁”,@synchronized(self){...}
   //目的是,锁住与抢夺资源相关的代码,包括读和写
 4. 平时,尽量不要用抢夺资源去做判断条件,并且同步锁的范围越小越好!
*/

@end
@implementation ViewController

/*
  // 同步锁是要手敲出来的
  @synchronized (self) {

  }
*/

// 为了在TextView里面增加文本,更新界面,需要先写一个方法处理。
// 1. 读出当前文本框的内容
// 2. 把要追加的文本附加在当前文本框内容的后面
// 3. 重新为文本框赋值
// 这是负责更新界面的UI
- (void)appendTextView:(NSString *)text
{
    NSMutableString *str = [NSMutableString stringWithString:_infoTextView.text];
    [str appendFormat:@"\n%@", text];
    [_infoTextView setText:str];
    // 定义一个NSRange,代表文本框需要滚动到的位置    
    NSRange range = NSMakeRange(str.length, 1);
 // 我们现在想要滚动到最后,这个方法的参数是一个NSRange    
    [_infoTextView scrollRangeToVisible:range];
}

// 多线程一:响应按钮点击,启动NSThread售票
- (IBAction)threadSales:(id)sender
{   
    _tickets = 100;    
    // 创建线程 NSThread1
    NSThread *thread1 = [[NSThread alloc]initWithTarget:self
    selector:@selector(threadSaleMethod) object:nil];
    // 设置线程1的名字
    [thread1 setName:@"售票线程-1"];
    // 启动线程 NSThread1 只有NSThread需要手动start
    [thread1 start];
    // 创建线程 NSThread2
    NSThread *thread2 = [[NSThread alloc]initWithTarget:self
    selector:@selector(threadSaleMethod) object:nil];
 // 设置线程2的名字
    [thread2 setName:@"售票线程-2"];
    // 启动线程 NSThread2 只有NSThread需要手动start 
    [thread2 start];
}

// 多线程一:实际NSThread售票运行的代码,线程跑的方法
#pragma mark - 自定义方法,NSThread售票核心代码
- (void)threadSaleMethod
{
    // 1. 判断是否还有票
    // 2. 更新界面,提示当前票数
    // 3. 总票数-1
    // 4. 模拟延时
    // 要解决一个问题:在threadSaleMethod这一个方法里面,我们就把所有的票卖光!!!
    // 线程锁:所谓线程锁,就是:在修改或者判断共享资源的时候,
    //需要把共享资源加锁,防止别的线程对
    // 共享资源进行修改。
    // 使用线程锁的方式:
    // 1. 定义锁,懒加载,且锁必须是成员变量
    if (_lock == nil) {
        _lock = [[NSLock alloc]init];
    }    
    while (YES) {
  // 2. 使用共享资源之前,加锁  
        [_lock lock];
        if (_tickets > 0) {
            // 做了一个字符串,显示提示信息
            NSString *str = [NSString stringWithFormat:@"当前票数是%d,售票线程是%@", _tickets, [[NSThread currentThread]name]];

            // 主线程,UI界面中显示一下票数
            // 在多线程方法里面不能这样使用的
            //        [self appendTextView:@"12"];
            // waitUntilDone 的意思是:是否等待主线程更新完毕
            [self performSelectorOnMainThread:@selector(appendTextView:)
          withObject:str waitUntilDone:YES];
   // 售完一张,票数减1
            _tickets--;
            // 3. 使用共享资源完毕,立即解锁  
            [_lock unlock];
            // 模拟不同售票效率
            if ([[[NSThread currentThread]name] isEqualToString:@"售票线程-1"]) {
                [NSThread sleepForTimeInterval:0.2];
            } else {
                [NSThread sleepForTimeInterval:0.3];
            }                    
        } else {
            // 3. 使用共享资源完毕,立即解锁  
            [_lock unlock];            
   // 结束时,打印下线程名
            NSString *str = [NSString stringWithFormat:@"票已售完%@",
       [[NSThread currentThread]name]];
   // 主线程,UI界面中显示一下哪个线程结束了
            [self performSelectorOnMainThread:@selector(appendTextView:) 
       withObject:str waitUntilDone:YES];
            NSLog(@"%@", str);
            // 退出循环
            break;
        }
    }
}

// 多线程二:响应按钮点击,通过NSInvocationOperation添加到NSOperationQueue售票
- (IBAction)invocationSales:(id)sender
{
    _tickets = 20;
    // 1. 定义2个NSInvocationOperation操作
    // 1.1. 操作需要调用一个target对象的selector方法,类似NSThread
    // 1.2. 第3个参数object代表:方法是可以接收参数的,且只能接收一个。
    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self
      selector:@selector(operationSaleMethod:) object:@"Operation - 1"];
    NSInvocationOperation *operation2 = [[NSInvocationOperation alloc]initWithTarget:self
      selector:@selector(operationSaleMethod:) object:@"Operation - 2"];    
    // 2. 定义1个操作队列NSOperationQueue
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    // 3. 将2个操作逐一添加到操作队列,自动启动
    [queue addOperation:operation1];
    [queue addOperation:operation2];
}
// 多线程二:通过NSInvocationOperation添加到NSOperationQueue售票运行的代码,线程跑的方法
// 同样也是多线程三:通过NSOperationQueue的block售票的核心代码,线程跑的方法
#pragma mark - NSOperation售票,使用@synchronized(self){}
// NSOperation售票方法,参数是上面方法定义的操作名称
- (void)operationSaleMethod:(NSString *)operationName
{
    // 卖票流程——在这一个方法里面,我们需要把所有的票卖光!!!
    // 1. 是否有票
    // 2. 显示当前票数
    // 3. 票数-1
    // 4. 通过延时,模拟效率
    while (YES) {
        // !!!同步锁要锁住所有抢夺资源的代码
        // 平时,尽量不要用抢夺的资源做判断条件,会增加同步锁的范围,降低效率!
        @synchronized(self) {
            if (self.tickets > 0) {
                NSString *str = [NSString stringWithFormat:@"当前票数:%d,线程名称:%@",
        self.tickets, operationName];
                // 主线程队列“只”负责更新UI
                // 把所有的成员变量调用的位置都改成了getter方式调用,发挥atomic关键字
                // 属性调用是通过getter,这样调用才能发挥atomic的作用
                [[NSOperationQueue mainQueue]addOperationWithBlock:^{
                    // 在NSOperationQueue的主队列中,只负责更新界面UI
                    [self appendTextView:str];
                }];
                self.tickets--;
    // 通过延时,模拟不同售票效率
                if ([operationName isEqualToString:@"Operation - 1"] ||
        [operationName isEqualToString:@"Block - 1"]) {
                    [NSThread sleepForTimeInterval:0.2];
                } else {
                    [NSThread sleepForTimeInterval:1.0];
                }
            } else {
    NSString *str = [NSString stringWithFormat:@"票已售完,线程名称:%@",
        operationName];
    // 在NSOperationQueue的主队列中,只负责更新界面UI    
                [[NSOperationQueue mainQueue]addOperationWithBlock:^{                    
                    [self appendTextView:str];
                }];
                break;
            }
        }//同步代码块@synchronized,到这儿才结束
    }
}

// 多线程三:响应按钮点击,通过NSOperationQueue的block售票
- (IBAction)blockSales:(id)sender
{
    _tickets = 20;
 // 1,定义NSOperationQueue操作队列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
 // 2,通过block给操作队列添加自定义方法,并执行
    [queue addOperationWithBlock:^{
        [self operationSaleMethod:@"Block - 1"];
    }];
 // 2,通过block给操作队列添加自定义方法,并执行
    [queue addOperationWithBlock:^{
        [self operationSaleMethod:@"Block - 2"];
    }];
 // 2,通过block给操作队列添加自定义方法,并执行
    [queue addOperationWithBlock:^{
        [self operationSaleMethod:@"Block - 3"];
    }];
 // 3,设置NSOperationQueue操作队列,最大并发执行任务个数
    [queue setMaxConcurrentOperationCount:2];
}
// 多线程四:响应按钮点击,通过GCD grand central dispatch售票
- (IBAction)gcdSales:(id)sender
{
    _tickets = 20;
    // 1. 获取全局队列 dispatch_get_global_queue,参数1为默认优先级,
    // 参数2标记永远是0
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    // 2. 创建小组 dispatch_group_create
    dispatch_group_t group = dispatch_group_create();
    // 3. 向小组添加异步任务一,dispatch_group_async
 // 参数1,小组名
 // 参数2,全局队列名
 // 参数3,block,即指定具体要执行的方法,可带参数:名字
    dispatch_group_async(group, queue, ^{
        [self gcdSaleMethod:@"GCD-1"];
    });
 // 3. 向小组添加异步任务二,dispatch_group_async
 // 参数1,小组名
 // 参数2,全局队列名
 // 参数3,block,即指定具体要执行的方法,可带参数,名字
    dispatch_group_async(group, queue, ^{
        [self gcdSaleMethod:@"GCD-2"];
    });
    // 4. 监听小组通知
 // 参数1,小组名
 // 参数2,获得主队列 dispatch_get_main_queue()
 // 参数3,block代码块:所有异步任务都完成时,要做的事情!!!
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        // 提示用户没有票了!更新到界面UI
        [self appendTextView:@"票已售完!"];
    });
}

// 多线程四:通过GCD向小组添加的异步任务,即线程跑的方法
#pragma mark - GCD售票 具体卖票流程
- (void)gcdSaleMethod:(NSString *)gcdName
{
    // 1. 确认票数
    // 2. 更新界面
    // 3. 票数-1
    // 4. 模拟延时
    while (YES) {
        if (_tickets > 0) {
            // 1. 确定要更新的内容
   NSString *str = [NSString stringWithFormat:@"当前票数:%d, 售票线程:%@",
       _tickets, gcdName];
            // 2. dispatch_async(),开启异步任务,
   //  参数1,要在哪个地方执行该异步任务:dispatch_get_main_queue()
   //  参数2,block指明要执行的具体异步任务:更新UI界面,并且票数-1
            dispatch_async(dispatch_get_main_queue(), ^{
                [self appendTextView:str];
    // GCD中 对共用资源的修改也要放到获得的主队列里
                _tickets--;
            });
            // 通过延时,模拟不同售票效率
            if ([gcdName isEqualToString:@"GCD-1"]) {
                [NSThread sleepForTimeInterval:0.2];
            } else {
                [NSThread sleepForTimeInterval:1.0];
            }
        } else {
            break;
        }
    }
}
@end

第二步,JS调用OC方法

本篇文章通过声明代理并遵循JSExport协议来完成调用。注:代理声明的方法与调用的方法名保持一致。

H5代码:

window.test.showAlert('js调用oc本地方法');

注意:test为h5与移动端约定的上下文id。

代理类JSObject.h

#import <Foundation/Foundation.h>#import <JavaScriptCore/JavaScriptCore.h>@protocol JSObjcDelegate <JSExport>/** * 调起弹窗 * tip 描述文案 */- showAlert:(NSString *)tip;@endNS_ASSUME_NONNULL_BEGIN//必须遵循代理,否则方法调用不生效@interface JSObject : NSObject<JSObjcDelegate>@property(nonatomic, weak)id<JSObjcDelegate> delegate;@endNS_ASSUME_NONNULL_END

注意:在.h中声明代理的同时,要遵循代理协议,否则代理方法是无法调起的。

JSObject.m

#import "JSObject.h"@implementation JSObject//调起弹窗- showAlert:(NSString *)tip{ [self.delegate showAlert:tip];}@end

方法的实现放到控制器的.m中,如果需要放到base类中实现,也可以放到baseVC中,如下:ViewController.m

//本地方法的具体实现- showAlert:(NSString *)tip{ UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"测试" delegate:nil cancelButtonTitle:tip otherButtonTitles:@"OK", nil]; [alert show];}

以上是本地方法代理的声明以及方法的实现,然而,如何调用呢?接下来是方法的调用:ViewController.m初始化UIWebView:

- viewDidLoad { [super viewDidLoad]; webPageView = [UIWebView new]; webPageView.delegate = self; webPageView.scalesPageToFit = YES; webPageView.frame = CGRectMake(0, 0, KScreenWidth, KScreenHeight - 50); [self.view addSubview:webPageView];// [webPageView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]]]; NSString *path = [[NSBundle mainBundle] pathForResource:@"myHtml" ofType:@"html"]; [webPageView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]]];}

通过JSContext实现本地方法与JS的连接:

//js调用oc本地方法- js_ocMethod{ //方法类 JSObject *jsObject = [JSObject new]; jsObject.delegate = self; //js执行环境,包含了js执行时所需要的所有函数和对象 JSContext *jsContext = [webPageView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; //test:H5与移动端约定的id jsContext[@"test"] = jsObject; jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) { context.exception = exceptionValue; NSLog(@"异常信息:%@", exceptionValue); };}

并在– webViewDidFinishLoad:(UIWebView )webView代理方法中调用
js_ocMethod*即可。

图片 2image.png

最后,这是html文件中的代码,该文件在也已经包含在Demo中

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>标题</title></head><body><div><p h3>JS与OC交互</p></div><div><!-- 初始化一个按钮,点击调用boc本地方法 --><input type="button" value="OC本地弹窗" onclick="show()"></div><script type="text/javascript"> //show为按钮点击的响应事件 //showAlert为oc本地方法 //test为q移动端与h5约定的id function show(){ window.test.showAlert('js调用oc本地方法'); }</script></body></html>

iOS技术交流群:681732945

H:/0730/01_ASI_ViewController.h

//  ViewController.h
//  ASI演练
//  Created by apple on 13-7-30.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import 
#import "ASIHTTPRequest.h"
@interface ViewController : UIViewController 
// 响应按钮点击,下载文件
- (IBAction)downloadFile:(id)sender;
@end

H:/0730/01_ASI_ViewController.m

//  ViewController.m
//  ASI演练
/*
ASI工程注意事项:
 1,不能选ARC
 2,更改IOS 部署 目标为 IOS5.0
 3,将ASI压缩包,解压,拖动Classes文件夹和External目录拖进工程
 4,尝试编译,出现错误:无法找到libxml/HTMLparser.h
  解决方法:
  进入build settings,找到_head search paths头文件搜索目录_添加:
  ${SDK_DIR}/usr/include/libxml2,并回车
 5,再次尝试编译,出现错误:ASITestCase.h:12:9: 'GHUnitIOS/GHUnit.h' file not found
  错误原因:没有GHUnit框架
  解决办法:
  进入build phases
  展开compile sources
  将tests结尾的文件全部移除,按减号,即测试文件,不参与编译
  即删除单元测试部分的代码引用
 6,再次command B 编译,85个错误
  解决方法:
  很简单,进入summary,找到链接的框架和引用,+号,添加下列iOS框架引用即可
  CFNetwork.framework
  SystemConfiguration.framework
  MobileCoreServices.framework
  libz.dylib
  libxml2.dylib
 7,上述框架,在ASI提供的工程样本中可以看到,再次编译OK
 8,为了解压缩,还要添加SSZipArchive框架
  将以下文件加入工程:
  SSZipArchive.h
  SSZipArchive.m
  minizip文件夹
 9,编译OK
*/
//  Created by apple on 13-7-30.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import "ViewController.h"
#import "SSZipArchive.h"
// 遵守两个ASI协议 
@interface ViewController ()
{
    // 下载文件的大小,头信息字典中的文件长度,在后面进度中要用到
    CGFloat   _fileLength;
}
@end
@implementation ViewController
#pragma mark - 响应按钮点击,开始启动ASI框架断点续传下载文件
- (IBAction)downloadFile:(id)sender
{
    // 1.   指定下载文件地址
    NSString *urlString = @"http://teacher.local/~apple/itcast/download/iTunesConnect_DeveloperGuide_CN.zip";
    NSURL *url = [NSURL URLWithString:urlString];
    // 2.   设定文件保存路径及临时缓存路径
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
       NSUserDomainMask, YES);
    //保存路径
    NSString *downloadPath = [documents[0]stringByAppendingPathComponent:@"book.zip"];
 //缓存路径
    NSString *tempPath = [documents[0]stringByAppendingPathComponent:@"book.tmp"];
    // 3.   通过URL,初始化ASIHTTPRequest实例对象,不支持ARC
    ASIHTTPRequest *request = [[[ASIHTTPRequest alloc]initWithURL:url]autorelease];
    // 4.   设置代理为当前控制器——ASI是通过代理回调的方式处理网络请求的
    [request setDelegate:self];
    // 5.   设置下载完毕的保存路径
    [request setDownloadDestinationPath:downloadPath];
    // 6.   设置临时缓存路径
    [request setTemporaryFileDownloadPath:tempPath];
    // 7.   设置允许断点续传
    [request setAllowResumeForFileDownloads:YES];
    // 8.   设置下载进程代理——用户想知道下载的实际进展情况
    [request setDownloadProgressDelegate:self];
    // 9.   启动异步请求
    [request start];
}
#pragma mark - ASI代理方法
// 2. 接收到响应头 didReceiveResponseHeaders 目的获得文件长度
- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders
{
    // 通过Log,我们看到了"Content-Length" = 6105204;
    // 貌似可以用来监控下载进度
    // 暂时不去管它
    NSLog(@"请求头%@", responseHeaders);
    // 在这里,我们能够知道文件长度,如果我们在这里记录下来文件的长度,假设100M
    // 需要获得的是文件的兆数会更加人性化 字节->K->M(1024)
    NSInteger length = [responseHeaders[@"Content-Length"]integerValue];
    // 文件长度计算之后,是一个小数,需要改变一下成员变量的类型
    _fileLength = (CGFloat)length / 1024 / 1024;
}
#pragma mark - 下载进度的代理方法
- (void)setProgress:(float)newProgress
{
    // 传回来的参数是一个下载进度的百分比
    // 那么,我们告诉用户还差多少M下载完成?
    NSLog(@"%.2f", newProgress * _fileLength);
    // 100M * 0.2 = 20M
}

#pragma mark - ASI代理方法
// 3. 请求完成 requestFinished
- (void)requestFinished:(ASIHTTPRequest *)request
{
    NSLog(@"请求完成");
    // 我们可以去做解压缩的工作了。因为下载工作已经完成了!
    // 需求:
    // 1. 知道文件保存路径
    // 2. 解压缩文件
    // 2.1 定义一个压缩文件
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
      NSUserDomainMask, YES);
    NSString *downloadPath = [documents[0]stringByAppendingPathComponent:@"book.zip"];    
    // 2.3 调用SSZipArchive的类方法解压缩,参数2是一个目录
    [SSZipArchive unzipFileAtPath:downloadPath toDestination:documents[0]];
    // 3. 通过文件管理者(单例),删除压缩文件
    [[NSFileManager defaultManager]removeItemAtPath:downloadPath error:nil];
}


#pragma mark - ASI代理方法
// 代理方法之1. 请求开始
- (void)requestStarted:(ASIHTTPRequest *)request
{
    NSLog(@"请求开始");
}
#pragma mark - ASI代理方法
// 代理方法之4. 请求失败
- (void)requestFailed:(ASIHTTPRequest *)request
{
    NSLog(@"请求失败");
}
@end

H:/0730/02_AFN_ViewController.h

//
//  ViewController.h
//  AFN断点续传演练
//
//  Created by apple on 13-7-30.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import 

@interface ViewController : UIViewController

// 下载文件
- (IBAction)downloadFiles:(id)sender;

@end

H:/0730/02_AFN_ViewController.m

//  ViewController.m
//  AFN断点续传演练
//  Created by apple on 13-7-30.
//  Copyright (c) 2013年 itcast. All rights reserved.
/*
 AFN使用步骤:
 1,新建工程的时候,勾选ARC(毕竟AFN有是人在维护的)
 2,拖动文件夹AFNetworking到工程中
 3,将解压要用到的文件夹SSZipArchive拖到工程中
  同时导入它依赖的libz.dylib框架 
 4,编译,弹出2个warning,缺少框架
  SystemConfiguration.framework
  MobileCoreServices.framework
 5,展开supporting files文件夹,找到-->
  工程名-Prefix.pch文件,在#endif的前面添加
  #import
  #import
 6,再次编译ok
*/
#import "ViewController.h"
#import "AFNetworking.h"
#import "SSZipArchive.h"
@interface ViewController ()
@end
@implementation ViewController
#pragma mark - 下载文件
- (IBAction)downloadFiles:(id)sender
{
    // 1.   指定下载文件地址
    NSURL *url = [NSURL URLWithString:@"http://169.254.98.245/~apple/itcast/download/iTunesConnect_DeveloperGuide_CN.zip"];
    // 2.   指定文件保存路径
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
       NSUserDomainMask, YES);
    NSString *downloadPath = [documents[0]stringByAppendingPathComponent:@"book.zip"];
    // 3.   创建NSURLRequest
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    // 4.   通过固定请求,创建AFURLConnectionOperation,多态
    AFURLConnectionOperation *operation = [[AFHTTPRequestOperation alloc] 
        initWithRequest:request];
    // 5.   设置操作的输出流(在网络中的数据是以流的方式传输的,
   //告诉操作把文件保存在第2步设置的路径中)
    [operation setOutputStream:[NSOutputStream
     outputStreamToFileAtPath:downloadPath append:NO]];
    // 6.   设置下载进程处理块代码
    // 6.1 bytesRead 读取的字节——这一次下载的字节数
    // 6.2 totalBytesRead 读取的总字节——已经下载完的
    // 6.3 totalBytesExpectedToRead 希望读取的总字节——就是文件的总大小
    [operation setDownloadProgressBlock:^(NSUInteger bytesRead,
   long long totalBytesRead, long long totalBytesExpectedToRead) {
        // 做下载进度百分比的工作
        NSLog(@"下载百分比:%f", (float)totalBytesRead / totalBytesExpectedToRead);
    }];
    // 7.   操作完成块代码
    [operation setCompletionBlock:^{
        // 解压缩的顺序
        // 1. 定义要解压缩的文件 —— downloadPath
        // 2. 要解压缩的目标目录,必须是目录
        // 3. 调用类方法解压缩
        [SSZipArchive unzipFileAtPath:downloadPath toDestination:documents[0]];

        // 使用文件管理者,删除压缩包
        [[NSFileManager defaultManager]removeItemAtPath:downloadPath error:nil];
    }];
    // 8   启动操作
    [operation start];
}
@end

H:/0730/04_UIWebView_ViewController.h

//
//  ViewController.h
//  UIWebView演练
//
//  Created by apple on 13-7-30.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import 

@interface ViewController : UIViewController

// 成员属性:UIWebView控件
@property (weak, nonatomic) IBOutlet UIWebView *localWebView;

// 点击,加载PDF文件按钮
- (IBAction)clickPDFButton:(id)sender;
// 点击,加载HTMLString
- (IBAction)loadHTMLString:(id)sender;

// 点击,使用loadData加载数据
- (IBAction)loadData:(id)sender;

@end

H:/0730/04_UIWebView_ViewController.m

//  ViewController.m
//  UIWebView演练
//  Created by apple on 13-7-30.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
 // 通过自定义方法获得MIMETYPE
    [self mimeType];
}
// 自定义方法,获取MIMEType
// 因为我们不能记住所有类型文档的MIMEType,所以我们自己动手,写一个方法
- (NSString *)mimeType
{
    // 一。本地文件URL生成的过程
    // 1. 绝对路径
    NSString *path = [[NSBundle mainBundle]pathForResource:@"关于.docx" ofType:nil];
    // 2 绝对路径转FILEURL
    NSURL *fileURL = [NSURL fileURLWithPath:path];
    // 二。网络文件URL生成的过程
    // 1. 网络地址字符串
    NSString *urlString = @"http://www.baidu.com";
    // 2. 生成URL
    NSURL *webURL = [NSURL URLWithString:urlString];
    // 1. 定义固定请求
    NSURLRequest *request = [NSURLRequest requestWithURL:fileURL];
    // 2. 定义响应,到时候,传入地址,到时候方便接收返回的response
    NSURLResponse *response = nil;
    // 3. NSConnection静态方法,发送同步请求,传入接收响应的地址
    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
    NSLog(@"MIMEType %@", response.MIMEType);
    return response.MIMEType;
}
// 响应按钮点击事件,
- (IBAction)clickPDFButton:(id)sender
{
    [self viewLocalPDFFile];
}
// 1. 我们现在准备了一个素材是PDF
// 2. 我们要把这个PDF显示在webView里面
// 显示本地PDF文件在WebView
- (void)viewLocalPDFFile
{
    // 1. 定义URL
    // 1. 全路径
    NSString *path = [[NSBundle mainBundle]pathForResource:@"iTunesConnect_DeveloperGuide_CN.pdf" ofType:nil];
    // 2 全路径得到fileURL
    NSURL *fileURL = [NSURL fileURLWithPath:path];
    // 2. 通过fileURL构建请求
    NSURLRequest *request = [NSURLRequest requestWithURL:fileURL];
    // 4. 重要!!!!!!设置WebView的数据侦测类型:为侦测所有类型
    [_localWebView setDataDetectorTypes:UIDataDetectorTypeAll];
    // 5. 使用WebView加载这个请求即可
    [_localWebView loadRequest:request];
}

// 响应按钮点击,加载HTMLString
- (IBAction)loadHTMLString:(id)sender
{
    // 暂时不考虑baseURL,集中在String上面
    // 用“iOS 正则表达式”去搜索相关知识点,可以做新闻类的应用!
    NSString *fullHTML = @"hello我爱你";
    NSString *partHTML = @"我爱你!!!";
    // webview是可以显示部分html代码的
    [_localWebView loadHTMLString:partHTML baseURL:nil];
}
// 响应按钮点击,加载“data数据”——NSData
- (IBAction)loadData:(id)sender
{
    // 1. pdf文件绝对路径
    NSString *path = [[NSBundle mainBundle]pathForResource:@"iTunesConnect_DeveloperGuide_CN.pdf"
           ofType:nil];
    // 2 通过 绝对路径 生成fileURL
    NSURL *fileURL = [NSURL fileURLWithPath:path];
    // 2. 用NSData类方法加载数据,参数为fileURL
    NSData *data = [NSData dataWithContentsOfURL:fileURL];
    // 3. 使用webView加载data类型数据
    [_localWebView loadData:data MIMEType:@"application/pdf"
      textEncodingName:@"UTF-8" baseURL:nil];
}
@end

H:/0730/05_UIWebView浏览器综合应用_ViewController.h

//
//  ViewController.h
//  UIWebView Demo
//
//  Created by apple on 13-7-21.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import 

@interface ViewController : UIViewController 

// URL文本
@property (weak, nonatomic) IBOutlet UITextField *urlText;
// 回退按钮
@property (weak, nonatomic) IBOutlet UIBarButtonItem *goBackButton;
// 前进按钮
@property (weak, nonatomic) IBOutlet UIBarButtonItem *goForwardButton;
// 重载按钮
@property (weak, nonatomic) IBOutlet UIBarButtonItem *reloadButton;
// 停止按钮
@property (weak, nonatomic) IBOutlet UIBarButtonItem *stopButton;

// Web视图
@property (weak, nonatomic) IBOutlet UIWebView *webView;

// 回退
- (IBAction)goBack:(id)sender;
// 前进
- (IBAction)goForward:(id)sender;
// 刷新
- (IBAction)reloadURL:(id)sender;

// 提交表单
- (IBAction)submit:(id)sender;

@end

H:/0730/05_UIWebView浏览器综合应用_ViewController.m

//  ViewController.m
//  UIWebView 浏览器综合演示
//  Created by apple on 13-7-21.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import "ViewController.h"
@interface ViewController ()
// 访问指定URL字符串的内容,仅由文本框回车事件调用
- (void)gotoURLString:(NSString *)urlString;
// 访问指定的URL内容
- (void)gotoURL:(NSURL *)url;
// 获得本地文件的MIMEType
- (NSString *)MIMEType:(NSString *)fileName;
@end
@implementation ViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    [self MIMEType:@"001.网络基础.pdf"];
 // 调用自定义测试方法
    [self testLoadHTMLFile];
}
// 测试加载本地HTML文件
- (void)testLoadHTMLFile
{
    // 测试加载本地HTML文件,需要指定MIMETYPE
    NSString *dataPath = [[NSBundle mainBundle]pathForResource:@"demo.html" ofType:nil];
 // baseURL基址,以便查找CSS JS jpg等
    NSURL *baseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle]resourcePath]
      isDirectory:YES];
    // 只有加载的html文件才需要指定baseURL路径,告诉浏览器去哪里找图片、样式表等文件
    [_webView loadData:[NSData dataWithContentsOfFile:dataPath]
     MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:baseURL];
}

// 自定义方法,获得本地文件的MIMEType
- (NSString *)MIMEType:(NSString *)fileName
{
    // 根据文件名,得到绝对路径
    NSString *path = [[NSBundle mainBundle]pathForResource:fileName ofType:nil];
    // 根据绝对路径,得到fileURL
    NSURL *url = [NSURL fileURLWithPath:path];
    // 根据url 创建固定请求
    NSURLRequest *request = [NSURLRequest requestWithURL: url];
    // 定义响应,以便接收响应内容
    NSURLResponse *response = nil;
    // 发送同步请求,并传入响应的地址,以便接收响应
    [NSURLConnection sendSynchronousRequest:request
     returningResponse:&response error:nil];
    NSLog(@"MIMEType is %@", [response MIMEType]);
    return [response MIMEType];
}
#pragma mark - UIWebView加载内容的测试方法
// 加载HTML字符串
- (void)testLoadHTMLString
{
    // 测试加载HTML字符串
    NSString *html = @"红楼梦世外仙姝";
    [_webView loadHTMLString:html baseURL:nil];
}
// 加载部分HTML字符串测试
- (void)testLoadPartHTMLString
{
    // 测试加载部分HTML字符串,不需要显示整个网页内容时,通常使用此方法
    NSString *partHtml = @"寂寞林";
    [_webView loadHTMLString:partHtml baseURL:nil];
}

// 加载本地PDF文件
- (void)testLoadPDFFile
{
    // 测试加载本地PDF,需要指定MIMETYPE
    NSString *dataPath = [[NSBundle mainBundle]pathForResource:@"001.网络基础.pdf" ofType:nil];
    [_webView loadData:[NSData dataWithContentsOfFile:dataPath]
   MIMEType:@"application/pdf" textEncodingName:@"UTF-8" baseURL:nil];
}
// 加载本地文本文件
- (void)testLoadTextFile
{
    // 测试加载本地文本文件,需要指定MIMETYPE
    NSString *dataPath = [[NSBundle mainBundle]pathForResource:@"关于.txt" ofType:nil];
    [_webView loadData:[NSData dataWithContentsOfFile:dataPath]
   MIMEType:@"text/plain" textEncodingName:@"UTF-8" baseURL:nil];
}

#pragma mark - UITextField代理方法
// 文本框回车事件
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
 // 如果被回车的是地址栏,且不为空
    if (textField == _urlText && textField.text.length > 0) {
  // 退出键盘
        [textField resignFirstResponder];
  // 调用自定义方法,转到URLstring方法
        [self gotoURLString:textField.text];
    }
    return YES;
}

#pragma mark - 自定义方法,回车后,调用访问指定URL内容
// 访问指定URL字符串的内容,仅由文本框事件调用,文本框回车时候调用的
- (void)gotoURLString:(NSString *)urlString
{
    NSURL *url = nil;
    // 判断是否是httpURL
    if ([urlString hasPrefix:@"http://"]) {
        // URL中有中文的,是需要加百分号的!
        url = [NSURL URLWithString:[urlString
    stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    } else if ([urlString hasPrefix:@"file://"]) {
        // 判断给定参数是否已经是完整的url路径,避免出现前进后退后,
    //URL变成完整URL无法访问的情况
        if ([urlString hasPrefix:@"file://localhost/"]) {
            // 注意此处不能使用fileURLWithPath方法???????????
   // 因为fileURLWithPath是将绝对路径,转成fileURL
   // 而此时,已经是fileURL了
            url = [NSURL URLWithString:urlString];
        } else {
            // 如果没有localhost前缀的,说明是新输入的本地文件,需要转换url。
            // 检测字串范围
            NSRange range = [urlString rangeOfString:@"file://"];
            // 截取剩余部分作为文件名
            NSString *fileName = [urlString substringFromIndex:range.length];
            // 根据文件名,生成文件绝对路径
            NSString *path = [[NSBundle mainBundle]pathForResource:fileName ofType:nil];
            // 判断绝对路径是否存在
            if ([[NSFileManager defaultManager]fileExistsAtPath:path]) {
    // 若存在,将绝对路径转成fileURL
                url = [NSURL fileURLWithPath:path];
            } else {
                url = nil;
            }
        }        
    }
    // 如果到这儿url仍为空,说明,转换失败,输入地址栏内容有误
    if (url == nil) {
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示"
         message:@"输入地址不正确,请重新输入!"
                                    delegate:nil
                                    cancelButtonTitle:@"确定"
                                    otherButtonTitles:nil, nil];
        [alert show];
        // 设置文本框输入焦点
        [_urlText becomeFirstResponder];
    } else {
        // 地址正确,下一步,调用自定义方法,访问指定的URL内容
        [self gotoURL:url];
    }
}
// 地址正确,下一步,调用自定义方法,访问指定的URL内容
- (void)gotoURL:(NSURL *)url
{
    // 使用转换后的URL字符串替代用户输入的URL文本框内容
 // absoluteString???
    [_urlText setText:[url absoluteString]];
    // 1, 根据url 创建固定请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    // 2, 设置浏览器,自动侦测所有数据类型
    [_webView setDataDetectorTypes:UIDataDetectorTypeAll];
    // 3, webView 加载请求
    [_webView loadRequest:request];
}

// 响应按钮点击,JS 提交表单
- (IBAction)submit:(id)sender
{
    // 获取当前页面的url
    NSString *url = [_webView
   stringByEvaluatingJavaScriptFromString:@"document.location.href"];
    NSLog(@"url %@", url);
    // 获取当前页面的标题
    NSString *title = [_webView
    stringByEvaluatingJavaScriptFromString:@"document.title"];
    NSLog(@"title %@", title);
    // 提交表单
    [_webView stringByEvaluatingJavaScriptFromString:@"document.forms[0].submit(); "];
}

#pragma mark - UIWebViewDelegate 代理方法
// 网页中的每一个请求都会被触发这个方法,返回NO代表不执行这个请求(常用于JS与iOS之间通讯)
- (BOOL)webView:(UIWebView *)webView
   shouldStartLoadWithRequest:(NSURLRequest *)request 
   navigationType:(UIWebViewNavigationType)navigationType
{
    NSLog(@"将要加载请求");
    return YES;
}

#pragma mark - IBActions
// 调用浏览器webView默认的,回退操作
- (IBAction)goBack:(id)sender
{
    [_webView goBack];
}
// 调用浏览器webView默认的,前进操作
- (IBAction)goForward:(id)sender
{
    [_webView goForward];
}
// 调用浏览器webView默认的,刷新操作
- (IBAction)reloadURL:(id)sender
{
    [_webView reload];
}

#pragma mark - UIWebViewDelegate 代理方法
// 网页开始加载的时候调用
- (void)webViewDidStartLoad:(UIWebView *)webView
{
    NSLog(@"开始加载");
}
#pragma mark - UIWebViewDelegate 代理方法
// 网页加载完成的时候调用
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    NSLog(@"加载完成");
}
#pragma mark - UIWebViewDelegate 代理方法
// 网页加载出错的时候调用
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    NSLog(@"加载出错%@", [error localizedDescription]);
}

@end

////
ViewController.h// 卖票//// Created by apple on 13-7-29.// Copyright (c)
2013年 itcast. All rights reserved.//#import @inter…

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 澳门新葡亰官网app 版权所有